Ansible之YMAL语法介绍以及playbook详解,ymalplaybook


转自:http://houzhimeng.blog.51cto.com/3938990/1734009

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


相关内容

    暂无相关文章