天天看點

04@ansible playbook語句詳解

文章目錄

  • ​​playbook條件語句​​
  • ​​一、根據不同的作業系統安裝apache​​
  • ​​1、示例​​
  • ​​2、使用括号對條件進行分組​​
  • ​​3、指定多條件為清單​​
  • ​​4、條件運算​​
  • ​​5、rsync(劇本)​​
  • ​​6、register指令(執行結果儲存變量,通過when語句進行判斷)​​
  • ​​二、playbook循環語句​​
  • ​​1、啟動多個服務​​
  • ​​2、定義變量(循環)​​
  • ​​3、字典循環​​
  • ​​三、playbook——handlers​​
  • ​​四、playbook任務标簽​​
  • ​​1、标簽方式​​
  • ​​2、标簽的使用​​
  • ​​3、使用标簽(-t)​​
  • ​​五、playbook(檔案複用)​​
  • ​​1、示例一​​
  • ​​2、示例二​​
  • ​​3、示例三​​
  • ​​六、playbook(忽略錯誤)​​
  • ​​六、playbook(錯誤處理)​​
  • ​​1、強制調用handler​​
  • ​​2、抑制changed​​

playbook條件語句

我們使用​

​Ansible​

​​的過程中,條件判斷的使用頻率極其高,不管是​

​shell​

​還是各大程式設計語言中,流程控制,條件判斷這些都是必不可少的

例如:

1.我們使用不同的系統的時候,可以通過判斷系統來對軟體包進行安裝。

2.在​​

​nfs​

​​和​

​rsync​

​​安裝過程中,用戶端伺服器不需要推送配置檔案,之前我們都是寫多個play,會影響效率。

3.我們在源碼安裝nginx的時候,執行第二遍就無法執行了,此時我們就可以進行判斷是否安裝過。

一、根據不同的作業系統安裝apache

1、示例

"shut down Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_facts['os_family'] == "Debian"
    # note that all variables can be used directly in conditionals without double curly braces
- hosts: web_group
  tasks:
    - name: Install CentOS Httpd
      yum:
        name: httpd
        state: present
    #官方
      when: ansible_facts['os_family'] == "CentOS"
    #非官方
      when: ansible_distribution == "CentOS"

    - name: Install Ubuntu Httpd
      yum:
        name: apache2
        state: present
      when: ansible_facts['os_family'] == "Ubuntu"      

2、使用括号對條件進行分組

tasks:
  - name: "shut down CentOS 6 and Debian 7 systems"
    command: /sbin/shutdown -t now
    when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or
          (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7"      

3、指定多條件為清單

tasks:
  - name: "shut down CentOS 6 systems"
    command: /sbin/shutdown -t now
    when:
      - ansible_facts['distribution'] == "CentOS"
      - ansible_facts['distribution_major_version'] == "6"      

4、條件運算

tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6      

5、rsync(劇本)

1)#服務端推送配置檔案
[root@m01 ~]# cat rsyncd/rsyncd.yaml
- hosts: rsync
  tasks:
    - name: Install Rsyncd Server
      yum:
        name: rsync
        state: present

    - name: Create www Group
      group:
        name: www
        gid: 1000
        
    - name: Create www User
      user:
        name: www
        group: www
        uid: 1000
        create_home: false
        shell: /sbin/nologin

    - name: Scp Rsync Config
      copy:
        src: ./rsyncd.j2
        dest: /etc/rsyncd.conf
        owner: root
        group: root
        mode: 644
      when: ansible_hostname == "backup"

    - name: Create Passwd File
      copy:
        content: 'rsync_backup:123'
        dest: /etc/rsync.passwd
        owner: root
        group: root
        mode: 0600
      when: ansible_hostname == "backup"

    - name: Create backup Directory
      file:
        path: /backup
        state: directory
        mode: 0755
        owner: www
        group: www
        recurse: yes
      when: ansible_hostname == "backup"

    - name: Start Rsyncd Server
      systemd:
        name: rsyncd
        state: started
      when: ansible_hostname == "backup"
      


2)#rsync用戶端推送腳本

[root@m01 ~]# vim rsync.yml
- hosts: rsync_server
  tasks:
    - name: SCP Backup Shell
      copy:
        src: ./backup.sh
        dest: /root/backup.sh
      when: ansible_hostname is match "web*"

#執行結果
PLAY [rsync_server] **************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [web02]
ok: [backup]
ok: [web01]

TASK [SCP Backup Shell] **********************************************************************************************************************************************************************************************************************
skipping: [backup]
changed: [web01]
changed: [web02]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
backup                     : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
web01                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web02                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0      

6、register指令(執行結果儲存變量,通過when語句進行判斷)

- hosts: web_group
  tasks:
    - name: Check Httpd Server
      command: systemctl is-active httpd
      ignore_errors: yes
      register: check_httpd

    - name: debug outprint
      debug: var=check_httpd

    - name: Httpd Restart
      service:
        name: httpd
        state: restarted
      when: check_httpd.rc == 0      

二、playbook循環語句

當我們建立目錄之類的操作時,建立2個目錄就要寫兩個file子產品來建立,如果要建立100個,就需要寫100個file子產品!!!!害----- 當然不是,隻要用循環即可,就可減少代碼的重複性

1、啟動多個服務

- hosts: web_group
  tasks:
    - name: start service
      systemd:
        name: "{{ item }}"      

2、定義變量(循環)

#方式一
- name: ensure a list of packages installed
  yum:
    name: "{{ packages }}"  #定義變量名
  vars:
    packages:
    - httpd
    - httpd-tools
    
#方式二    
- hosts: web_group
  tasks:
    - name: ensure a list of packages installed
      yum: name= "{{ item }}" state=present
      with_items:
        - httpd
        - httpd-tools      

3、字典循環

1.#建立使用者

[root@m01 ~]# cat loop.yml
- hosts: web_group
  tasks:
    - name: Add Users
      user:
        name: "{{ item.name }}"
        groups: "{{ item.groups }}"
        state: present
      with_items:
        - { name: 'zls', groups: 'linux' }
        - { name: 'egon', groups: 'python' }
2.#拷貝檔案

- hosts: web_group
  tasks:
    - name: copy conf and code
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        mode: "{{ item.mode }}"
      with_items:
        - { src: "./httpd.conf", dest: "/etc/httpd/conf/", mode: "0644" }
        - { src: "./upload_file.php", dest: "/var/www/html/", mode: "0600" }      

三、playbook——handlers

handler用來執行某些條件下的任務,比如當配置檔案發生變化的時候,通過notify觸發handler去重新開機服務。在saltstack中也有類似的觸發器,寫法相對Ansible簡單,隻需要watch,配置檔案即可
#劇本編寫
[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  tasks:
    - name: Install Http Server
      yum:
        name: httpd
        state: present

    - name: config httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf
      notify:     #使用觸發器
        - Restart Httpd Server
        - Restart PHP Server

    - name: start httpd server
      service:
        name:httpd
        state: started
        enabled: yes

  handlers:     #觸發器劇本編寫
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted 

    - name: Restart PHP Server
      systemd:
        name: php-fpm
        state: restarted
        


#注:
1.無論多少個task通知了相同的handlers,handlers僅會在所有tasks結束後運作一次。

2.Handlers隻有在其所在的任務被執行時,才會被運作;如果一個任務中定義了notify調用Handlers,但是由于條件判斷等原因,該任務未被執行,那麼Handlers同樣不會被執行。

3.Handlers隻會在每一個play的末尾運作一次;如果想在一個playbook中間運作Handlers,則需要使用meta子產品來實作。例如: -meta: flush_handlers。

4.如果一個play在運作到調用Handlers的語句之前失敗了,那麼這個Handlers将不會被執行。我們可以使用meta子產品的--force-handlers選項來強制執行Handlers,即使Handlers所在的play中途運作失敗也能執行。

5.不能使用handlers替代tasks      

四、playbook任務标簽

預設情況下,Ansible在執行一個playbook時,會執行playbook中定義的所有任務,Ansible的标簽(tag)功能可以給單獨任務甚至整個playbook打上标簽,然後利用這些标簽來指定要運作playbook中的個别任務,或不執行指定的任務

1、标簽方式

1.#對一個task打一個标簽
2.#對一個task打多個标簽
3.#對多個task打一個标簽      

2、标簽的使用

#标簽如何使用      

3、使用标簽(-t)

[root@m01 m01]# cat tag.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  tasks:
    - name: Install Http Server
      yum:
        name: httpd
        state: present
      tags: 
        - install_httpd
        - httpd_server

    - name: configure httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf/httpd.conf
      notify: Restart Httpd Server
      tags: 
        - config_httpd
        - httpd_server

    - name: start httpd server
      service:
        name: httpd
        state: started
        enabled: yes
      tags: service_httpd

  handlers:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted 

[root@m01 m01]# ansible-playbook tag.yml --list-tags
[root@m01 m01]# ansible-playbook tag.yml -t httpd_server
[root@m01 m01]# ansible-playbook tag.yml -t install_httpd,confiure_httpd
[root@m01 m01]# ansible-playbook tag.yml --skip-tags httpd_server      

五、playbook(檔案複用)

在編寫playbook的過程中,寫多個playbook沒有辦法一鍵執行,這樣我們需要單個playbook去執行,很雞肋,是以在playbook中有一個功能,叫做​

​include​

​用來動态調用task任務清單
04@ansible playbook語句詳解
表示rolse頭檔案
隻調用task:include_tasks
調用整個task檔案:include (新版本:import_playbook)
在saltstack中,叫做top file入口檔案      

1、示例一

[root@m01 m01]# cat task.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  tasks:                           #包含的劇本
    - include_tasks: task_install.yml
    - include_tasks: task_configure.yml
    - include_tasks: task_start.yml

  handlers:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted


[root@m01 m01]# cat task_install.yml   #劇本一
- name: Install Http Server
  yum:
    name: httpd
    state: present

[root@m01 m01]# cat task_configure.yml  #劇本二
- name: configure httpd server
  template:
    src: ./httpd.j2
    dest: /etc/httpd/conf/httpd.conf
  notify: Restart Httpd Server

[root@m01 m01]# cat task_start.yml      #劇本三
- name: start httpd server
  service:
    name: httpd
    state: started
    enabled: yes      

2、示例二

- include: httpd.yml
- include: nfs.yml
- include: rsync.yml      

3、示例三

- import_playbook: httpd.yml
- import_playbook: nfs.yml
- import_playbook: rsync.yml      

六、playbook(忽略錯誤)

預設playbook會檢測tasks執行的傳回狀态,如果遇到錯誤則會立即終止playbook的後續tasks執行,然鵝有些時候playbook即使執行錯誤了也要讓其繼續執行

playbook加入參數:ignore_errors: yes 表忽略錯誤

[root@m01 ~]# cat ignore.yml
---
- hosts: web_group
  tasks:
    - name: Ignore False
      command: /bin/false
      ignore_errors: yes   #錯誤忽略
      
    - name: touch new file
      file:
        path: /tmp/zls.txt
        state: touch      

六、playbook(錯誤處理)

如上所述,當task執行失敗時,playbook将不再繼續執行,包括如果在task中設定了handler也不會被執行

1、強制調用handler

[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  force_handlers: yes         #強制調用handler
  tasks:

    - name: config httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf
      notify: 
        - Restart Httpd Server
        - Restart PHP Server

    - name: Install Http Server
      yum:
        name: htttpd
        state: present

    - name: start httpd server
      service:
        name:httpd
        state: started
        enabled: yes


  handlers:        #觸發器      

2、抑制changed

[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  force_handlers: yes      
  tasks:
    - name: shell
      shell: netstat -lntup|grep httpd
      register: check_httpd
      changed_when: false

    - name: debug
      debug: msg={{ check_httpd.stdout.lines }}
      
      
      
      
      
      
[root@m01 project2]# cat changed_when.yml 
- hosts: webservers
  vars:
    - http_port: 8080
  tasks:
    - name: configure httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf/httpd.conf
      notify: Restart Httpd Server

    - name: Check HTTPD
      shell: /usr/sbin/httpd -t
      register: httpd_check
      changed_when: 
        - httpd_check.stdout.find('OK')
        - false

    - name: start httpd server
      service:
        name: httpd
        state: started
        enabled: yes      

繼續閱讀