【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

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值