如何Ansible编写一个Playbook

  • 2019 年 11 月 12 日
  • 笔记

1、playbooks介绍

playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的。

2、playbook基础组件

1.Hosts:运行执行任务(task)的目标主机

2.remote_user:在远程主机上执行任务的用户

3.tasks:任务列表

4.handlers:任务,与tasks不同的是只有在接受到通知时才会被触发

5.templates:使用模板语言的文本文件

6.variables:变量,变量替换

3、playbook和临时命令的比较

1.临时命令不适合复杂配置管理或编配场景。

2.临时命令一次只能调用一个模块或一组参数。当需要多个操作时,必须使用多个临时命令来执行。

3.playbook是描述要在受管理主机上实施的必要配置或程序性步骤的文件。playbook为配置管理和部署提供了强大而灵活的解决方案。playbook可以将冗长而复杂的管理任务变为可轻松重复的历程,并且预测成果。

4、命令到playbook的演化

为了便于理解playbook,我们使用user模块在指定节点docker-03上创建一个用户名为newbie,uid为4000的用户。

 [root@docker-01 ~]# ansible -m user -a "name=newbie uid=4000 state=present" docker-03   docker-03 | CHANGED => {      "ansible_facts": {          "discovered_interpreter_python": "/usr/bin/python"     },      "changed": true,      "comment": "",      "create_home": true,      "group": 4000,      "home": "/home/newbie",      "name": "newbie",      "shell": "/bin/bash",      "state": "present",      "system": false,      "uid": 4000   }

如果写成playbook

 [root@docker-01 ~]# cat user.yml   ---   -name: Configure important user consistently   hosts: docker-03   tasks:      -name: newbie exists with UID 4000       user:         name: newbie         uid: 4000         state: present     [root@docker-01 ~]# ansible-playbook user.yml     PLAY [Configure important user consistently] ***********************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [newbie exists with UID 4000] *********************************************   changed: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0 

paly的第一行以破折号和空格(指示play是列表的第一项)开始,然后是第一个key:name

name key描述paly的目的。name key是可选的,但推荐使用。

 -name: Configure important user consistently

play中的第二个key是hosts属性,指定运行play任务的主机。

 hosts: docker-03

play中最后一个key是tasks属性,为这个play运行的任务列表。

 tasks:      -name: newbie exists with UID 4000       user:         name: newbie         uid: 4000         state: present

playbook是YAML格式的文本文件,扩展名通常为yml。

playbook使用带空格字符的缩进来表示数据结构。YAML对缩进使用了多少空格没有严格的要求,但是有两个基本规则:

1、层次机构中相同级别的数据元素(例如相同列表中的项)必须具有相同的缩进。

2、子项必须比其父项缩进的更多。

可以添加空行增加可读性。

5、Tab键的使用

yml文件只能使用空格缩进,不能使用Tab,如果vim编辑器,可以通过编辑$HOME/.vimrc将Tab转化为2个空格。文件如果不存在,则自己创建。

 [root@docker-03 ~]# vim ~/.vimrc   autocmd FileType yaml setlocal ai ts=2sw=2et

6、playbook的格式

playbook以三个破折号(—)作为文档开始标记。以三个点(…)作为文档结尾标记,尽管在实践中经常被省略。

在这些标记之间,playbook由一组paly构成。YAML列表中的item以一个破折号开始,后跟空格。例如:

 -name: Configure important user consistently   -apple: This is an apple   -orange: This is an orange

paly本身是key-value对的集合。同一个paly中keys应该有相同的缩进。下面的示例显示了一个带有三个keys的YAML代码片段。前两个keys的值很简单。第三个key的列表中有三个items作为值。

 name: Configure important user consistently   hosts: docker-03   tasks:      -first      -second      -third

tasks属性列出要在主机上运行的任务,列表中的每个任务本身都是键值对的集合。

以下是另一个多tasks的演示

 tasks:      -name: web server is enabled        service:         name: httpd         enabled: true        -name: NTP server is enabled        service:         name: chronyd         enabled: true        -name: Postfix is enabled        service:         name: postfix         enables: true

7、执行一个简单的playbook

 [root@docker-02 ~]# cat webserver.yml   ---   -name: play to setup web server   hosts: docker-03   tasks:    -name: latest httpd version installed     yum:       name: httpd       state: latest     [root@docker-02 ~]# ansible-playbook webserver.yml     PLAY [play to setup web server] ************************************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [latest httpd version installed] ******************************************   changed: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0  

上面的输出说明了为何有必要在playbook中将name属性用于play和任务,即便此属性是可选的。playbook执行时显示name属性的值。对于具有多个play和tasks的palybook,使用name属性会给监控playbook的执行提供非常大的帮助。

一般来说,Ansible playbook中的任务是幂等(idempotent)的,可以安全的多次执行playbook。如果目标托管机已经处于正确的状态,则不应进行任何修改。例如,假设前一个例子的剧本再次执行。

 [root@docker-02 ~]# ansible-playbook webserver.yml     PLAY [play to setup web server] ************************************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [latest httpd version installed] ******************************************   ok: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=0   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0 

所有任务状态ok,且没有发生任何change

8、语法验证

在执行playbook前,最好进行验证,确保其内容的语法正确无误。ansible-playbook命令提供–syntax-check选项,可用于验证playbook文件的语法。下例演示了一个playbook成功通过语法验证。

 [root@docker-02 ~]# ansible-playbook --syntax-check webserver.yml   playbook: webserver.yml

语言验证失败时,将报语法错误。输出中包含语法问题在playbook中的大致位置。下例演示了一个playbook语法验证失败,其中play的name属性后缺少了空格分隔符。

 [root@docker-02 ~]# ansible-playbook --syntax-check webserver.yml   ERROR! Syntax Error whileloading YAML.   mapping values are not allowed inthis context     The error appears to be in'/root/webserver.yml': line 3, column 8, but may   be elsewhere inthe file depending on the exact syntax problem.     The offending line appears to be:     -name: play to setup web server   hosts: docker-03         ^ here

9、执行空运算

另一个有用的选项-C选项。这会使Ansible报告在执行该playbook时将会发生什么更改,但不会对受管主机进行任何实际的更改。

下面演示了一个playbook的空运行,它在受管主机上安装了最新版本的httpd软件包。

 [root@docker-02 ~]# ansible-playbook -C webserver.yml     PLAY [play to setup web server] ************************************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [latest httpd version installed] ******************************************   changed: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0  

10、实战2个plays,针对两台主机分别操作

 [root@docker-03 ~]# vim /etc/ansible/hosts   [test1]   172.17.120.50   [test2]   172.17.120.51     [root@docker-03 ~]# vim test.yml   ---   #This is a simple playbook with two plays   -name: first play   hosts: 172.17.120.50   tasks:      -name: first task     yum:       name: httpd       state: present      -name: second task      service:       name: httpd       enabled: true     -name: second play   hosts: 172.17.120.51   tasks:      -name: first task      service:       name: mariadb       enabled: true     [root@docker-03 ~]# ansible-playbook test.yml   PLAY [first play] ******************************************************************************************************************************************************************************************     TASK [Gathering Facts] *************************************************************************************************************************************************************************************   ok: [172.17.120.50]     TASK [first task] ******************************************************************************************************************************************************************************************   ok: [172.17.120.50]     TASK [second task] *****************************************************************************************************************************************************************************************   changed: [172.17.120.50]     PLAY [second play] *****************************************************************************************************************************************************************************************     TASK [Gathering Facts] *************************************************************************************************************************************************************************************   ok: [172.17.120.51]     TASK [first task] ******************************************************************************************************************************************************************************************   changed: [172.17.120.51]     PLAY RECAP *************************************************************************************************************************************************************************************************   172.17.120.50             : ok=3   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   172.17.120.51             : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0