Ansible之playbook(劇本)介紹與案例分析

Ansible的腳本---playbook劇本

通過task調用ansible的模板將多個play組織在一個playbook中運行。

playbooks本身由以下各部分組成

(1)Tasks:任務,即調用模塊完成的某操作;

(2)Variables:變量

(3)Templates:模板

(4)Handlers:處理器,當某條件滿足時,觸發執行的操作;

(5)Roles:角色。

下面是一個playbook的示例

- hosts: webserver              //定義的主機組,即應用的主機

  vars:                        //定義變量

    http_port: 80

    max_clients: 200

  user: root

  tasks:                               //執行的任務

  - name: ensure apache is at the latest version

    yum: pkg=httpd state=latest

  - name: write the apache config file

    template: src=/srv/httpd.j2 dest=/etc/httpd.conf

    notify:

    - restart apache

  - name: ensure apache is running

    service: name=httpd state=started

  handlers:                       //處理器

    - name: restart apache

      service: name=httpd state=restarted

執行一個playbook

ansible-playbook [yaml文件名]

例如:ansible-playbook ping.yml

參數:-k(–ask-pass) 用來交互輸入ssh密碼

        -K(-ask-become-pass) 用來交互輸入sudo密碼

        -u   指定用戶

補充命令:

ansible-playbook nginx.yaml --syntax-check    #檢查yaml文件的語法是否正確

ansible-playbook nginx.yaml --list-task       #檢查tasks任務

ansible-playbook nginx.yaml --list-hosts      #檢查生效的主機

ansible-playbook nginx.yaml --start-at-task='Copy Nginx.conf'     #指定從某個task開始運行

hosts和users介紹

Playbook的設計目的是爲了讓某個或某些主機以某個用戶的身份去執行相應的任務。其中用於指定要執行指定任務的主機用hosts定義,可以是一個主機也可以是由冒號分割的多個主機組;用於指定被管理主機上執行任務的用戶用remote_user來定義

---

- hosts: webserver               #指定主機組,可以是一個或多個組。

  remote_user: root                #指定遠程主機執行的用戶名

還可以爲每個任務定義遠程執行用戶:

---

- hosts: mysql

  remote_user: root             

  tasks:

    - name: test connection

      ping:

      remote_user: mysql          #指定遠程主機執行tasks的運行用戶爲mysql

執行playbook時:ansible-playbook ping.yml -k

remote_user也可以定義指定用戶通過sudo的方法在被管理主機上運行指令

指定遠程主機sudo切換用戶:

---

- hosts: mysql

  remote_user: root            

  become: yes                #2.6版本以後的參數,之前是sudo,意思爲切換用戶運行

  become_user: mysql          #指定sudo用戶爲mysql

執行playbook時:ansible-playbook ping.yml -K

tasks列表和action介紹

1.Play的主體部分是task列表,task列表中的各任務按次序逐個在hosts中指定的主機上執行,即在所有主機上完成第一個任務後再開始第二個任務。

在運行playbook時(從上到下執行),如果一個host執行task失敗,整個tasks都會回滾,請修正playbook 中的錯誤,然後重新執行即可。

Task的目的是使用指定的參數執行模塊,而在模塊參數中可以使用變量,模塊執行時冪等的,這意味着多次執行是安全的,因爲其結果一致。

2.每一個task必須有一個名稱name,這樣在運行playbook時,從其輸出的任務執行信息中可以很好的辨別出是屬於哪一個task的。如果沒有定義name,‘action’的值將會用作輸出信息中標記特定的task。

3.定義一個task,常見的格式:”module: options” 例如:yum: name=httpd

4.ansible的自帶模塊中,command模塊和shell模塊無需使用key=value格式

小示例:

---

- hosts: webserver

  remote_user: root

  tasks:

   - name: disable selinux

     command: '/sbin/setenforce 0'

   - name: make sure apache is running

     service: name=httpd state=started

20.png21.png

play中只要執行命令的返回值不爲0,就會報錯,tasks停止

:q

可以使用ignore_errors: True 來忽略錯誤信息,繼續執行task

修改如下

---

- hosts: webserver

  remote_user: root

  tasks:

   - name: command

     command: '/sbin/command'

     ignore_errors: True             #忽略錯誤,強制返回成功

   - name: make sure apache is running

     service: name=httpd state=started

23.png

22.png

以下是另外一個示例,

表示可以在一個playbook文件中針對不同的主機同時設置各自的tasks

---

- hosts: webserver

  remote_user: root

  tasks:

   - name: create nginx group

     group: name=nginx system=yes gid=208

   - name: create nginx user

     user: name=nginx uid=208 group=nginx system=yes

- hosts: mysql

  remote_user: root

  tasks:

   - name: copy file to mysql

     copy: src=/etc/inittab dest=/opt/inittab.back

24.png25.png26.png

Handlers介紹

Handlers用於當關注的資源發生變化時所採取的操作。在notify中列出的操作便稱爲handler,也就是在notify中需要調用handler中定義的操作。而notify這個動作在每個play的最後被觸發,僅在所有的變化發生完成後一次性的執行指定操作。

Handlers也是一些task的列表,和一般的task並沒有什麼區別。

是由通知者進行的notify,如果沒有被notify,則Handlers不會執行,假如被notify了,則Handlers被執行

不管有多少個通知者進行了notify,等到play中的所有task執行完成之後,handlers也只會被執行一次

示例

---

- hosts: webserver

  remote_user: root

  tasks:

   - name: install httpd package

     yum: name=httpd state=latest

   - name: install configuration file for httpd

     copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf

     notify:                         //引用下面handlers的操作

      -restart httpd

   - name: start httpd service

     service: enabled=true name=httpd state=started

  handlers:          //定義操作,如果被notify,則執行定義的操作,否則不執行

   - name: restart httpd

     service: name=httpd state=restarted

也可以引入變量

變量的介紹

在Ansible中變量名僅能由字母,數字和下劃線組成,並且只能以字母開頭。

使用參數vars:    定義變量

變量引用格式:{{變量名}}  

---

- hosts: webserver

  remote_user: root

  vars:            //定義變量

  - package: httpd

  - service: httpd

  tasks:

   - name: install httpd package

     yum: name={{package}} 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={{service}} state=started        //引用第二個變量

  handlers:

   - name: restart httpd

     service: name={{service}} state=restarted                //引用第二個變量

playbook使用變量的方法:

1.通過ansible命令傳遞

例如:編輯如下yaml

vi a.yml

---

- hosts: mysql

  remote_user: root

  vars:

  - user: 

  tasks:

  - name: add new user

    user: name={{user}}

然後執行命令: ansible-playbook a.yml -e "user=testvar"

可以執行命令查看:ansible mysql  -a 'id testvar'

30.png31.png

2.直接在yaml中定義變量---如上handlers示例

3.直接引用一些變量

如:引用ansible的固定變量

ansible_all_ipv4_addresses:此變量是查看主機網卡ipv4地址的固定變量

vi test.yml

---

- hosts: mysql

  remote_user: root

  tasks:

   - name: copy file

     copy: content="{{ansible_all_ipv4_addresses}}," dest=/opt/vars.txt

執行命令:ansible-playbook test.yml

查看mysql主機上vars.txt文件內容

32.png33.png

再如:引用主機變量

vi /etc/ansible/hosts

在mysql組的主機後面添加如下

[mysql]

192.168.195.163 testvar="195.163"          #定義testvar變量的值爲195.163

vi test.yml      #添加{{testvar}}主機變量

---

- hosts: mysql

  remote_user: root

  tasks:

   - name: copy file

     copy: content="{{ansible_all_ipv4_addresses}},{{testvar}}" dest=/opt/vars.txt

執行命令:ansible-playbook test.yml

查看mysql主機上vars.txt文件內容

34.png35.png36.png37.png

--------條件測試--------

如果需要根據變量、facts(setup)或此前任務的執行結果來作爲某task執行與否的前提時要用到條件測試,在Playbook中條件測試使用when子句。

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

vi b.yml

---

- hosts: webserver

  remote_user: root

  tasks:

    - name: reboot CentOS

      command:  '/usr/sbin/init 6'

      when: ansible_distribution == "CentOS"

1.png

2.png

多條件判斷

vi b.yml

---

- hosts: webserver

  remote_user: root

  tasks:

    - name: reboot CentOS

      command:  '/usr/sbin/init 6'

      when:

        - ansible_distribution == "CentOS"

        - ansible_distribution_major_version == "7"

3.png

組條件判斷

vi when.yml

---

- hosts: mysql

  remote_user: root

  tasks:

    - name: "shut down CentOS 6 and Debian 7 systems"

      command: /sbin/shutdown -t now

      when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or

            (ansible_distribution == "Debian" and ansible_distribution_major_version == "7")

自定義變量進行條件測試

vi when.yml

---

- hosts: all

  vars:

    exist: "True"

  tasks:

  - name: creaet file

    command:  touch /tmp/test.txt

    when: exist | match("True")

  - name: delete file

    command:  rm -rf /tmp/test.txt

    when: exist | match("False")

4.png5.png6.png

將變量exist的值改爲“False”,再執行一遍playbook,結果如何?

7.png8.png9.png

----------迭代-------------

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

---

- hosts: webserver

  remote_user: root

  tasks:

    - name: "Install Packages"

      yum: name={{ item }} state=latest

      with_items:

        - httpd

        - mysql-server

        - php

10.png

也可以自己定義

---

- hosts: webserver

  remote_user: root

  tasks:

    - name: "Add users"

      user: name={{ item.name }} state=present groups={{ item.groups }}

      with_items:

        - { name:'test1', groups:'wheel'}

        - { name:'test2', groups:'root'}

11.png12.png13.png


Templates模塊

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

在ansible管理端上yum安裝httpd服務並複製httpd配置文件作爲模板進行修改配置

yum -y install httpd

cp  /etc/httpd/conf/httpd.conf ./

vi httpd.conf                            //放在管理端

Listen {{http_port}}

ServerName {{server_name}}

MaxClients {{access_num}}

mv httpd.conf httpd.conf.j2

44.png43.png

vi /etc/ansible/hosts

[webserver]

192.168.195.162 http_port=192.168.195.162:80 access_num=100 server_name="www.yun.com:80"

45.png

vi apache.yml

---

- hosts: webserver

  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: start httpd server

      service: name={{service}} enabled=true state=started

  handlers:

    - name: restart httpd

      service: name={{service}} state=restarted

//注意格式對齊

ansible-playbook apache.yml    #執行腳本

46.png

47.png

安裝好httpd後,直接通過瀏覽器進行訪問apache網頁,可以看到默認首頁

49.png

去遠程主機上查看,配置文件修改內容

grep -i listen /etc/httpd/conf/httpd.conf

grep -i maxClient /etc/httpd/conf/httpd.conf

grep -i servername /etc/httpd/conf/httpd.conf

48.png

tags模塊

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

vi hosts.yml

---

- hosts: webserver

  remote_user: root

  tasks:

    - name: Copy hosts file

      copy: src=/etc/hosts dest=/opt/hosts

      tags:

      - only

    - name: touch file

      file: path=/opt/hosts-1 state=touch

執行命令:ansible-playbook hosts.yml --tags="only"

查看被管理服務器上的文件創建情況

38.png39.png40.png

事實上,不光可以爲單個或多個task指定同一個tags。playbook還提供了一個特殊的tags爲always。作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。

vi hosts.yml

---

- hosts: webserver

  remote_user: root

  tasks:

    - name: Copy hosts file

      copy: src=/etc/hosts dest=/opt/hosts-2

      tags:

      - only

    - name: touch file

      file: path=/opt/hosts-3 state=touch

  tags:

  - always

執行命令:ansible-playbook hosts.yml --tags="only"

查看被管理服務器上的文件創建情況

41.png42.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章