Ansible-playbook 劇本編寫


一、playbooks 組成

1、playbooks本身由以下各部分組成

(1) Tasks: 任務,即通過task調用ansible的模板將多個操作組織在一個playbook 中運行
(2) Variables: 變量
(3) Templates: 模板
(4) Handlers: 處理器,當changed狀態條件滿足時, (notify) 觸發執行的操作
(5) Roles: 角色

2、操作示例一:

2.1 編寫yaml文件也就是playbook

vim test1.yaml
---                                                                    #yaml文件以---開頭,以表明這是一個yaml文件,可省略
   - name: first play                                                     #定義一個play的名稱,可省略
     gather_facts: false                                                    #設置不進行facts信息收集,這可以加快執行速度,可省略
     hosts: webservers                                                      #指定要執行任務的被管理主機組,如多個主機組用冒號分隔
     remote_user: root                                                      #指定被管理主機上執行任務的用戶
     tasks:                                                                 #定義任務列表,任務列表中的各任務按次序逐個在hosts中指定的主機上執行
     - name: test connection                                                # 自定義任務名稱
       ping:                                                                  #使用 module: [options] 格式來定義一個任務
     - name: disable selinux
       command: '/sbin/setenforce 0'                                           #command模塊和shell模塊無需使用key=value格式
       ignore_errors: True                                                     #如執行命令的返回值不為0,就會報錯,tasks停止,可使用ignore_errors忽略失敗的任務
     - name: disable firewalld
       service: name=firewalld state=stopped                                   #使用 module: options 格式來定義任務,option使用key=value格式
     - name: install httpd
       yum: name=httpd state=latest
     - name: install configuration file for httpd
       copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf               #這里需要一個事先准備好的/opt/httpd.conf文件
       notify: "restart httpd"                                                 #如以上操作后為changed的狀態時,會通過notify指定的名稱觸發對應名稱的handlers操作
     - name: start httpd service
       service: enabled=true name=httpd state=started
   handlers:                                                               #handlers中定義的就是任務,此處handlers中的任務使用的是service模塊
     - name: restart httpd                                                   #notify和handlers中任務的名稱必須一致
       service: name=httpd state=restarted

#Ansible在執行完某個任務之后並不會立即去執行對應的handler,而是在當前play中所有普通任務都執行完后再去執行handler,
這樣的好處是可以多次觸發notify,但最后只執行一次對應的handler,從而避免多次重啟。
---
   - name: first play
     gather_facts: false
     hosts: webservers
     remote_user: root
     tasks:
     - name: test connection
       ping:
     - name: disable selinux
       command: '/sbin/setenforce 0'
       ignore_errors: True
     - name: disable firewalld
       service: name=firewalld state=stopped
     - name: install httpd
       yum: name=httpd state=latest
     - name: install configuration file for httpd
       copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
       notify: "restart httpd"
     - name: start httpd service
       service: enabled=true name=httpd state=started
     handlers:
     - name: restart httpd
       service: name=httpd state=restarted

2.2 修改配置文件並放入/opt/目錄下

vim httpd.conf         #在/opt/目錄下放入修改之后的配置文件

#42行,指定端口
Listen 8080
#95行,指定域名
ServerName www.ly.com:8080

image
image

image

2.3 運行playbook

ansible-playbook test1.yaml
//補充參數:
-k(–ask-pass):用來交互輸入ssh密碼
-K(-ask-become-pass):用來交互輸入sudo密碼
-u:指定用戶
ansible-playbook test1.yaml --syntax-check                         #檢查yaml文件的語法是否正確
ansible-playbook test1.yaml --list-task                            #檢查tasks任務
ansible-playbook test1.yaml --list-hosts                           #檢查生效的主機
ansible-playbook test1.yaml --start-at-task='install httpd'        #指定從某個task開始運行

image

image

image

3、操作實例二:定義、引用變量

- name: second play
  hosts: dbservers
  remote_user: root
  vars:                                                                        #定義變量
    - groupname: mysql                                                         #格式為 key: value
    - username: nginx
  tasks:
    - name: create group
      group: name={{groupname}} system=yes gid=306                              #使用 {{key}} 引用變量的值
    - name: create user
      user: name={{username}} uid=306 group={{groupname}}
    - name: copy file
      copy: content="{{ansible_default_ipv4}}" dest=/opt/vars.txt               #在setup模塊中可以獲取facts變量信息


ansible-playbook test2.yaml -e "username=nginx"                             #在命令行里定義變量
- name: second play
  hosts: dbservers
  remote_user: root
  vars:
    - groupname: mysql
    - username: nginx
  tasks:
    - name: create group
      group: name={{groupname}} system=yes gid=3000
    - name: create user
      user: name={{username}} uid=2512 group={{groupname}}
    - name: copy file
      copy: content="{{ansible_default_ipv4}}" dest=/opt/vars.txt

image

image

image

4、操作示例三:指定遠程主機sudo切換用戶

---
- hosts: dbservers
remote_user: zhangsan
become: yes #2.6版本以后的參數,之前是sudo,意思為切換用戶運行
become_user: root #指定sudo用戶為root
執行playbook時:ansible-playbook test3.yml -K <密碼>
---
 - hosts: dbservers
   remote_user: lisi
   become: yes
   become_user: root

image

image

image

5、操作示例四:when條件判斷

在Ansible中,提供的唯一一個通用的條件判斷是when指令,當when指令的值為true時,則該任務執行,否則不執行該任務。

//when一個比較常見的應用場景是實現跳過某個主機不執行任務或者只有滿足條件的主機執行任務

vim test4.yaml
---
- hosts: all
remote_user: root
tasks:
    - name: shutdown host
    command: /sbin/shutdown -r now
    when: ansible_default_ipv4.address == "192.168.229.80" #when指令中的變量名不需要手動加上 {{}}
    或
    when: inventory_hostname == "<主機名>"

ansible-playbook test4.yaml
---
- hosts: all
  remote_user: root
  tasks:
  - name: shutdown host
    command: /sbin/shutdown -r now
    when: ansible_default_ipv4.address == "192.168.237.20"

image

image

6、操作示例:五:迭代

Ansible提供了很多種循環結構,一般都命名為with_items,作用等同於 loop 循環。

vim test5.yaml
---
- name: play5
  hosts: dbservers
  gather_facts: false
  tasks:
    - name: create directories      ##創建目錄。目錄名使用with_items里的循環
      file:
        path: "{{item}}"              ##由於值是{{....}} ,所以為了防止被認為是字典,要加上雙引號.
        state: directory
      with_items:                   #等同於 loop:
        - /tmp/test1
        - /tmp/test2
   - name: add users                ###使用循環創建用戶,並添加附加組
     user: name={{item.name}} state=present groups={{item.groups}}
     with_items:
        - name: test1
          groups: wheel
        - name: test2
          groups: root
     或
     with_items:
       - {name:'test1', groups:'wheel'}
       - {name:'test2', groups:'root'}

ansible-playbook test5.yaml
---
- name: playbook5
  hosts: dbservers
  gather_facts: flase
  tasks:
    - name: create directories
      file:
        path: "{{item}}"
        state: directory
      with_items:
        - /tmp/test1
        - /tmp/test2
    - name: add users
      user: name={{item.name}} state=present groups={{item.groups}}
      with_items:
        - name: test1
          groups: wheel
        - name: test2
          groups: root

image

image

image

二、playbook的模塊

1、Templates 模塊

Jinja是基於Python的模板引擎。Template類是Jinja的一個重要組件,可以看作是一個編譯過的模板文件,用來產生目標文本,傳遞Python的變量給模板去替換模板中的標記。

1.1.先准備一個以 .j2 為后綴的 template 模板文件,設置引用的變量

cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2

vim /opt/httpd.conf.j2
Listen {{http_port}}            #42行,修改
ServerName {{server_name}}  #95行,修改
DocumentRoot "{{root_dir}}"     #119行,修改 <Directory "{{root_dir}}">     #131修改 配置目錄訪問權限

image

image

image

image

image

1.2.修改主機清單文件,使用主機變量定義一個變量名相同,而值不同的變量

vim /etc/ansible/hosts
[webservers]
192.168.237.20 http_port=192.168.237.20:80 server_name=www.lsq.com:80 root_dir=/etc/httpd/htdocs

[dbservers]
192.168.237.30 http_port=192.168.237.30:80 server_name=www.test.com:80 root_dir=/etc/httpd/htdocs

image

image

image

1.3、編寫 playbook

---
- hosts: all
  remote_user: root
  vars:
   - package: httpd
   - service: httpd
  tasks:
  - name: install httpd package
    yum: name={{package}} state=latest
  - name: install configure file
    template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    notify:
      - restart httpd
  - name: create root dir
    file: path=/etc/httpd/htdocs state=directory
  - name: start httpd server
    service: name={{service}} enabled=true state=started
  handlers:
  - name: restart httpd
    service: name={{service}} state=restarted

image

image

1.4、制作測試網頁

ansible 192.168.237.20 -m shell -a "echo 'this is test1' > /etc/httpd/htdocs/index.html"   #制作網頁測試文件

ansible 192.168.237.30 -m shell -a "echo 'this is test2' > /etc/httpd/htdocs/index.html" #登錄訪問查看

image

2、tags 模塊

可以在一個playbook中為某個或某些任務定義“標簽”,在執行此playbook時通過ansible-playbook命令使用--tags選項能實現僅運行指定的tasks。
playbook還提供了一個特殊的tags為always。作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。

vim webhosts.yaml
---
- hosts: webservers
  remote_user: root
  tasks:
   - name: Copy hosts file
     copy: src=/etc/hosts dest=/opt/hosts
     tags:
       - only                                                        #可自定義
   - name: touch file
     file: path=/opt/testhost state=touch
     tags:
       - always                                                      #表示始終要運行的代碼

ansible-playbook webhosts.yaml --tags="only"

vim dbhosts.yaml
---
- hosts: dbservers
  remote_user: root
  tasks:
   - name: Copy hosts file
     copy: src=/etc/hosts dest=/opt/hosts
     tags:
       - only
   - name: touch file
     file: path=/opt/testhost state=touch

ansible-playbook dbhosts.yaml --tags="only"
---
- hosts: webservers
  remote_user: root
  tasks:
   - name: Copy hosts file
     copy: src=/etc/hosts dest=/opt/hosts
     tags:
       - only
   - name: touch file
     file: path=/opt/testhost state=touch
     tags:
       - always

分別去兩台被管理主機上去查看文件創建情況

image

image

image

image

3、Roles 模塊

Ansible為了層次化、結構化地組織Playbook,使用了角色(roles),roles可以根據層次型結構自動裝載變量文件、task以及handlers等。簡單來講,roles就是通過分別將變量、文件、任務、模塊及處理器放置於單獨的目錄中,並可以便捷地include它們。roles一般用於基於主機構建服務的場景中,但也可以用於構建守護進程等場景中。

3.1 roles 的目錄結構:

cd /etc/ansible/
tree roles/
roles/
├── web/
│ ├── files/
│ ├── templates/
│ ├── tasks/
│ ├── handlers/
│ ├── vars/
│ ├── defaults/
│ └── meta/
└── db/
├── files/
├── templates/
├── tasks/
├── handlers/
├── vars/
├── defaults/
└── meta/

3.2 roles 內各目錄含義解釋

●files
用來存放由 copy 模塊或 script 模塊調用的文件。

●templates
用來存放 jinjia2 模板,template 模塊會自動在此目錄中尋找 jinjia2 模板文件。

●tasks
此目錄應當包含一個 main.yml 文件,用於定義此角色的任務列表,此文件可以使用 include 包含其它的位於此目錄的 task 文件。

●handlers
此目錄應當包含一個 main.yml 文件,用於定義此角色中觸發條件時執行的動作。

●vars
此目錄應當包含一個 main.yml 文件,用於定義此角色用到的變量。

●defaults
此目錄應當包含一個 main.yml 文件,用於為當前角色設定默認變量。

●meta
此目錄應當包含一個 main.yml 文件,用於定義此角色的特殊設定及其依賴關系。

3.3 在一個 playbook 中使用 roles 的步驟:

(1)創建以 roles 命名的目錄

mkdir /etc/ansible/roles/ -p        #yum裝完默認就有

image

(2)創建全局變量目錄(可選)

mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all     #文件名自己定義,引用的時候注意

image

(3)在 roles 目錄中分別創建以各角色名稱命令的目錄,如 httpd、mysql

mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql
mkdir /etc/ansible/roles/php

image

(4)在每個角色命令的目錄中分別創建files、handlers、tasks、templates、meta、defaults和vars目錄,用不到的目錄可以創建為空目錄,也可以不創建

mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta}

image

(5)在每個角色的 handlers、tasks、meta、defaults、vars 目錄下創建 main.yml 文件,千萬不能自定義文件名

touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml

image

(6)修改 site.yml 文件,針對不同主機去調用不同的角色

vim /etc/ansible/site.yml
---
- hosts: webservers
  remote_user: root
  roles:
    - httpd
- hosts: dbservers
  remote_user: root
  roles:
   - mysql

示例范本

(7)運行 ansible-playbook

cd /etc/ansible
ansible-playbook site.yml

三、roles在LAMP中的應用

1、編寫httpd模塊

寫一個簡單的tasks/main.yml

vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apache
  yum: name={{pkg}} state=latest
- name: start apache
  service: enabled=true name={{svc}} state=started


//定義變量:可以定義在全局變量中,也可以定義在roles角色變量中,一般定義在角色變量中

vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd

這里我們定義在角色變量中

image

image

2、編寫mysql模塊

vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysql
  yum: name={{pkg}} state=latest
- name: start mysql
  service: enabled=true name={{svc}} state=started

vim /etc/ansible/roles/mysql/vars/main.yml
pkg:
 - mariadb
 - mariadb-server
svc: mariadb

image

image

3、編寫php模塊

vim /etc/ansible/roles/php/tasks/main.yml
- name: install php
  yum: name={{pkg}} state=latest
- name: start php-fpm
  service: enabled=true name={{svc}} state=started

vim /etc/ansible/roles/php/vars/main.yml
pkg:
 - php
 - php-fpm
svc: php-fpm

image

image

4、編寫roles示例

vim /etc/ansible/site.yml

---
- hosts: webservers
  remote_user: root
  roles:
   - httpd
   - mysql
   - php


cd /etc/ansible
ansible-playbook site.yml

image

image

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM