【python運維】Ansible之YMAL語法介紹以及playbook詳解

1.YAML介紹

 

YAML是一個可讀性高的用來表達資料序列的格式。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。Clark Evans在2001年在首次發表了這種語言,另外Ingy dt Net與Oren Ben-Kiki也是這語言的共同設計者。

 

YAML Ain't Markup Language,即YAML不是XML。不過,在開發的這種語言時,YAML的意思其實是:"Yet Another Markup Language"(仍是一種標記語言)。其特性:

 

YAML的可讀性好

YAML和腳本語言的交互性好

YAML使用實現語言的數據類型

YAML有一個一致的信息模型

YAML易於實現

YAML可以基於流來處理

YAML表達能力強,擴展性好

 

更多的內容及規範參見http://www.yaml.org。

 

YAML語法

 

YAML的語法和其他高階語言類似,並且可以簡單表達清單、散列表、標量等數據結構。其結構(Structure)通過空格來展示,序列(Sequence)裏的項用"-"來代表,Map裏的鍵值對用":"分隔。下面是一個示例。

1

2

3

4

5

6

7

name: John Smith

age: 41

gender: Male

spouse:

    name: Jane Smith

    age: 37

    gender: Female

children:

1

2

3

4

5

6

    -   name: Jimmy Smith

        age: 17

        gender: Male

    -   name: Jenny Smith

        age 13

        gender: Female

 

YAML文件擴展名通常爲.yaml,如example.yaml。

 

2.Ansible基礎元素

通過roles傳遞變量

 

當給一個主機應用角色的時候可以傳遞變量,然後在角色內使用這些變量,示例如下:

 

1

2

3

4

- hosts: webservers

  roles:

    - common

    - { role: foo_app_instance, dir'/web/htdocs/a.com',  port: 8080

通過roles傳遞變量

 

當給一個主機應用角色的時候可以傳遞變量,然後在角色內使用這些變量,示例如下:

1

2

3

4

- hosts: webservers

  roles:

    - common

    - { role: foo_app_instance, dir'/web/htdocs/a.com',  port: 8080

 

Inventory

 

ansible的主要功用在於批量主機操作,爲了便捷地使用其中的部分主機,可以在inventory file中將其分組命名。默認的inventory file爲/etc/ansible/hosts。

 

inventory file可以有多個,且也可以通過Dynamic Inventory來動態生成。

 

inventory文件格式

 

inventory文件遵循INI文件風格,中括號中的字符爲組名。可以將同一個主機同時歸併到多個不同的組中;此外,當如若目標主機使用了非默認的SSH端口,還可以在主機名稱之後使用冒號加端口號來標明。

 

1

ntp.magedu.com

1

2

3

[webservers]

www1.magedu.com:2222

www2.magedu.com

 

1

2

3

4

[dbservers]

db1.magedu.com

db2.magedu.com

db3.magedu.com

 

如果主機名稱遵循相似的命名模式,還可以使用列表的方式標識各主機,例如:

1

2

3

4

[webservers]

www[01:50].example.com

[databases]

db-[a:f].example.com

 

3.ansible playbooks

playbook的組成結構:

    Inventory

    Modules

     Ad Hoc Commands

    Playbooks

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

Variables:變量

Templates:模板

Handlers:處理器,由某事件觸發執行的操作

Roles:角色

 

基本結構:

- host: websrvs

  remote_user:

  tasks: 

  - task1

   module_name: module_args

  - task 2

 

實例1:

1

2

3

4

5

6

7

8

9

10

11

12

- hosts: webservs

  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: dbservs

  remote_user: root

  tasks:

  - name: copy file to dbservs

    copy: src=/etc/inittab dest=/tmp/inittab.ansible

 

實例2:

1

2

3

4

5

6

7

8

9

- hosts: webservs

  remote_user: root

  tasks:

  - name: install httpd package

    yum: name=httpd state=latest

  - name: install configuration file for httpd

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

  - name: start httpd service

    service: enabled=true name=httpd state=started

 

handlers

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

 

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

- name: template configuration file

  template: src=template.j2 dest=/etc/foo.conf

  notify:

     - restart memcached

     - restart apache

 

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

1

2

3

4

5

handlers:

    - name: restart memcached

      service:  name=memcached state=restarted

    - name: restart apache

      service: name=apache state=restarted

實例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

- hosts: webservs

  remote_user: root

  tasks:

  - name: install httpd package

    yum: name=httpd state=latest

  - name: install configuration file for httpd

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

    notify:

    - restart httpd

  - name: start httpd service

    service: enabled=true name=httpd state=started

  handlers:

  - name: restart httpd

    service: name=httpd state=restarted

 

腳本中定義變量:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

- hosts: webservs

  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=/tmp/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=httpd state=restarted

 

when 

簡單示例:

1

2

3

4

5

6

7

8

- hosts: all

  remote_user: root

  vars:

  - username: user10

  tasks:

  - name: create {{ username }} user

    user: name={{ username }}

    when: ansible_fqdn == "node2.magedu.com"

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

1

2

3

4

tasks:

  - name: "shutdown Debian flavored systems"

    command/sbin/shutdown -h now

    when: ansible_os_family == "Debian"

 

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

1

2

3

4

5

6

7

8

9

10

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中定義的變量。

 

 

迭代

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

1

2

3

4

5

- name: add several users

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

  with_items:

     - testuser1

     - testuser2

 

上面語句的功能等同於下面的語句:

1

2

3

4

- name: add user testuser1

  user: name=testuser1 state=present groups=wheel

- name: add user testuser2

  user: name=testuser2 state=present groups=wheel

 

迭代:重複同類task時使用

調用:item

定義循環列表:with_items

- apache

- php

- mysql-server

 

注意:with_items中的列表值也可以是字典, 但引用時要使用item.KEY

1

2

3

- {name: apache, conf: conffiles/httpd.conf}

- {name: php, conf: conffiles/php.ini}

- {name: mysql-server, conf: conffiles/my.cnf}

 

tags:

在playbook可以爲某個或某些任務定義一個“標籤”,在執行此playbook時,通過爲ansible-playbook命令使用--tags選項能實現僅運行指定的tasks而非所有的;

1

2

3

4

- name: install configuration file for httpd

template: src=/root/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf

tags:

- conf

 

特殊tags: always

 

roles

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

 

一個roles的案例如下所示:

site.yml

webservers.yml

fooservers.yml

roles/

   common/

     files/

     templates/

     tasks/

     handlers/

     vars/

     meta/

   webservers/

     files/

     templates/

     tasks/

     handlers/

     vars/

     meta/

 

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

---

- hosts: webservers

  roles:

     - common

     - webservers

 

也可以向roles傳遞參數,例如:

---

 

1

2

3

4

5

- hosts: webservers

  roles:

    - common

    - { role: foo_app_instance, dir'/opt/a',  port: 5000 }

    - { role: foo_app_instance, dir'/opt/b',  port: 5001 }

 

甚至也可以條件式地使用roles,例如:

---

 

- hosts: webservers

  roles:

    - { role: some_role, when: "ansible_os_family == 'RedHat'" }

 

 

實例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

[root@hzm ~]# tree ansible_playbooks/

ansible_playbooks/

└── roles

    ├── dvsrvs

    │   ├── files #存放由copy或script等模塊調用的文件;

    │   ├── handlers  #此目錄中應當包含一個main.yml文件,用於定義此角色用到的各handler;在handler中使用include包含的其它的handler文件也應該位於此目錄中;

    │   ├── meta  #應當包含一個main.yml文件,用於定義此角色的特殊設定及其依賴關係;ansible 1.3及其以後的版本才支持;

    │   ├── tasks    #至少應該包含一個名爲main.yml的文件,其定義了此角色的任務列表;此文件可以使用include包含其它的位於此目錄中的task文件;

    │   ├── templates  #template模塊會自動在此目錄中尋找Jinja2模板文件;

    │   └── vars  #應當包含一個main.yml文件,用於定義此角色用到的變量

    └── websrvs

        ├── files

        ├── handlers

        ├── meta

        ├── tasks

        ├── templates

        └── vars

 

 

 

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