1. 程式人生 > >Ansible Playbooks 介紹 和 使用 二

Ansible Playbooks 介紹 和 使用 二

通過 服務 rep when add 完成 nts tps chan

目錄

  • handlers
    • playbook 案例 2 handlers
    • vars 變量
      • setup facts 變量使用
      • 案例
      • inventory 中定義變量
      • 案例
  • 條件測試
    • when 語句
    • 案例

handlers

接上一篇文章 Ansible Playbooks 介紹 和 使用 一 繼續說明

用於當關註的資源發生變化時采取一定的操作。

notify這個 action可用於在每個play的最後被處罰,這樣可以避免多次有改變時每次都執行指定的操作,取而代之,盡在所有的變化發生完成後一次性執行指定的操作。在notify中列出的操作成為handler。

例如:

- name: template configuration file
  template: src=template.j2 dest=/etc/foo.conf
  notify:
  - restart memcached
  - restart apache

handler是task列表,這些task與前述task並沒有本質上的不同。

handlers:
- name: restart memcached
  service: name=memcached state=restarted
- name: restart apache
  service: name=httpd state=restarted

playbook 案例 2 handlers

應用場景

在webservs組安裝httpd服務,默認啟動httpd監聽的是80端口

步驟

  1. 創建一個配置安裝httpd服務的playbook,並配置開機器啟動等相關操作
  2. 執行httpd.yml
  3. 修改配置文件httpd.conf中的端口為8080
  4. 再次執行httpd的playbook文件

首先創建httpd.yml文件

[root@node01 ansible]# pwd
/etc/ansible
[root@node01 ansible]# cat httpd.yml 
- hosts: webservs
  remote_user: root
  tasks:
  - name: install httpd packge
    yum: name=httpd state=present
  - name: configuration file for httpd
    copy: src=/etc/ansible/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
  - name: start httpd service
    service: name=httpd enabled=true state=started

創建配置文件目錄,並拷貝httpd.conf

[root@node01 ansible]# pwd
/etc/ansible
[root@node01 ansible]# mkdir conf
[root@node01 ansible]# cp /etc/httpd/conf/httpd.conf conf/
[root@node01 ansible]# vim conf/httpd.conf

執行httpd.yuml的playbook

[root@node01 ansible]# ansible-playbook httpd.yml 

PLAY [webservs] ***********************************************************************************************************

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

TASK [install httpd packge] ***********************************************************************************************
changed: [10.0.0.65]

TASK [configuration file for httpd] ***************************************************************************************
ok: [10.0.0.65]

TASK [start httpd service] ************************************************************************************************
changed: [10.0.0.65]

PLAY RECAP ****************************************************************************************************************
10.0.0.65                  : ok=4    changed=2    unreachable=0    failed=0

驗證:

[root@node01 ansible]# ansible webservs -a ‘rpm -qa httpd‘
10.0.0.65 | CHANGED | rc=0 >>
httpd-2.4.6-80.el7.centos.1.x86_64

[root@node01 ansible]# ansible webservs -m shell -a ‘netstat -lntup | grep 80‘
10.0.0.65 | CHANGED | rc=0 >>
tcp6       0      0 :::80                   :::*                    LISTEN      31354/httpd

修改ansible服務端下httpd.conf配置文件中的端口為8080,然後重新執行

[root@node01 ansible]# egrep ‘^Listen‘ conf/httpd.conf 
Listen 8080
[root@node01 ansible]# ansible-playbook httpd.yml 

PLAY [webservs] ***********************************************************************************************************

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

TASK [install httpd packge] ***********************************************************************************************
ok: [10.0.0.65]

TASK [configuration file for httpd] ***************************************************************************************
changed: [10.0.0.65]

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

PLAY RECAP ****************************************************************************************************************
10.0.0.65                  : ok=4    changed=1    unreachable=0    failed=0   

[root@node01 ansible]# ansible webservs -m shell -a ‘netstat -lntup | grep httpd‘
10.0.0.65 | CHANGED | rc=0 >>
tcp6       0      0 :::80                   :::*                    LISTEN      31354/httpd       

[root@node01 ansible]# ansible webservs -m shell -a ‘egrep "^Listen" /etc/httpd/conf/httpd.conf‘
10.0.0.65 | CHANGED | rc=0 >>
Listen 8080

最後可以看到,雖然遠程主機的配置文件中的端口修改了,但實際監聽的端口沒有變,說明httpd沒有重啟

此時就需要用handlers,來監聽當有類似於這樣的配置文件操作變更的時候,就需要重啟這樣的操作,

下面修改httpd.yml中的內容

[root@node01 ansible]# cat httpd.yml 
- hosts: webservs
  remote_user: root
  tasks:
  - name: install httpd packge
    yum: name=httpd state=present
  - name: configuration file for httpd
    copy: src=/etc/ansible/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify: 
    - restart httpd
  - name: start httpd service
    service: name=httpd enabled=true state=started
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted

再次把httpd.conf中的端口改成808,然後再次執行

[root@node01 ansible]# egrep ‘^Listen‘ conf/httpd.conf 
Listen 808
[root@node01 ansible]# ansible-playbook httpd.yml 

PLAY [webservs] ***********************************************************************************************************

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

TASK [install httpd packge] ***********************************************************************************************
ok: [10.0.0.65]

TASK [configuration file for httpd] ***************************************************************************************
changed: [10.0.0.65]

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

RUNNING HANDLER [restart httpd] *******************************************************************************************
changed: [10.0.0.65]

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

[root@node01 ansible]# ansible webservs -m shell -a ‘netstat -lntup | grep httpd‘
10.0.0.65 | CHANGED | rc=0 >>
tcp6       0      0 :::808                  :::*                    LISTEN      32212/httpd

最後可以看到,遠程主機的httpd服務監聽的端口已經變成了808。

vars 變量

在playbook中使用變量,可以直接在playbook中直接定義變量,也可以在其他模板中定義變量,在playbook文件中飲用

下面以httpd.yml為例,在文件中增加vars變量

[root@node01 ansible]# cat httpd.yml 
- hosts: webservs
  remote_user: root
  vars:
  - package: httpd
  - service: httpd
  tasks:
  - name: install httpd package
    yum: name={{ package }} state=present
  - name: configuration file for httpd
    copy: src=/etc/ansible/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify: 
    - restart httpd
  - name: start httpd service
    service: name={{ service }} enabled=true state=started
  handlers:
  - name: restart httpd
    service: name={{ service }} state=restarted

從上面的定義可以看出,變量的引用是通過{{ }} 兩個大括號來的
下面看下重新執行一下,看下效果

[root@node01 ansible]# ansible-playbook httpd.yml 

PLAY [webservs] ***********************************************************************************************************

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

TASK [install httpd package] **********************************************************************************************
ok: [10.0.0.65]

TASK [configuration file for httpd] ***************************************************************************************
ok: [10.0.0.65]

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

PLAY RECAP ****************************************************************************************************************
10.0.0.65                  : ok=4    changed=0    unreachable=0    failed=0 

可以看到都是OK,說明變量引用成功了

setup facts 變量使用

playbook也可以直接引用facts中獲取的遠程主機信息的變量來使用

案例

首先來查看

[root@node01 ansible]# ansible webservs -m setup | head 
10.0.0.65 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.0.65"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::20c:29ff:fe07:47f6"
        ], 
        "ansible_apparmor": {
            "status": "disabled"

這裏就使用變量:ansible_all_ipv4_addresses 來調用使用

[root@node01 ansible]# cat test.yml 
- hosts: webservs
  remote_user: root
  tasks:
  - name: copy file
    copy: content="{{ ansible_all_ipv4_addresses }}" dest=/tmp/vars.ans
[root@node01 ansible]# ansible-playbook test.yml 

PLAY [webservs] ***********************************************************************************************************

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

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

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

[root@node01 ansible]# ansible webservs -a ‘cat /tmp/vars.ans‘
10.0.0.65 | CHANGED | rc=0 >>
["10.0.0.65"]

從上面最後輸出的結果來看,變量的調用成功。

inventory 中定義變量

同樣也可以在inventory中定義變量,然後在playbook中引用

案例

修改inventory文件hosts

[root@node01 ansible]# cat hosts
# This is the default ansible ‘hosts‘ file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the ‘#‘ character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

[webservs]
10.0.0.65 testvars="10.0.0.65"

[dbservs]
10.0.0.66 testvars="10.0.0.66"

上面給個主機定義了 testvars變量

下面來引用,修改playbook文件

[root@node01 ansible]# cat test.yml 
- hosts: webservs, dbservs
  remote_user: root
  tasks:
  - name: copy file
    copy: content="{{ ansible_all_ipv4_addresses }}\n{{ testvars }}" dest=/tmp/vars.ans
[root@node01 ansible]# ansible-playbook test.yml 

PLAY [webservs, dbservs] **************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************
ok: [10.0.0.65]
ok: [10.0.0.66]

TASK [copy file] **********************************************************************************************************
changed: [10.0.0.66]
changed: [10.0.0.65]

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

[root@node01 ansible]# ansible all -a ‘cat /tmp/vars.ans‘
10.0.0.66 | CHANGED | rc=0 >>
[u‘10.0.0.66‘]
10.0.0.66

10.0.0.65 | CHANGED | rc=0 >>
[u‘10.0.0.65‘]
10.0.0.65

從上面最後的輸出結果可以看出,引用成功。

條件測試

如果需要根據變量、facts或此前任務的執行結果來為某task執行與否的前提時要用到條件測試。

when 語句

在task後面添加when子句即可使用條件測試;when語句支持jinja2表達式語法,例如:

tasks:
- name: "shutdown Debian flavored systems"
  command: /sbin/shutdown -h now
  when: ansible_os_family == "Debian"

when 語句中還可以使用jinja2的太多filter,例如要忽略此前某語句的錯誤並基於其結果(failed或者sucess)運行後面指定的語句,可使用類似如下的形式:

tasks:
- command: /bin/false
  register: result
  ignore_errors: True
- command: /bin/something
  when: result | failed
- command: /bin/something_else
  when: result | success
- command: /bin/still/something_else
  when: result | skipped

此外 when語句中還可以使用facts或playbook中定義的變量。

案例

Ansible Playbooks 介紹 和 使用 二