Playbook是Ansible的配置,部署和编排语言。 他们可以描述您希望远程系统执行的策略,或一般IT流程中的一组步骤。
如果Ansible modules是您workshop的工具,则playbooks是您的说明手册,您的主机inventory是您的原材料。
在基本层面上,可以使用playbooks来管理远程机器的配置和部署。 在更高级别,他们可以对涉及滚动更新的多层次推出进行排序,并可以将操作委派给其他主机,与监控服务器进行交互,同时加载平衡器。
虽然这里有很多信息,但是不需要一次就可以学习所有的东西。 随着时间的推移,您可以开始小型化,随时随地选择更多功能。
playbooks旨在让人可读,并以基本的文字语言开发。 可以通过多种方法来组织playbooks和他们包含的文件,我们将提供一些建议,并充分利用“可复制”。
建议您阅读“ Playbook ”文档,同时阅读“ 示例手册” 。 这些说明了最佳实践以及如何将许多各种概念集中在一起。
关于Playbooks
Playbook是一种与adhoc任务执行模式完全不同的方式,而且特别强大。
简单地说,Playbooks是一个非常简单的配置管理和多机器部署系统的基础,不像任何已经存在的那样,而且非常适合部署复杂的应用程序。
Playbook可以声明配置,但它们也可以协调任何手动订购过程的步骤,即使不同的步骤必须在特定订单的机器组之间来回弹起。 他们可以同步或异步地启动任务。
虽然您可以运行主/usr/bin/ansible
程序来进行自组织任务,但是Playbook更有可能被保留在源代码管理中,并用于推出配置或确保远程系统的配置符合规范。
还有一些完整的剧本可以在ansible-examples存储库中说明很多这些技术。 我们建议您在另一个标签中查看这些内容。
在学习剧本之后,还有很多跳跃点,所以在完成本节之后,请回到文档索引。
Playbook Language Example
Playbook以YAML格式(见YAML Syntax )表示,并具有最少的语法,它有意尝试不是编程语言或脚本,而是一个配置或进程的模型。
每个playbook由一个或多个“plays”组成。
一个play的目标是将一组主机映射到一些明确定义的roles,由事件可调用的任务代表。 在基本层面上,一个任务只不过是对一个可以粘贴的模块的调用(参见关于模块 )。
通过编写多个“plays”的playbook,可以协调多机器部署,在Web服务器组中的所有计算机上运行某些步骤,然后在数据库服务器组上执行某些步骤,然后在Web服务器组等上再次执行命令。
“plays”或多或少是体育比喻。 你可以有很多戏剧影响你的系统做不同的事情。 它不像你只是定义一个特定的状态或模型,你可以在不同的时间运行不同的play。
对于初学者来说,这是一个仅包含一个play的playbook:
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: name=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 (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
- name: restart apache
service: name=httpd state=restarted
当使用具有很长参数的任务或具有许多参数的模块时,可以通过多行将任务项目中断以改进结构。 以下是上述示例的另一个版本,但是使用YAML字典为它们的key=value
参数提供模块:
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum:
name: 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可以包含多个play。 您可能有一个Playbook首先定位到Web服务器,然后是数据库服务器。 例如:
---
- hosts: webservers
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
- hosts: databases
remote_user: root
tasks:
- name: ensure postgresql is at the latest version
yum: name=postgresql state=latest
- name: ensure that postgresql is started
service: name=postgresql state=started
您可以使用此方法在您要定位的主机组,登录到远程服务器的用户名,是否要sudo之间进行切换。 play,像任务一样,按照playbook中指定的顺序运行:从上到下。
Basics
Hosts and Users
对于Playbook中的每个play,您可以选择您的基础设施中的哪些机器进行定位,以及什么远程用户完成步骤(称为任务)。
hosts
行是一个或多个组或主机模式的列表,以冒号分隔,如“ 模式”文档中所述。 remote_user
只是用户帐户的名称:
--- - hosts: webservers remote_user: root
还可以为每个任务定义远程用户:
---
- hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
remote_user: yourname
支持作为其他用户来运行(请参阅Become (Privilege Escalation) ):
--- - hosts: webservers remote_user: yourname become: yes
您也可以使用成为特定任务而不是整个play:
---
- hosts: webservers
remote_user: yourname
tasks:
- service: name=nginx state=started
become: yes
become_method: sudo
您也可以登录,然后成为与root不同的用户:
--- - hosts: webservers remote_user: yourname become: yes become_user: postgres
您还可以使用其他权限升级方法,如su:
---
- hosts: webservers
remote_user: yourname
become: yes
become_method: su
如果需要指定sudo的密码,请使用--ask-become-pass
或使用旧的sudo语法--ask-sudo-pass
( -K
)运行ansible-playbook
。
如果你运行成为playbook,并且playbook似乎挂起,它可能会停留在特权升级提示符下。 只要控制C来杀死它并再次运行,添加相应的密码。
您还可以控制运行主机的顺序。 默认是按照inventory提供的顺序:
- hosts: all order: sorted gather_facts: False tasks: - debug: var=inventory_hostname
order的可能值为:
- inventory:
- 默认值。 该order是由“inventory”提供的
- reverse_inventory:
- 顾名思义,将inventory提供的顺序反过来了
- sorted:
- 主机按名称的字母顺序排列
- reverse_sorted:
- 反向
- shuffle:
- Hosts are randomly ordered each run主机每次运行随机顺序
-
Tasks list
每个play包含一个任务列表。 任务按顺序执行,一次一个地执行与主机模式匹配的所有计算机,然后再转到下一个任务。 重要的是要明白,在一个playbook中,所有的主机都要得到相同的任务指令。 play的目的是将选择的主机映射到任务。
当运行从上到下运行的playbook时,失败任务的主机将从整个playbook的旋转中取出。 如果事情失败,只需更正playbook文件并重新运行。
每个任务的目标是执行一个非常具体的参数的模块。 如上所述,变量可以在模块的参数中使用。
模块应该是幂等的,也就是说,按顺序运行一个模块多次应该具有一样的运行效果。 实现幂等的一种方法是使模块检查其所期望的最终状态是否已经实现,并且如果该状态已经实现,
则在不执行任何动作的情况下退出。 如果一个playbook所使用的所有模块都是幂等的,那么这个playbook本身就有可能是幂等的,所以重新运行这个playbook应该是安全的。
command和shell模块通常会重新运行相同的命令,如果命令类似于chmod
或setsebool
等,则完全可以。尽管有一个可用于创建这些模块的creates
标志也是幂等的。
每个任务都应该有一个name
,它包含在运行该play的输出中。 这是人类可读的输出,因此提供每个任务步骤的良好描述是有用的。 如果没有提供名称,则将“feed”的字符串用作输出。
可以使用旧版action: module options
格式声明任务,但建议您使用更常规的module: options
格式。 在整个文档中使用了这种推荐的格式,但是您可能会在某些playbook中遇到较旧的格式。
这是一个基本的任务。 与大多数模块一样,服务模块采用key=value
参数:
tasks: - name: make sure apache is running service: name=httpd state=started
command和shell模块是唯一获取参数列表而不使用key=value
表单的模块。 这使得他们按照你所期望的方式工作:
tasks:
- name: enable selinux
command: /sbin/setenforce 1
command和shell模块关心返回代码,所以如果你有一个成功的退出代码不为零的命令,你可能希望这样做:
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
或这个:
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
如果行动线太长了,你可以在一个空间上打破它,并缩进任何延续线:
tasks:
- name: Copy ansible inventory file to client
copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
owner=root group=root mode=0644
变量可以在动作行中使用。 假设您在vars
部分中定义了一个名为vhost
的vars
,您可以这样做:
tasks: - name: create a virtual host file for {{ vhost }} template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}
Action Shorthand
可选择在0.8及更高版本中列出这样的模块:
template : src = templates / foo.j2 dest = / etc / foo.conf
您会注意到在早期版本中,这只能用作:
action : template src = templates / foo.j2 dest = / etc / foo.conf
旧的表单继续在较新的版本中工作,没有任何弃用的计划。
Handlers: Running Operations On Change
如上所述,模块应该是幂等的,并且可以在远程系统上进行更改时进行中继。 Playbook认识到这一点,并有一个基本的事件系统可以用来响应变化。
这些“通知”动作在play中每个任务块的末尾触发,只有在多个不同任务通知时才会被触发一次。
例如,多个资源可能表明apache需要重新启动,因为它们已经更改了一个配置文件,但apache只会被triggered一次以避免不必要的重新启动。
以下是当文件内容更改时重新启动两个服务的示例,但仅当文件更改时:
- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
任务notify
部分列出的内容称为处理程序。
处理程序是由全局唯一名称引用的任务列表,与常规任务完全没有任何区别,并由通知程序通知。 如果没有通知处理程序,它将不会运行。 无论通过处理程序有多少任务,在所有任务在特定的play中完成后,它将只运行一次。
这是一个示例处理程序部分:
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
至于Ansible 2.2,处理程序也可以“listen”通用主题,任务可以通知这些主题如下:
handlers: - name: restart memcached service: name=memcached state=restarted listen: "restart web services" - name: restart apache service: name=apache state=restarted listen: "restart web services" tasks: - name: restart everything command: echo "this task will restart the web services" notify: "restart web services"
这种使用可以更容易地触发多个处理程序。 它也使处理程序与名称分离,从而更容易在剧本和角色之间共享处理程序(特别是当使用像Galaxy这样的共享源的第三方角色时)。
角色将在后面描述,但值得指出的是:
- 在
pre_tasks
,tasks
和post_tasks
部分内通知的处理程序将在通知的部分的末尾自动刷新; - 在
roles
部分内通知的处理程序将在roles
部分结束时自动刷新,但在任何tasks
处理程序之前。
如果您想要立即刷新所有处理程序命令,在1.2及更高版本中,您可以:
tasks: - shell: some tasks go here - meta: flush_handlers - shell: some other tasks
在上述示例中,任何排队处理程序将在达到meta
语句时提前处理。 这是一个niche的例子,但可以不时地派上用场。
Executing A Playbook
现在你已经学会了Playbook的语法,你如何运行一个playbook? 这很简单。 让我们用10级的并行度来运行一个playbook:
ansible-playbook playbook.yml -f 10
Ansible-Pull
如果你想反转Ansible的架构,那么节点就可以检查到一个中央位置,而不是把配置推送给他们,你可以。
ansible-pull
是一个小脚本,可以从git检出配置指令的备份,然后针对该内容运行ansible-playbook
。
假设您负载平衡您的checkout位置,基本无限可ansible-pull
秤。
运行ansible-pull --help
帮助详细信息。
还有一个clever playbook可以通过推送模式下的crontab来配置安全性。
Tips and Tricks
要检查playbook的语法,请使用带有--syntax-check
标志的--syntax-check
ansible-playbook
。 这将通过解析器运行playbook文件,以确保其包含的文件,角色等没有语法问题。
查看playbook执行的底部以获取目标节点的总结以及它们的执行情况。 一般失败和致命的“不可达到”的通信尝试在计数中保持分开。
如果您想查看成功模块以及不成功模块的详细输出,请使用--verbose
标志。 这在可用0.5和更高版本中可用。
如果安装了cowsay包,可靠的剧本输出将大大提升。 尝试一下!
在运行它之前,要查看playbook会受到哪些主机的影响,您可以执行以下操作:
ansible-playbook playbook.yml --list-hosts