3.2.2 運維自動化之ansible-playbook和roles

playbook

    play 的主要功能在於將事先歸併爲一組的主機裝扮成事先通過 ansible 中的 task 定義好的角色。從根本上來講,所謂 task 無非是調用 ansible 的一個 module。將多個 play 組織在一個 playbook 中,即可以讓它們聯同起來按事先編排的機制同唱一臺大戲。

先來看一個簡單的 playbook:

---                   #以三個"-"開頭
- hosts: group1       #作用的主機列表
  remote_user: root   #在遠程以哪個用戶的身份執行

  tasks:              #任務集   
  - name: test        #任務的名字
    shell: echo "hello world"   #執行的操作

1、列表以"- "開頭,鍵值對":"後有空格

2、同一級別縮進必須一致,且不能空格與 tab 混用

3、元素:

    Hosts:執行的遠程主機列表
    Tasks:任務集
    Varniables:內置變量或自定義變量在playbook中調用
    Templates:模板,可替換模板文件中的變量並實現一些簡單邏輯的文件
    Handlersnotity:由特定條件觸發的操作,滿足條件方纔執行,否則不執行

    tags:標籤指定某條任務執行,用於選擇運行playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分,即便如此,有些代碼爲測試其確實沒有發生變化的時間依然會非常地長。此時,如果確信其沒有變化,就可以通過tags跳過此些代碼片斷

    playbook 核心元素

hosts:playbook 中的每一個play的目的都是爲了讓某個或某些主機以某個指定的用戶身份執行任務。hosts 用於指定要執行指定任務的主機,需要事先定義在主機清單中

remote_user: 可用於Host和task中。也可以通過指定其通過sudo的方式在遠程主機上執行任務,其可用於play全局或某任務。

[root@CentOS7 .ansible]# cat first.yml 
---
- hosts: group1
  remote_user: jiangbowen

  tasks: 
  - name: create file
    file: name=/data/TestFile state=touch
task列表和action
    play 的主體部分是 task list。task list 中的各任務按次序逐個在 hosts 中指定的所有主機上執行,即在所有主機上完成第一個任務後再開始第二個。在運行自下而下某 playbook 時,如果中途發生錯誤,所有已執行任務都將回滾,因此,在更正 playbook 後重新執行一次即可
    task 的目的是使用指定的參數執行模塊,而在模塊參數中可以使用變量。模塊執行是冪等的,這意味着多次執行是安全的,因爲其結果均一致,shell 模塊除外
    每個 task 都應該有其 name,用於 playbook 的執行結果輸出,建議其內容儘可能清晰地描述任務執行步驟。如果未提供 name,則 action 的結果將用於輸出
---
- hosts: group1
  remote_user: root

  tasks: 
  - name: disable SELinux
    shell: setenforce 0
    ignore_errors: True   #忽略錯誤,69主機上的selinux爲disabled,如果執行setenforce 0的話會報錯
  - name: install httpd
    yum: name=httpd state=installed
  - name: start httpd
    service: name=httpd state=started
[root@CentOS7 .ansible]# ansible-playbook install.yml


PLAY [group1] *******************************************************************************************************************************************************************************


TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.69]
ok: [192.168.30.75]


TASK [disable SELinux] **********************************************************************************************************************************************************************
fatal: [192.168.30.69]: FAILED! => {"changed": true, "cmd": "setenforce 0", "delta": "0:00:00.003807", "end": "2018-05-31 17:25:44.820715", "msg": "non-zero return code", "rc": 1, "start": "2018-05-31 17:25:44.816908", "stderr": "setenforce: SELinux is disabled", "stderr_lines": ["setenforce: SELinux is disabled"], "stdout": "", "stdout_lines": []}
...ignoring     #忽略錯誤,繼續執行
changed: [192.168.30.75]


TASK [install httpd] ************************************************************************************************************************************************************************
changed: [192.168.30.75]
changed: [192.168.30.69]


TASK [start httpd] **************************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.75]


PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=4    changed=3    unreachable=0    failed=0   
192.168.30.75              : ok=4    changed=3    unreachable=0    failed=0   

Handlers:是task列表,這些task與前述的task並沒有本質上的不同,用於當關注的資源發生變化時,纔會採取一定的操作

notify
    這個 action 可用於在每個 play 的最後被觸發,這樣可以避免多次有改變發生時每次都執行指定的操作,僅在所有的變化發生完成後一次性地執行指定操作。在 notify 中列出的操作稱爲 handler,也即 notify 中調用 handler 中定義的操作。

[root@CentOS7 .ansible]# cat handler.yml    #因爲冪等性的原因,所以當服務啓動的情況下,修改配置文件再次執行playbook,並不會
---                                         #重啓服務去讀取文件,所以需要一種方法監控條件的改變,當發生改變時觸發一些動作。
- hosts: 192.168.30.75
  remote_user: root

  tasks:
  - name: install package
    yum: name=httpd state=installed
  - name: copy config         
    copy: src=/etc/httpd/conf/httpd.conf  dest=/etc/httpd/conf/ backup=yes
    notify: restart service     #當copy動作執行完畢,且返回changed狀態,則觸發restart service
  - name: start httpd service
    service: name=httpd state=started

  handlers:
  - name: restart service    #restart service的動作
    service: name=httpd state=restarted
[root@CentOS7 .ansible]# ansible-playbook handler.yml 

PLAY [192.168.30.75] ************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]

TASK [install package] **********************************************************************************************************************************************************************
ok: [192.168.30.75]

TASK [copy config] **************************************************************************************************************************************************************************
changed: [192.168.30.75]

TASK [start httpd service] ******************************************************************************************************************************************************************
ok: [192.168.30.75]

RUNNING HANDLER [restart service] ***********************************************************************************************************************************************************
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.75              : ok=5    changed=2    unreachable=0    failed=0   

tags:爲 task 打上標籤,通過 -t 指定標籤,能夠只執行個別 task。

[root@CentOS7 .ansible]# cat handler.yml
---
- hosts: 192.168.30.75
  remote_user: root

  tasks:
  - name: install package
    yum: name=httpd state=installed
    tags: install
  - name: copy config
    copy: src=/etc/httpd/conf/httpd.conf  dest=/etc/httpd/conf/ backup=yes
    notify: restart service
    tags: copy_conf
  - name: start httpd service
    service: name=httpd state=started
    tags: start

  handlers:
  - name: restart service
    service: name=httpd state=restarted
[root@CentOS7 .ansible]# ansible-playbook -t copy_conf  handler.yml 


PLAY [192.168.30.75] ************************************************************************************************************************************************************************


TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]


TASK [copy config] **************************************************************************************************************************************************************************
ok: [192.168.30.75]


PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.75              : ok=2    changed=0    unreachable=0    failed=0   

變量與 templates

變量也遵循 YAML 語法,使用鍵值對錶示。

    語法:變量名=值

變量名:僅能由字母、數字和下劃線組成,且只能以字母開頭

變量來源:優先級由小到大

    ansible 用戶 -m setup 中的變量(無需聲明,可以直接調用)

    /etc/ansible/hosts 中的變量

        私有變量:對單個主機單獨定義

        公共變量:對主機組中的所有主機定義

    在 playbook 或 role 中定義

    通過 ansible -e 臨時定義的變量

查看 ansible setup 中的變量,支持通配符 * 。

[root@CentOS7 .ansible]# ansible group1 -m setup -a 'filter=ansible_hostname'   #默認顯示所有變量,使用filter進行過濾
192.168.30.69 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "CentOS6"
    }, 
    "changed": false
}
192.168.30.75 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "CentOS75"
    }, 
    "changed": false
}

調式變量時通過"{{ 變量名 }}"使用變量:變量名前後有空格

[root@CentOS7 .ansible]# cat Var.yml 
---
- hosts: group2
  remote_user: root

  tasks:
  - name: touch VarFile
    file: name=/data/{{ testVar }} state=touch

查看變量的優先級,在 /etc/ansible/hosts、playbook、命令行中定義 testVar 變量,賦予不同的值

[root@CentOS7 .ansible]# ansible-playbook '-e testVar=commandVar' Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible]# ansible group2 -m shell -a 'ls /data/*Var'
192.168.30.174 | SUCCESS | rc=0 >>
/data/commandVar                #當命令行中定義同名變量時,優先使用命令行中的變量

192.168.30.75 | SUCCESS | rc=0 >>
/data/commandVar

[root@CentOS7 .ansible]# ansible-playbook Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible]# ansible group2 -m shell -a 'ls /data/*Var'
192.168.30.174 | SUCCESS | rc=0 >>
/data/playbookVar              #不在命令行中定義變量後,使用了playbook中的變量

192.168.30.75 | SUCCESS | rc=0 >>
/data/playbookVar

[root@CentOS7 .ansible]# ansible-playbook Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible] ansible group2 -m shell -a 'ls /data/*Var*'
192.168.30.174 | SUCCESS | rc=0 >>
/data/hostVar74                #再次刪除playbook中的變量,/etc/ansible/hosts中的主機變量生效
                               #且能夠作用與不同組中的相同主機
192.168.30.75 | SUCCESS | rc=0 >>
/data/hostVar75
[root@CentOS7 .ansible]#⮀⮀ansible-playbook Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible]# ansible group2 -m shell -a 'ls /data/*Var'
192.168.30.174 | SUCCESS | rc=0 >>
/data/GroupVar                 #刪除主機變量後,組變量生效

192.168.30.75 | SUCCESS | rc=0 >>
/data/GroupVar

爲了方便管理,建議將所有變量存放在文件中,形成模塊化

[root@CentOS7 .ansible]# cat vars1.yml vars2.yml    #在不同的文件中定義變量
package: httpd
package: bind
[root@CentOS7 .ansible]# cat install.yml            #在使用時,讀取不同的文件就可以調用變量
---
- hosts: group2
  remote_user: root
  vars_files:      #聲明讀取文件中的變量
  - vars1.yml      #指定讀取的文件

  tasks: 
  - name: install httpd
    yum: name={{ package }} state=installed
  - name: start httpd
  service: name={{ package }} state=started
[root@CentOS7 .ansible]# ansible-playbook install.yml 

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [install software] *********************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

TASK [start service] ************************************************************************************************************************************************************************
changed: [192.168.30.75]
changed: [192.168.30.174]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=2    unreachable=0    failed=0   
192.168.30.75              : ok=3    changed=2    unreachable=0    failed=0   

templates 模塊用於以特定模板複製文件。

    選項

src:指定源文件路徑
dest:指定目標文件路徑和文件名
mode:對端文件的權限
owner:對端文件的所有者
group:所屬組
backup:複製到對端時對原文件進行備份

模板文件使用 jinja2 語言,其中可以使用:

    字符串:使用單引號或雙引號
    數字:整數,浮點數
    列表:[item1, item2, ...]
    元組:(item1, item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布爾型:true/false
    算術運算:+, -, *, /, //, %, **
    比較操作:==, !=, >, >=, <, <=
    邏輯運算:and, or, not
    流表達式:For If When    

模板文件必須以”.j2“爲後綴,建議將模板文件放在 ~/.ansible 目錄中,但是路徑沒有限制,也可以放在其他路徑中,使用時指定路徑即可。

.
├── naginxVar.yml
├── nginx.yml
└── templates
    └── nginx.conf.j2

1 directory, 3 files

template 模塊不能用於 adhoc,只能用於 playbook 和 roles 中

[root@CentOS7 .ansible]# cat nginx.yml 
---
- hosts: group2
  remote_user: root

  tasks:
  - name: install nginx
    yum: name=nginx state=installed
  - name: setup config
    template: src=/root/.ansible/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf   #使用template模塊
  - name: start nginx
    service: name=nginx state=started

查看 nginx.conf.j2 文件

[root@CentOS7 templates]# cat nginx.conf.j2 
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes {{ ansible_processor_vcpus*2 }};   #修改進程數爲:調用ansible setup中變量,並且乘2
error_log /var/log/nginx/error.log; 
pid /run/nginx.pid;
...

    由此可見在 template 中,可以使用各種方式來表達想要修改的文本。

執行 nginx.yml 後查看進程個數

[root@CentOS174 yum.repos.d]# ps aux | grep nginx
root       4975  0.0  0.1 122908  2256 ?        Ss   09:59   0:00 nginx: master process /usr/sbin/nginx
nginx      4976  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process   #worker process確實爲內核個數的兩倍
nginx      4977  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process
nginx      4978  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process
nginx      4979  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process
root       4997  0.0  0.0 112660   964 pts/0    S+   10:00   0:00 grep --color=auto nginx

判斷、迭代

when

在 task 後添加 when 語句即可使用條件測試;when語句支持 Jinja2 表達式語法。

    如果需要根據變量、facts 或此前任務的執行結果來做爲某 task 執行與否的前提時要用到條件測試,通過 when 語句實現,在 task 中使用,jinja2的語法格式

    創建一個playbook,實現 centos6/7 不同版本使用不同的 template

[root@CentOS174 .ansible]# cat testwhen.yml 
---
- hosts: group1
  remote_user: root
  vars:
  - port1: 88    #聲明變量
  - port2: 99

  tasks:
  - name: copy tempale for centos6
    template: src=apache2.2.conf.j2 dest=/etc/httpd/conf/httpd.conf
    when: ansible_distribution_major_version == "6"     #判斷系統版本
  - name: copy tempale for centos7
    template: src=apache2.4.conf.j2 dest=/etc/httpd/conf/httpd.conf
    when: ansible_distribution_major_version == "7"
  - name: start service
    service: name=httpd state=restarted

    在 template 中,對 httpd 服務的監聽端口進行修改,分別應用 port1 和 port2,執行playbook

[root@CentOS174 .ansible]# ansible-playbook testwhen.yml 

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.69]
ok: [192.168.30.74]

TASK [copy tempale for centos6] *************************************************************************************************************************************************************
skipping: [192.168.30.74]    #這項task跳過了centos7主機
ok: [192.168.30.69]

TASK [copy tempale for centos7] *************************************************************************************************************************************************************
skipping: [192.168.30.69]   #同上
ok: [192.168.30.74]

TASK [start service] ************************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=3    changed=1    unreachable=0    failed=0   
192.168.30.74              : ok=3    changed=1    unreachable=0    failed=0   

    查看兩臺主機上 httpd 服務監聽的端口

[root@CentOS69 ~]# ss -ntlp | grep httpd   #監聽在88端口上,與port1對應
LISTEN     0      128                      :::88                      :::*      users:(("httpd",4038,6),("httpd",4050,6),("httpd",4051,6),("httpd",4052,6),("httpd",4053,6),("httpd",4054,6),("httpd",4055,6),("httpd",4056,6),("httpd",4057,6))
[root@CentOS74 ~]# ss -ntlp | grep httpd   #監聽在99端口上,與port2對應
LISTEN     0      128         :::99                      :::*                   users:(("httpd",pid=11761,fd=4),("httpd",pid=11760,fd=4),("httpd",pid=11759,fd=4),("httpd",pid=11758,fd=4),(httpd",pid=11757,fd=4),("httpd",pid=11756,fd=4))

with_item

    當有需要重複性執行的任務時,可以使用迭代機制,對迭代項的引用,固定變量名爲"item"。

    創建多個用戶,並且自定義指定UID

[root@CentOS174 .ansible]# cat addUser.yml
---
- hosts: group1
  remote_user: root

  tasks:
  - name: add some user
    user: name={{ item.name }} uid={{ item.uid }} state=present
    with_items:                          #迭代項
      - { name: 'user1', uid: 1111 }     #使用字典的格式,也可以是變量
      - { name: 'user2', uid: 2222 }
      - { name: 'user3', uid: 3333 }

    執行 playbook 後查看結果

[root@CentOS174 .ansible]# ansible-playbook addUser.yml 

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.74]
ok: [192.168.30.69]

TASK [add some user] ************************************************************************************************************************************************************************
changed: [192.168.30.74] => (item={u'name': u'user1', u'uid': 1111})
changed: [192.168.30.69] => (item={u'name': u'user1', u'uid': 1111})
changed: [192.168.30.74] => (item={u'name': u'user2', u'uid': 2222})
changed: [192.168.30.69] => (item={u'name': u'user2', u'uid': 2222})
changed: [192.168.30.74] => (item={u'name': u'user3', u'uid': 3333})
changed: [192.168.30.69] => (item={u'name': u'user3', u'uid': 3333})

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.74              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS69 ~]# id user1
uid=1111(user1) gid=1111(user1) groups=1111(user1)   #創建了對應的三個用戶
[root@CentOS69 ~]# id user2
uid=2222(user2) gid=2222(user2) groups=2222(user2)
[root@CentOS69 ~]# id user3
uid=3333(user3) gid=3333(user3) groups=3333(user3)

for 與 if

    使用 for 循環語句和 if 判斷語句,可以更靈活的使用 template

    查看 playbook

[root@CentOS174 .ansible]# cat test.yml 
---
- hosts: group1
  remote_user: root
  vars:
    apache_vhosts:
    - web1:
      listen: 8080
      root: "/var/www/apache/web1/"
    - web2:
      listen: 80
      server_name: "web2.magedu.com"
      root: "/var/www/apache/web2/"
    - web3:
      listen: 88
      server_name: "web3.magedu.com"
      root: "/var/www/apache/web3/"

  tasks:
  - name: template configto
    template: src=apache.conf.j2 dest=/data/apache.conf

    查看 template

[root@CentOS174 .ansible]# cat templates/apache.conf.j2 
{% for vhost in apache_vhosts %}       #從apache_vhosts中循環,賦值給vhost
server {
	listen {{ vhost.listen }}
{% if vhost.server_name is defined %}  #判斷vhost字典中是否存在server_name
	server_name {{ vhost.server_name }}  #若果有server_name則引用
{% endif %}
	root {{ vhost.root }}
}
{% endfor %}   #結束循環

    執行 playbook 後根據 template 生成了 apache.conf 文件

[root@CentOS69 ~]#??cat /data/apache.conf 
server {                    #web1中沒有server_name,所以沒有生成
	listen 8080       
	root /var/www/apache/web1/
}
server {
	listen 80           #根據playbook中的定義,對應的listen鍵值對不同
	server_name web2.magedu.com
	root /var/www/apache/web2/
}
server {
	listen 88
	server_name web3.magedu.com
	root /var/www/apache/web3/
}

roles

    ansilbe自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。簡單來講,roles就是通過分別將變量、文件、任務、模板及處理器放置於單獨的目錄中,並可以便捷地include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中。

    角色目錄建議存放在 /etc/ansible/roles 中,查看一個角色的目錄結構

[root@CentOS174 roles]# tree
.
└── apache
    ├── default         #設定默認變量時使用此目錄中的main.yml文件
    ├── files           #存放由copy或script模塊等調用的文件
    │   └── index.html
    ├── handlers        #至少應該包含一個名爲main.yml的文件;其它的文件需要在此文件中通過include進行包含
    │   └── main.yml    #若需要handler,則必須有一個main.yml
    ├── meta            #定義當前角色的特殊設定及其依賴關係,至少應該包含一個名爲main.yml的文件,其它文件需在此文件中通過include進行包含
    ├── tasks           #定義task,role的基本元素,至少應該包含一個名爲main.yml的文件;其它的文件需要在此文件中通過include進行包含
    │   ├── copy.yml
    │   ├── install.yml
    │   ├── main.yml    #必須有一個main.yml
    │   ├── start.yml
    │   ├── template2.2.yml
    │   ├── template2.4.yml
    │   └── user.yml
    ├── templates       #template模塊查找所需要模板文件的目錄
    │   ├── apache2.2.conf.j2
    │   └── apache2.4.conf.j2
    └── vars           #定義變量,至少應該包含一個名爲main.yml的文件;其它的文件需要在此文件中通過include進行包含
        └── main.yml    #必須有一個main.yml

8 directories, 12 files

 查看 tasks 中每個角色,其中調用文件可以寫相對路徑,ansible 會自動在 /etc/ansible/roles/project 中查找

- name: copy index
  copy: src=index.html dest=/var/www/html
- name: install apache
  yum: name=httpd state=installed
- name: start apache
  service: name=httpd state=started
- name: copy conf for centos6
  template: src=apache2.2.conf.j2 dest=/etc/httpd/conf/httpd.conf
  when: ansible_distribution_major_version == "6"
  notify: restart httpd
- name: copy conf for centos7
  template: src=apache2.4.conf.j2 dest=/etc/httpd/conf/httpd.conf
  when: ansible_distribution_major_version == "7"
  notify: restart httpd
- name: create user
  user: name=apache system=yes shell=/sbin/nologin

查看 tasks 中文件 main.yml

- include: user.yml      #當執行時按照當前排列順序執行
- include: install.yml
- include: copy.yml
- include: start.yml
- include: template2.2.yml
- include: template2.4.yml

查看 handler 中文件 main.yml

[root@CentOS174 roles]# cat apache/handlers/*
- name: restart httpd
  service: name=httpd state=restarted
查看 vars 中文件 main.yml
[root@CentOS174 roles]# cat apache/vars/*
port1: 88
port2: 99

    按照需求創建各個 roles 後,使用 playbook 執行即可

[root@CentOS174 ~]# cat /etc/ansible/apache_roles.yml 
- hosts: group1
  remote_user: root
  
  roles:
  - apache

執行後查看結果  

[root@CentOS174 ansible]# ansible-playbook apache_roles.yml

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.74]
ok: [192.168.30.69]

TASK [apache : create user] *****************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

TASK [apache : install apache] **************************************************************************************************************************************************************
changed: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy index] ******************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

TASK [apache : start apache] ****************************************************************************************************************************************************************
changed: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos6] *******************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos7] *******************************************************************************************************************************************************
skipping: [192.168.30.69]
changed: [192.168.30.74]

RUNNING HANDLER [apache : restart httpd] ****************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=7    changed=6    unreachable=0    failed=0   
192.168.30.74              : ok=7    changed=6    unreachable=0    failed=0   

    甚至,可以在 roles 中應用標籤判斷語句,和變量

[root@CentOS174 ansible]# cat apache_roles.yml
- hosts: group1
  remote_user: root
  
  roles:
  - { role: apache, tags: ['httpd', 'web'], when: ansible_distribution_major_version == "6" }

    查看執行結果

[root@CentOS174 ansible]# ansible-playbook -t web apache_roles.yml

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.74]
ok: [192.168.30.69]

TASK [apache : create user] *****************************************************************************************************************************************************************
skipping: [192.168.30.74]   #所有操作都跳過了centos6
changed: [192.168.30.69]    

TASK [apache : install apache] **************************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy index] ******************************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : start apache] ****************************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos6] *******************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos7] *******************************************************************************************************************************************************
skipping: [192.168.30.69]   #複製apache2.4的配置文件,所以跳過了所有主機
skipping: [192.168.30.74]

RUNNING HANDLER [apache : restart httpd] ****************************************************************************************************************************************************
changed: [192.168.30.69]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=7    changed=6    unreachable=0    failed=0   
192.168.30.74              : ok=1    changed=0    unreachable=0    failed=0   





發佈了75 篇原創文章 · 獲贊 11 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章