ansible playbook

应客户需求某次给客户的提供的软件需要提供ansible playbook!   what???  什么鬼,接到这个任务我也是满脸懵逼!

好吧接下来我们看看这到底是个什么鬼!

 

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应该是安全的。
commandshell模块通常会重新运行相同的命令,如果命令类似于chmodsetsebool等,则完全可以。尽管有一个可用于创建这些模块的creates标志也是幂等的。 每个任务都应该有一个name ,它包含在运行该play的输出中。 这是人类可读的输出,因此提供每个任务步骤的良好描述是有用的。 如果没有提供名称,则将“feed”的字符串用作输出。 可以使用旧版action: module options格式声明任务,但建议您使用更常规的module: options格式。 在整个文档中使用了这种推荐的格式,但是您可能会在某些playbook中遇到较旧的格式。 这是一个基本的任务。 与大多数模块一样,服务模块采用key=value参数: 
tasks:
  - name: make sure apache is running
    service: name=httpd state=started


commandshell模块是唯一获取参数列表而不使用key=value表单的模块。 这使得他们按照你所期望的方式工作:
tasks:
  - name: enable selinux
    command: /sbin/setenforce 1

commandshell模块关心返回代码,所以如果你有一个成功的退出代码不为零的命令,你可能希望这样做:
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部分中定义了一个名为vhostvars ,您可以这样做: 
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 , taskspost_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