1. 程式人生 > >【Absible學習】Ansible playbook (一)

【Absible學習】Ansible playbook (一)

tags 列表 最好 test list playbook ppi -m color

* 簡介

執行一些簡單的任務,使用ad-hoc命令可以方便的解決問題,但是有時一個設施過於復雜,需要大量的操作時候,執行的ad-hoc命令是不適合的,這時最好使用playbook。playbook 字面意思,即劇本,是 一個不同於使用Ansible命令行執行方式的模式,其功能更強大靈活,可以定制配置,可以按照指定的操作步驟有序執行,支持同步和異步方式。就像執行shell命令與寫shell腳本一樣,一個playbook文件由一個或多個play組成,每個play定義了在一個或多個遠程主機上執行的一系列的task,不過playbook有自己的語法格式。playbook由YMAL( /?j?m?l/ )語言編寫。YMAL格式是類似於JSON的文件格式。playbook和模板文件(template)還可使用jinja2語法語法實現高級功能。

  • YMAL格式:

1、文件的第一行應該以 "---" (三個連字符)開始,表明YMAL文件的開始。
2、在同一行中,#之後的內容表示註釋,類似於shell,python和ruby。
3、YMAL中的列表元素以”-”開頭,然後緊跟著一個空格,後面為元素內容。
4、同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
5、play中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以":"分隔表示,":"後面還要增加一個空格。

* 核心元素

  • Tasks:任務,由模板定義的操作列表
  • Variables:變量
  • Templates:模板,即使用模板語法的文件
  • Handlers:處理器 ,當某條件滿足時,觸發執行的操作
  • Roles:角色

* hosts和users

在playbook中的每一個play都可以選擇在哪些服務器和以什麽用戶執行,hosts一行可以是一個主機組(以逗號分隔)、主機(多個主機以冒號分隔),可使用通配模式。其中remote_user表示執行的用戶賬號。

[root@Super ansible]# cat ping.yml 
---
- hosts: HWY
  tasks:
  - name: test ping
    ping:
[root@Super ansible]# 

上面playbook中只有一個play,也可以在一個playbook中寫多個play:

[root@Super ansible]# cat ping.yml
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: test ping
    ping:
- hosts: 10.15.43.15:10.15.43.16
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: test ping
    ping:
- hosts: 10.10.15.165
         10.10.15.192
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: test ping
    ping:
[root@Super ansible]# 

上面的playbook中寫了3個play,第一個play針對10.15.43.17;第二個play針對10.15.43.15和10.15.43.16;第三個play針對10.10.15.165和10.10.15.192。

  • 指定遠程主機sudo切換
[root@Super ansible]# cat ping.yml 
---
- hosts: 10.10.15.165:10.10.15.192
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: test ping
    ping:
  - name: mkdir directory 20180817
    file:
      path: /app/20180817
      state: directory
      owner: ywbz
      group: ywbz
      mode: 650
  - name: touch file ywbz
    file: path=/app/20180817/ywbz state=touch owner=ywbz
          group=ywbz mode=765
  - name: error command
    shell: /bin/justin
    ignore_errors: True
  - name: restart service snmp
    service: name=snmpd state=restarted enabled=yes
[root@Super ansible]# 

remote_user: ywbz //在遠程主機上以哪個用戶身份執行
become: yes //是否允許身份切換
become_method: su //切換用戶身份的方式,有sudo、su、pbrun等方式,默認為sudo
become_user: root //切換成什麽用戶身份,默認為root

remote_user、become、become_method、become_use選項不僅可用於全局,也可用於各task中。remote_user、become、become_method、become_user分別對應inventory文件中的ansible_user、ansible_become、ansible_become_method、ansible_become_user。如果需要指定切換用戶身份時的密碼,可在執行ansible-playbook時使用選項 --ask-become-pass指定(舊版ansible使用 --ask-sudo-pass指定sudo切換時的密碼)

* Tasks list 和action

  • Play的主體部分是task列表,task列表中的各任務按次序逐個在hosts中指定的主機上執行,即在所有主機上完成第一個任務後再開始第二個任務。
    在運行playbook時(從上到下執行),如果一個host執行task失敗,整個tasks都會回滾,請修正playbook 中的錯誤,然後重新執行即可。
    Task的目的是使用指定的參數執行模塊,而在模塊參數中可以使用變量,模塊執行時冪等的,這意味著多次執行是安全的,因為其結果一致。
  • 每一個task必須有一個名稱name,這樣在運行playbook時,從其輸出的任務執行信息中可以很好的辨別出是屬於哪一個task的。如果沒有定義name,‘action’的值將會用作輸出信息中標記特定的task。
  • 定義一個task,常見的格式:”module: options” 例如:yum: name=httpd
  • ansible的自帶模塊中,command模塊和shell模塊無需使用key=value格式
  • 常用命令
    1、執行playbook
    格式:
    ansible-playbook playbookname.yml ( 文件名以.yaml或.yml結尾)
    參數:

    -u REMOTE_USER, --user=REMOTE_USER # ssh 連接的用戶名
    -k, --ask-pass #ssh登錄認證密碼
    -s, --sudo #sudo 到root用戶,相當於Linux系統下的sudo命令
    -U SUDO_USER, --sudo-user=SUDO_USER #sudo 到對應的用戶
    -K, --ask-sudo-pass #用戶的密碼(—sudo時使用)
    -T TIMEOUT, --timeout=TIMEOUT # ssh 連接超時,默認 10 秒
    -C, --check # 指定該參數後,執行 playbook 文件不會真正去執行,而是模擬執行一遍,然後輸出本次執行會對遠程主機造成的修改
    -e EXTRA_VARS, --extra-vars=EXTRA_VARS # 設置額外的變量如:key=value 形式 或者 YAML or JSON,以空格分隔變量,或用多個-e
    -f FORKS, --forks=FORKS # 進程並發處理,默認 5
    -i INVENTORY, --inventory-file=INVENTORY # 指定 hosts 文件路徑,默認 default=/etc/ansible/hosts -
    l SUBSET, --limit=SUBSET # 指定一個 pattern,對- hosts:匹配到的主機再過濾一次
    --list-hosts # 只打印有哪些主機會執行這個 playbook 文件,不是實際執行該 playbook
    --list-tasks # 列出該 playbook 中會被執行的 task
    --private-key=PRIVATE_KEY_FILE # 私鑰路徑
    --step # 同一時間只執行一個 task,每個 task 執行前都會提示確認一遍
    --syntax-check # 只檢測 playbook 文件語法是否有問題,不會執行該 playbook
    -t TAGS, --tags=TAGS #當 play 和 task 的 tag 為該參數指定的值時才執行,多個 tag 以逗號分隔
    --skip-tags=SKIP_TAGS # 當 play 和 task 的 tag 不匹配該參數指定的值時,才執行
    -v, --verbose #輸出更詳細的執行過程信息,-vvv可得到所有執行過程信息。

    2、檢查yaml文件的語法是否正確
    格式:
    ansible-playbook playbookname.yml --syntax-check

[root@Super ansible]# ansible-playbook handler.yml --syntax-check
ERROR! ‘task‘ is not a valid attribute for a Play   //提示task不是一個有效的屬性,應該是tasks

The error appears to have been in ‘/opt/ansible/handler.yml‘: line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

---
- hosts: 10.10.13.100
  ^ here

[root@Super ansible]# ansible-playbook handler.yml --syntax-check
 [WARNING]: Could not match supplied host pattern, ignoring: 10.10.13.100   //提示主機在/etc/ansible/host裏沒有定義

playbook: handler.yml   //提示這個說明沒有語法問題
[root@Super ansible]# ansible-playbook handler.yml --syntax-check

playbook: handler.yml
[root@Super ansible]# 

3、檢查tasks任務
格式:
ansible-playbook playbookname.yml --list-task

4、檢查生效的主機
格式:
ansible-playbook playbookname.yml --list-hosts

[root@Super ansible]# ansible-playbook handler.yml --list-task

playbook: handler.yml

  play #1 (10.10.13.100): 10.10.13.100  TAGS: []
    tasks:
      config yum repo   TAGS: []
      install snmp  TAGS: []
      copy snmp config  TAGS: []
      make cache    TAGS: []
[root@Super ansible]#

5、檢查tag
格式:
ansible-playbook playbookname.yml --list-tags

[root@Super ansible]# ansible-playbook tags.yml --list-tags

playbook: tags.yml

  play #1 (10.15.43.17): 10.15.43.17    TAGS: []
      TASK TAGS: [always, del_user]
[root@Super ansible]#

6、測試運行

‘模擬執行‘並不是真正的執行,只是‘假裝‘執行一下,playbook中的任務並不會真正在目標主機中運行,所以你可以放心大膽的進行模擬,使用如下命令即可模擬運行playbook,模擬運行功能可以幫助我們‘預估‘playbook是否能夠正常執行。

格式:
ansible-playbook ping.yml --check

使用上述命令進行‘模擬‘時,一些任務可能會報錯,這可能是因為報錯的任務在執行時需要依賴之前的其他任務的完成結果,但是因為是‘模擬‘執行,所以之前的任務並不會真正的執行,既然之前的任務沒有真正的執行,自然不會產生對應的結果,所以後面的任務就報錯了。

6、指定從某個task開始運行
格式:
ansible-playbook ping.yml --start-at-task=‘ping‘

[root@Super ansible]# cat ping.yml 
---
- hosts: 10.10.15.165:10.10.15.192
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: test ping
    ping:
  - name: mkdir directory 20180817
    file:
      path: /app/20180817
      state: directory
      owner: ywbz
      group: ywbz
      mode: 650
  - name: touch file ywbz
    file: path=/app/20180817/ywbz state=touch owner=ywbz
          group=ywbz mode=765
  - name: error command
    shell: /bin/justin
    ignore_errors: True      //忽略錯誤
  - name: restart service snmp
    service: name=snmpd state=restarted enabled=yes
[root@Super ansible]# 

技術分享圖片

  • 對模塊的參數賦值可以使用"冒號"(冒號後有空格):
    file:

    path: /app/20180817
    state: directory
    owner: ywbz
    group: ywbz
    mode: 650

還可以使用"等號",每個參數之間使用空格隔開:

service: name=snmpd state=restarted enabled=yes

使用“等號”給模塊參數賦值時,當模塊參數比較多,這些參數"擠在一行"裏面,可以把它們分成多行去寫,也需要註意縮進。

file: path=/app/20180817/ywbz state=touch owner=ywbz

group=ywbz mode=765

  • playbook裏每個task都有對應的name,當我們省略name時,默認以當前任務調用的模塊的名稱作為任務的名稱,不過建議不要省略name,因為當任務存在name時,可讀性比較高。

  • task裏的各個屬性並沒有嚴格的順序要求,但是仍然需要嚴格按照縮進進行對齊。

  • play中只要執行命令的返回值不為0,就會報錯,tasks停止,可以添加下面【ignore_errors: True】 忽略錯誤,強制返回成功,但是需要註意後面task是否對此task有依賴關系,如果有依賴關系後面的作業就無法完成。

技術分享圖片


* Handlers

用於當關註的資源發生變化時觸發一定的操作。handlers也是一些task的列表,這些task與前述的task並沒有本質上的不同。由通知者進行的notify,如果沒有被notify,則Handlers不會執行,假如被notify了,則Handlers被執行,“notify”這個action可用於在每個play的最後被觸發,這樣可以避免多次有改變發生時每次都執行指定的操作,取而代之,僅在所有的變化發生完成後一次性地執行指定操作。在notify中列出的操作稱為handler。

格式:
notify:

  • restart service nginx
  • restart service tomcat
    或者
    notify: restart service nginx

技術分享圖片
技術分享圖片


* 引用變量

變量命名: 字母數字下劃線組成,只能以字母開頭

  • ansible內置變量
    ansible變量可以通過fact獲取
[root@Super ansible]# ansible 10.15.43.17 -S -R root -m setup
10.15.43.17 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.15.43.17"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::20c:29ff:fe12:3840"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "07/31/2013", 
        "ansible_bios_version": "6.00", 
......
[root@Super ansible]# ansible 10.15.43.17 -S -R root -m setup -a"filter=*distribution*"
10.15.43.17 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/redhat-release", 
        "ansible_distribution_file_variety": "RedHat", 
        "ansible_distribution_major_version": "7", 
        "ansible_distribution_release": "Core", 
        "ansible_distribution_version": "7.5.1804"
    }, 
    "changed": false
}
[root@Super ansible]#

ansible_all_ipv4_addresses:獲取IP

技術分享圖片

  • 自定義變量
  • 在inventory定義變量:在資源清單inventory(/etc/ansible/hosts)裏主機後面添加的變量。
[root@Super ansible]# grep ‘10.15.43.17‘ /etc/ansible/hosts 
10.15.43.17 ansible_ssh_port=22 ansible_ssh_user=ywbz ansible_ssh_pass=‘ygnl@428#‘ ansible_become_pass=‘FinChina@510267‘ testvar=‘my ip address:‘
[root@Super ansible]# cat var.yml 
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: copy file
    copy: content={{testvar}}:{{ansible_all_ipv4_addresses}} dest=/app/ipaddr.txt
[root@Super ansible]# ansible-playbook var.yml --syntax-check

playbook: var.yml
[root@Super ansible]# ansible-playbook var.yml -K
SUDO password: 

PLAY [10.15.43.17] ****************************************************************************************************

TASK [copy file] ******************************************************************************************************
changed: [10.15.43.17]

PLAY RECAP ************************************************************************************************************
10.15.43.17                : ok=1    changed=1    unreachable=0    failed=0   

[root@Super ansible]# ansible 10.15.43.17 -S -R root -m shell -a "cat /app/ipaddr.txt"
10.15.43.17 | SUCCESS | rc=0 >>
my ip address::[u‘10.15.43.17‘]

[root@Super ansible]# 

技術分享圖片

  • 在palybook裏定義變量

格式:
vars:
– var_name: value
– var_name: value

或者
vars:
var_name=value

[root@Super ansible]# cat var.yml 
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  vars:
  - blogname: ityunwei2017
  - blogaddr: 51cto
  tasks:
  - name: copy file
    copy: content="{{blogname}} {{blogaddr}}:{{ansible_all_ipv4_addresses}}" dest=/app/ipaddr.txt
[root@Super ansible]# ansible-playbook var.yml --syntax-check

playbook: var.yml
[root@Super ansible]# ansible-playbook var.yml -K
SUDO password: 

PLAY [10.15.43.17] ****************************************************************************************************

TASK [copy file] ******************************************************************************************************
changed: [10.15.43.17]

PLAY RECAP ************************************************************************************************************
10.15.43.17                : ok=1    changed=1    unreachable=0    failed=0   

[root@Super ansible]# ansible 10.15.43.17 -S -R root -m shell -a "cat /app/ipaddr.txt"
10.15.43.17 | SUCCESS | rc=0 >>
ityunwei2017 51cto:[u‘10.15.43.17‘]

[root@Super ansible]# 

技術分享圖片

  • 通過命令行傳遞變量
    格式:-e VAR=VALUE
ansible-playbook test.yml –extra-vars “host=www user=tom“

如果劇本中已有此處定義的變量則會被覆蓋

  • 向不同的主機傳遞不同的變量
    格式:IP/HOSTNAME variable_name=value

  • 向組內的所有主機傳遞相同的變量
    格式:[groupname:vars]
    variable_name=value

  • 在角色調用時傳遞
    roles:
    – { role: ROLE_NAME, var: value, …}

變量調用:
{{ var_name }}


* 條件判斷

在ansible中,只有when可以實現條件判斷。when的值是一個條件表達式,如果條件判斷成立,這個task就執行,如果判斷不成立,則task不執行,如果需要根據變量、facts(setup)或此前任務的執行結果來作為某task執行與否的前提時要用到條件測試,在Playbook中條件測試使用when子句,在task後添加when子句即可使用條件測試。

  • 單條件判斷

技術分享圖片

1、when判斷的對象是task,所以和task在同一列表層次。它的判斷結果決定它所在task是否執行,而不是它下面的task是否執行。
2、when中引用變量的時候不需要加{{ }}符號。
3、when中變量值判斷是否相等使用2個等號,值需要用雙引號引起來。

  • 多條件判斷
[root@Super ansible]# cat var.yml 
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: CentOS 7 7.5.1804
    copy: content="{{ansible_distribution}} {{ansible_distribution_version}}:{{ansible_all_ipv4_addresses}}" dest=/app/CentOS7.5.txt
    when: 
      - ansible_distribution_major_version == "7"
      - ansible_distribution_version == ‘7.5.1804‘
  - name: CentOS7
    copy: content="{{ansible_distribution}} {{ansible_distribution_version}}:{{ansible_all_ipv4_addresses}}" dest=/app/CentOS7.txt
    when: ansible_distribution_major_version == "7"
[root@Super ansible]# ansible-playbook var.yml --syntax-check

playbook: var.yml
[root@Super ansible]# ansible-playbook var.yml -K
SUDO password: 

PLAY [10.15.43.17] ****************************************************************************************************

TASK [CentOS 7 7.5.1804] **********************************************************************************************
changed: [10.15.43.17]

TASK [CentOS7] ********************************************************************************************************
changed: [10.15.43.17]

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

[root@Super ansible]# 

ansible_distribution_major_version == "7" 和 ansible_distribution_version == ‘7.5.1804‘ 同時滿足才執行task。

技術分享圖片

  • 組條件判斷
    when條件判斷支持各種邏輯組合
[root@Super ansible]# cat when.yml 
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: restart snmp  CentOS 5 or CentOS 6
    cron: name="ansible cron test" 
          minute=30 hour=6 day=* month=* weekday=*  user=root job="/sbin/service snmpd restart" 
          backup=yes 
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "5") or
          (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6")
  - name: restart cron  CentOS 5 or CentOS 6
    service: name=crond state=restarted
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "5") or
          (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6")
  - name: restart snmp CentOS 7
    cron: name="ansible cron test" 
          minute=30 hour=6 day=* month=* weekday=*  user=root job="/usr/bin/systemctl restart snmpd" 
          backup=yes 
    when: 
      - ansible_distribution == "CentOS"
      - ansible_distribution_major_version == "7"
  - name: restart cron CentOS 7
    service: name=crond state=restarted
    when: 
      - ansible_distribution == "CentOS"
      - ansible_distribution_major_version == "7"
[root@Super ansible]# ansible-playbook when.yml --syntax-check

playbook: when.yml
[root@Super ansible]# ansible-playbook when.yml -K
SUDO password: 

PLAY [10.15.43.17] ****************************************************************************************************

TASK [restart snmp  CentOS 5 or CentOS 6] *****************************************************************************
skipping: [10.15.43.17]

TASK [restart cron  CentOS 5 or CentOS 6] *****************************************************************************
skipping: [10.15.43.17]

TASK [restart snmp CentOS 7] ******************************************************************************************
changed: [10.15.43.17]

TASK [restart cron CentOS 7] ******************************************************************************************
changed: [10.15.43.17]

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

[root@Super ansible]#

技術分享圖片
技術分享圖片

取反
when: not ansible_distribution_major_version == "7"

  • 自定義條件判斷

* 叠代-循環

  • with_items叠代列表

有需要重復性執行的任務時,可以使用叠代機制。其使用格式為將需要叠代的內容定義為item變量引用,並通過with_items語句指明叠代的元素列表即可。

例如:要安裝一堆軟件包。

技術分享圖片

按照with_itenms裏的順序依次安裝

例如:創建多個用戶

[root@Super ansible]# cat with_items.yml 
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: install soft
    yum: name={{item}} state=latest
    with_items:
      - gcc
      - gcc-c++
      - wget
      - lrzsz
  - name: create user
    user: name={{item.name}} state=present groups={{item.groups}} 
    with_items:
      - {name: ‘test1‘, groups: ‘justin1‘}    //創建用戶test1,用戶組為justin1
      - {name: ‘test2‘, groups: ‘justin2‘}   //左右括號可以不用空格,冒號後需要空格
[root@Super ansible]# ansible-playbook with_items.yml --syntax-check

playbook: with_items.yml
[root@Super ansible]# ansible-playbook with_items.yml -K
SUDO password: 

PLAY [10.15.43.17] ****************************************************************************************************

TASK [install soft] ***************************************************************************************************
ok: [10.15.43.17] => (item=[u‘gcc‘, u‘gcc-c++‘, u‘wget‘, u‘lrzsz‘])

TASK [create user] ****************************************************************************************************
changed: [10.15.43.17] => (item={u‘name‘: u‘test1‘, u‘groups‘: u‘justin1‘})
changed: [10.15.43.17] => (item={u‘name‘: u‘test2‘, u‘groups‘: u‘justin2‘})

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

[root@Super ansible]# ansible 10.15.43.17 -S -R root -a ‘tail -5 /etc/passwd‘
10.15.43.17 | SUCCESS | rc=0 >>
zabbix:x:1001:1001::/home/zabbix:/sbin/nologin
ywbz:x:1002:1002::/home/ywbz:/bin/bash
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
test1:x:1003:1005::/home/test1:/bin/bash
test2:x:1004:1006::/home/test2:/bin/bash

[root@Super ansible]#

技術分享圖片

* Templates

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

* Tags

在一個playbook中,我們一般會定義很多個task,如果我們只想執行其中的某一個task或多個task時就可以使用tags標簽功能。

[root@Super ansible]# cat tags.yml 
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: install soft
    yum: name={{item}} state=latest
    with_items:
      - gcc
      - gcc-c++
      - wget
      - lrzsz
  - name: create user
    user: name={{item.name}} state=absent groups={{item.groups}} 
    with_items:
      - {name: ‘test1‘, groups: ‘justin1‘}
      - {name: ‘test2‘, groups: ‘justin2‘}
    tags:
      - del_user
[root@Super ansible]# ansible-playbook tags.yml --syntax-check

playbook: tags.yml
[root@Super ansible]# ansible-playbook tags.yml --tags="del_user" -K    //-t del_user
SUDO password: 

PLAY [10.15.43.17] ****************************************************************************************************

TASK [create user] ****************************************************************************************************
changed: [10.15.43.17] => (item={u‘name‘: u‘test1‘, u‘groups‘: u‘justin1‘})
changed: [10.15.43.17] => (item={u‘name‘: u‘test2‘, u‘groups‘: u‘justin2‘})

PLAY RECAP ************************************************************************************************************
10.15.43.17                : ok=1    changed=1    unreachable=0    failed=0   

[root@Super ansible]# 

技術分享圖片

如果想跳過某個task,將參數--tags替換成--skip-tags,從某個tag開始使用–start-at-task=START_AT,可以為單個或多個task指定同一個tags。

  • 系統中內置的特殊tags:

    always: 指定這個tag 後,無論執行哪一個tags時,該tags標記的task任務將永遠被執行,而不用去考慮是否使用了--skip-tags標記,
    tagged: 當 --tags 指定為它時,則只要有tags標記的task都將被執行,--skip-tags效果相反
    untagged: 當 --tags 指定為它時,則所有沒有tag標記的task 將被執行,--skip-tags效果相反
    all: 這個標記無需指定,ansible-playbook 默認執行的時候就是這個標記.所有task都被執行

[root@Super ansible]# cat tags.yml 
---
- hosts: 10.15.43.17
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  tasks:
  - name: install soft
    tags:
      - always
    yum: name={{item}} state=latest
    with_items:
      - gcc
      - gcc-c++
      - wget
      - lrzsz
  - name: create user
    user: name={{item.name}} state=absent groups={{item.groups}} 
    with_items:
      - {name: ‘test1‘, groups: ‘justin1‘}
      - {name: ‘test2‘, groups: ‘justin2‘}
    tags:
      - del_user
[root@Super ansible]# 

技術分享圖片


* roles

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

  • roles的文件結構:

files/:此角色中用到的所有文件均放置於此目錄中
templates/: Jinja2模板文件存放位置
tasks/:任務列表文件;可以有多個,但至少有一個叫做main.yml的文件
handlers/:處理器列表文件;可以有多個,但至少有一個叫做main.yml的文件
vars/:變量字典文件;可以有多個,但至少有一個叫做main.yml的文件
meta/:此角色的特殊設定及依賴關系

roles的目錄結構示例:

[root@Super ansible]# tree roles/
roles/
├── dbservers
│?? ├── files       存放由copy或script等模塊調用的靜態文件;
│?? ├── handlers        此目錄中應當包含一個main.yml文件,用於定義此角色用到的各handler;此文件可以使用include包含其它的位於此目錄中的handler文件;
│?? │?? └── main.yml
│?? ├── tasks       至少應該包含一個名為main.yml的文件,其定義了此角色的任務列表;此文件可以使用include包含其它的位於此目錄中的task文件;
│?? │?? └── main.yml
│?? ├── templates   template模塊會自動在此目錄中尋找Jinja2模板文件;
│?? └── vars        至少有一個main.yml文件,用於定義此角色用到的變量;
│??     └── main.yml
└── webservers
    ├── default     為當前角色設定默認變量時使用此目錄;應當包含一個main.yml文件;
    │?? └── main.yml
    ├── files
    ├── handlers
    │?? └── main.yml
    ├── meta        至少有一個main.yml文件,用於定義此角色的特殊設定及其依賴關系;ansible 1.3及其以後的版本才支持;
    │?? └── main.yml
    ├── tasks
    │?? └── main.yml
    ├── templates
    └── vars
        └── main.yml

14 directories, 8 files
[root@Super ansible]#

在playbook中,可以這樣使用roles:

[root@Super ansible]# cat roles.yml
---
- hosts: 10.10.15.165:10.10.15.192
  remote_user: ywbz
  become: yes
  become_method: su
  become_user: root
  roles:
  - common
  - webserver
  - dbserver
[root@Super ansible]#

也可以向roles傳遞參數
技術分享圖片

還可以條件式地使用roles
技術分享圖片

【Absible學習】Ansible playbook (一)