Working With Playbooks--Intro to Playbooks

Intro to Playbooks

Playbooks简介

About Playbooks

关于剧本

Playbooks are a completely different way to use ansible than in adhoc task execution mode, and are particularly powerful.

与adhoc任务执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。

Simply put, playbooks are the basis for a really simple configuration management and multi-machine deployment system, unlike any that already exist, and one that is very well suited to deploying complex applications.

简而言之,playbooks是真正简单的配置管理和多机器部署系统的基础,与已有的系统不同,并且非常适合部署复杂的应用程序。

Playbooks can declare configurations, but they can also orchestrate steps of any manual ordered process, even as different steps must bounce back and forth between sets of machines in particular orders. They can launch tasks synchronously or asynchronously.

Playbooks可以声明配置,但它们也可以协调任何手动订购流程的步骤,即使不同的步骤必须在特定订单的机器组之间来回跳转。他们可以同步或异步启动任务。

While you might run the main /usr/bin/ansible program for ad-hoc tasks, playbooks are more likely to be kept in source control and used to push out your configuration or assure the configurations of your remote systems are in spec.

虽然您可以运行/usr/bin/ansible主程序来执行临时任务,但是更有可能将源代码保留在源代码管理中并用于推出配置或确保远程系统的配置符合规范。

There are also some full sets of playbooks illustrating a lot of these techniques in the ansible-examples repository. We’d recommend looking at these in another tab as you go along.

ansible-examples存储库中还有一些完整的手册说明了很多这些技术 我们建议您在另一个标签中查看这些内容。

There are also many jumping off points after you learn playbooks, so hop back to the documentation index after you’re done with this section.

在学习了剧本后,还有许多跳跃点,所以在完成本节后,请跳回文档索引。

Playbook Language Example

Playbook语言示例

Playbooks are expressed in YAML format (see YAML Syntax) and have a minimum of syntax, which intentionally tries to not be a programming language or script, but rather a model of a configuration or a process.

Playbooks以YAML格式表示(请参阅YAML语法),并且具有最少的语法,有意尝试不是编程语言或脚本,而是配置或进程的模型。

Each playbook is composed of one or more ‘plays’ in a list.

每个剧本由列表中的一个或多个“剧本”组成。

The goal of a play is to map a group of hosts to some well defined roles, represented by things ansible calls tasks. At a basic level, a task is nothing more than a call to an ansible module (see Working With Modules).

游戏的目标是将一组主机映射到一些定义明确的角色,由ansible调用任务表示。在基本级别,任务只不过是对ansible模块的调用(请参阅使用模块)。

By composing a playbook of multiple ‘plays’, it is possible to orchestrate multi-machine deployments, running certain steps on all machines in the webservers group, then certain steps on the database server group, then more commands back on the webservers group, etc.

通过编写多个“播放”的剧本,可以编排多机部署,在Web服务器组中的所有计算机上运行某些步骤,然后在数据库服务器组上执行某些步骤,然后在Web服务器组上执行更多命令,等等。

“plays” are more or less a sports analogy. You can have quite a lot of plays that affect your systems to do different things. It’s not as if you were just defining one particular state or model, and you can run different plays at different times.

“戏剧”或多或少是体育比喻。你可以有很多戏剧影响你的系统做不同的事情。这并不是说你只是定义了一个特定的状态或模型,而是可以在不同的时间运行不同的plays。

For starters, here’s a playbook that contains just one play:

对于初学者来说,这是一个只包含一个游戏的剧本:

---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version 确保apache是最新版本
    yum:
      name: httpd
      state: latest
  - name: write the apache config file 写apache是最新版本
    template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running 确保apache正在进行
    service:
      name: httpd
      state: started
  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted

Playbooks can contain multiple plays. You may have a playbook that targets first the web servers, and then the database servers. For example:

Playbooks可以包含多个plays。您可能有一个首先针对Web服务器,然后是数据库服务器的手册。例如:

---
- hosts: webservers
  remote_user: root

  tasks:
  - name: ensure apache is at the latest version 确保apache是​​最新版本
    yum:
      name: httpd
      state: latest
  - name: write the apache config file 编写apache配置文件
    template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf

- hosts: databases
  remote_user: root

  tasks:
  - name: ensure postgresql is at the latest version 确保postgresql是最新版本
    yum:
      name: postgresql
      state: latest
  - name: ensure that postgresql is started 确保postgresql启动
    service:
      name: postgresql
      state: started

You can use this method to switch between the host group you’re targeting, the username logging into the remote servers, whether to sudo or not, and so forth. Plays, like tasks, run in the order specified in the playbook: top to bottom.

您可以使用此方法在您要定位的主机组,登录到远程服务器的用户名,是否为sudo等之间切换。与任务一样,播放按照剧本中指定的顺序运行:从上到下。

Below, we’ll break down what the various features of the playbook language are.

下面,我们将分解playbook语言的各种功能。

Basics

基础知识

Hosts and Users

主机列表和用户

For each play in a playbook, you get to choose which machines in your infrastructure to target and what remote user to complete the steps (called tasks) as.

对于剧本中的每个游戏,您可以选择基础架构中的哪些计算机作为目标,以及用什么远程用户完成步骤(称为任务)。

The hosts line is a list of one or more groups or host patterns, separated by colons, as described in the Working with Patterns documentation. The remote_user is just the name of the user account:

hosts行是一个由冒号分隔的一个或多个组或主机模式的列表,如使用模式 文档中所述。remote_user只是用户帐户的名称:

---
- hosts: webservers
  remote_user: root

The remote_user parameter was formerly called just user. It was renamed in Ansible 1.4 to make it more distinguishable from the user module (used to create users on remote systems).

remote_user参数以前只称为user它在Ansible 1.4中重命名,使其与用户模块(用于在远程系统上创建用户)更加区分

Note 注意

The remote_user parameter was formerly called just user. It was renamed in Ansible 1.4 to make it more distinguishable from the user module (used to create users on remote systems).

该remote_user参数以前只称为user。它在Ansible 1.4中重命名,使其与用户模块(用于在远程系统上创建用户)更加区分。

Remote users can also be defined per task:

每个任务也可以定义远程用户:

---
- hosts: webservers
  remote_user: root
  tasks:
    - name: test connection
      ping:
      remote_user: yourname

Support for running things as another user is also available (see Understanding Privilege Escalation):

还可以支持以另一个用户身份运行(请参阅了解权限提升):

---
- hosts: webservers
  remote_user: yourname
  become: yes

You can also use become on a particular task instead of the whole play:

您还可以使用成为特定任务而不是整个游戏:

---
- hosts: webservers
  remote_user: yourname
  tasks:
    - service:
        name: nginx
        state: started
      become: yes
      become_method: sudo

You can also login as you, and then become a user different than root:

您也可以像您一样登录,然后成为与root不同的用户:

---
- hosts: webservers
  remote_user: yourname
  become: yes
  become_user: postgres

You can also use other privilege escalation methods, like su:

您还可以使用其他权限提升方法,例如su:

---
- hosts: webservers
  remote_user: yourname
  become: yes
  become_method: su

If you need to specify a password to sudo, run ansible-playbook with --ask-become-pass or when using the old sudo syntax --ask-sudo-pass (-K). If you run a become playbook and the playbook seems to hang, it’s probably stuck at the privilege escalation prompt. Just Control-C to kill it and run it again adding the appropriate password.

如果您需要为sudo指定密码,请ansible-playbook使用--ask-become-pass或使用旧的sudo语法--ask-sudo-pass-K)运行。如果你运行一个成为playbook并且剧本似乎挂起,它可能会停留在权限提升提示下。只需控制-C来杀死它并再次运行它添加适当的密码。

重要
When using become_user to a user other than root, the module arguments are briefly written into a random tempfile in /tmp. These are deleted immediately after the command is executed. This only occurs when changing privileges from a user like ‘bob’ to ‘timmy’, not when going from ‘bob’ to ‘root’, or logging in directly as ‘bob’ or ‘root’. If it concerns you that this data is briefly readable (not writable), avoid transferring unencrypted passwords with become_user set. In other cases, /tmp is not used and this does not come into play. Ansible also takes care to not log password parameters.
当使用become_user非root用户时,模块参数会被简单地写入随机的临时文件中/tmp。执行命令后立即删除它们。这种情况只发生在将用户从'bob'更改为'timmy'时的权限,而不是从'bob'更改为'root',或直接以'bob'或'root'身份登录时。如果您担心此数据可以短暂读取(不可写),请避免使用become_user设置传输未加密的密码 。在其他情况下,/tmp不使用,这不会发挥作用。Ansible还注意不记录密码参数。

New in version 2.4.版本2.4中的新功能。

You can also control the order in which hosts are run. The default is to follow the order supplied by the inventory:

您还可以控制运行主机的顺序。默认设置是遵循库存inventory提供的顺序:

- hosts: all
  order: sorted
  gather_facts: False
  tasks:
    - debug:
        var: inventory_hostname

Possible values for order are:

顺序的值

inventory:
The default. The order is ‘as provided’ by the inventory 
默认值。订单由库存“提供”
reverse_inventory:
As the name implies, this reverses the order ‘as provided’ by the inventory
顾名思义,这会反转库存“按提供”的顺序
sorted:
Hosts are alphabetically sorted by name
主机按名称按字母顺序排序
reverse_sorted:
Hosts are sorted by name in reverse alphabetical order
主机按名称按反向字母顺序排序
shuffle:
   Hosts are randomly ordered each run
   主机是每次运行随机排序的

Tasks list

任务列表

Each play contains a list of tasks. Tasks are executed in order, one at a time, against all machines matched by the host pattern, before moving on to the next task. It is important to understand that, within a play, all hosts are going to get the same task directives. It is the purpose of a play to map a selection of hosts to tasks.

每个游戏都包含一系列任务。在继续执行下一个任务之前,任务将按顺序执行,对应所有与主机模式匹配的计算机。重要的是要理解,在游戏中,所有主机都将获得相同的任务指令。播放的目的是将选择的主机映射到任务。

When running the playbook, which runs top to bottom, hosts with failed tasks are taken out of the rotation for the entire playbook. If things fail, simply correct the playbook file and rerun.

当运行从上到下运行的剧本时,具有失败任务的主机将从整个剧本的轮换中取出。如果事情失败,只需更正剧本文件并重新运行。

The goal of each task is to execute a module, with very specific arguments. Variables, as mentioned above, can be used in arguments to modules.

每个任务的目标是执行一个具有非常具体参数的模块。如上所述,变量可用于模块的参数。

Modules should be idempotent, that is, running a module multiple times in a sequence should have the same effect as running it just once. One way to achieve idempotency is to have a module check whether its desired final state has already been achieved, and if that state has been achieved, to exit without performing any actions. If all the modules a playbook uses are idempotent, then the playbook itself is likely to be idempotent, so re-running the playbook should be safe.

模块应该是幂等的,也就是说,在序列中多次运行模块应该与仅运行一次模块具有相同的效果。实现幂等性的一种方法是让模块检查是否已经实现了期望的最终状态,并且如果已经实现该状态,则退出而不执行任何动作。如果剧本使用的所有模块都是幂等的,那么剧本本身很可能是幂等的,因此重新运行剧本应该是安全的。

The command and shell modules will typically rerun the same command again, which is totally ok if the command is something like chmod or setsebool, etc. Though there is a creates flag available which can be used to make these modules also idempotent.

commandshell模块通常会再次运行相同的命令,这是完全确定的,如果命令是一样的东西 chmod还是setsebool等虽然有一个creates可用的标志,它可以用来让这些模块也幂等。

Every task should have a name, which is included in the output from running the playbook. This is human readable output, and so it is useful to provide good descriptions of each task step. If the name is not provided though, the string fed to ‘action’ will be used for output.

每个任务都应该有一个name,它包含在运行playbook的输出中。这是人类可读的输出,因此提供每个任务步骤的良好描述是有用的。如果没有提供名称,则输入“action”的字符串将用于输出。

Tasks can be declared using the legacy action: module options format, but it is recommended that you use the more conventional module: options format. This recommended format is used throughout the documentation, but you may encounter the older format in some playbooks.

可以使用旧格式声明任务,但建议您使用更传统的格式。在整个文档中使用了此推荐格式,但在某些剧本中可能会遇到旧格式。action: module optionsmodule: options

Here is what a basic task looks like. As with most modules, the service module takes key=value arguments:

这是基本任务的样子。与大多数模块一样,服务模块采用key=value参数:
tasks:
  - name: make sure apache is running
    service:
      name: httpd
      state: started

The command and shell modules are the only modules that just take a list of arguments and don’t use the key=value form. This makes them work as simply as you would expect:

command shell 模块是只取参数列表,并没有使用唯一的模块key=value形式。这使它们像您期望的那样工作:

tasks:
  - name: enable selinux
    command: /sbin/setenforce 1

The command and shell module care about return codes, so if you have a command whose successful exit code is not zero, you may wish to do this:

command shell 模块关心的返回码,所以如果你有一个命令,其成功退出码不为零,你不妨这样做:

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand || /bin/true

Or this:

或这个:

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True

If the action line is getting too long for comfort you can break it on a space and indent any continuation lines:

如果动作线太长而不舒服,你可以在空格上打破它并缩进任何延续线:

tasks:
  - name: Copy ansible inventory file to client
    copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
            owner=root group=root mode=0644

Variables can be used in action lines. Suppose you defined a variable called vhost in the vars section, you could do this:

变量可用于动作行。假设您定义了一个vhost在该vars部分中调用的变量,您可以这样做:

tasks:
  - name: create a virtual host file for {{ vhost }}
    template:
      src: somefile.j2
      dest: /etc/httpd/conf.d/{{ vhost }}

Those same variables are usable in templates, which we’ll get to later.

这些相同的变量可以在模板中使用,我们将在稍后介绍。

Now in a very basic playbook all the tasks will be listed directly in that play, though it will usually make more sense to break up tasks as described in Creating Reusable Playbooks.

现在,在一个非常基本的游戏手册中,所有任务都将直接列在该游戏中,尽管按创建可重复使用的手册中的描述分解任务通常更有意义

Action Shorthand

动作简写

New in version 0.8.

版本0.8中的新功能。

Ansible prefers listing modules like this:

Ansible更喜欢列出这样的模块:

template:
    src: templates/foo.j2
    dest: /etc/foo.conf

Early versions of Ansible used the following format, which still works:

早期版本的Ansible使用以下格式,它仍然有效:

action: template src=templates/foo.j2 dest=/etc/foo.conf

Handlers: Running Operations On Change

处理程序:在变更时运行操作

As we’ve mentioned, modules should be idempotent and can relay when they have made a change on the remote system. Playbooks recognize this and have a basic event system that can be used to respond to change.

正如我们所提到的,模块应该是幂等的,并且可以在他们对远程系统进行更改时进行中继。Playbooks认识到这一点,并拥有一个可用于响应变化的基本事件系统。

These ‘notify’ actions are triggered at the end of each block of tasks in a play, and will only be triggered once even if notified by multiple different tasks.

这些“通知”操作在游戏中的每个任务块结束时触发,即使由多个不同任务通知也只会触发一次。

For instance, multiple resources may indicate that apache needs to be restarted because they have changed a config file, but apache will only be bounced once to avoid unnecessary restarts.

例如,多个资源可能表示需要重新启动apache,因为他们已经更改了配置文件,但是apache只会被弹回一次以避免不必要的重启。

Here’s an example of restarting two services when the contents of a file change, but only if the file changes:

以下是在文件内容发生更改时重新启动两个服务的示例,但仅在文件更改时:

- name: template configuration file
  template:
    src: template.j2
    dest: /etc/foo.conf
  notify:
     - restart memcached
     - restart apache

The things listed in the notify section of a task are called handlers.

notify任务部分中列出的内容称为处理程序。

Handlers are lists of tasks, not really any different from regular tasks, that are referenced by a globally unique name, and are notified by notifiers. If nothing notifies a handler, it will not run. Regardless of how many tasks notify a handler, it will run only once, after all of the tasks complete in a particular play.

处理程序是由全局唯一名称引用并由通知程序通知的任务列表,与常规任务实际上没有任何不同。如果没有通知处理程序,它将不会运行。无论通知处理程序的任务有多少,在特定游戏中完成所有任务后,它只会运行一次。

Here’s an example handlers section:

这是一个示例处理程序部分:

handlers:
    - name: restart memcached
      service:
        name: memcached
        state: restarted
    - name: restart apache
      service:
        name: apache
        state: restarted

As of Ansible 2.2, handlers can also “listen” to generic topics, and tasks can notify those topics as follows:

从Ansible 2.2开始,处理程序也可以“监听”通用主题,任务可以通知如下主题:

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"

This use makes it much easier to trigger multiple handlers. It also decouples handlers from their names, making it easier to share handlers among playbooks and roles (especially when using 3rd party roles from a shared source like Galaxy).

这种使用使得触发多个处理程序变得更加容易。它还将处理程序与其名称分离,从而更容易在playbooks和角色之间共享处理程序(特别是在使用Galaxy等共享源中的第三方角色时)。

注意
Notify handlers are always run in the same order they are defined, not in the order listed in the notify-statement. This is also the case for handlers using listen.
通知处理程序始终按照定义的顺序运行,而不是以notify-statement中列出的顺序运行。使用listen的处理程序也是如此。
Handler names and listen topics live in a global namespace.
处理程序名称和侦听主题位于全局命名空间中。
If two handler tasks have the same name, only one will run. *
如果两个处理程序任务具有相同的名称,则只运行一个。 *
You cannot notify a handler that is defined inside of an include. As of Ansible 2.1, this does work, however the include must be static.
您无法通知在include内定义的处理程序。从Ansible 2.1开始,这确实有效,但是include必须是静态的。

  

Roles are described later on, but it’s worthwhile to point out that:

角色将在后面描述,但值得指出的是:

  • handlers notified within pre_taskstasks, and post_tasks sections are automatically flushed in the end of section where they were notified;
  • 处理程序中通知pre_taskstasks以及post_tasks部分是在那里他们被通知部的端部自动刷新;
  • handlers notified within roles section are automatically flushed in the end of tasks section, but before any taskshandlers.
  • roles部分内通知的处理程序在部分末尾自动刷新tasks,但在任何tasks处理程序之前。

If you ever want to flush all the handler commands immediately you can do this:

如果您想立即刷新所有处理程序命令,可以执行以下操作:

tasks:
   - shell: some tasks go here
   - meta: flush_handlers
   - shell: some other tasks

In the above example any queued up handlers would be processed early when the meta statement was reached. This is a bit of a niche case but can come in handy from time to time.

在上面的示例中,任何排队的处理程序将在meta 到达语句时尽早处理这是一个利基案例,但可以不时派上用场。

Executing A Playbook

Now that you’ve learned playbook syntax, how do you run a playbook? It’s simple. Let’s run a playbook using a parallelism level of 10:

既然你已经学会了剧本语法,你如何运行剧本?这很简单。让我们使用10的并行度级别运行一个剧本

ansible-playbook playbook.yml -f 10

Ansible-Pull

Should you want to invert the architecture of Ansible, so that nodes check in to a central location, instead of pushing configuration out to them, you can.

如果您想要反转Ansible的体系结构,以便节点检入中心位置,而不是将配置推送到它们,您可以。

The ansible-pull is a small script that will checkout a repo of configuration instructions from git, and then run ansible-playbook against that content.

ansible-pull是一个小脚本,将从git检出配置指令的repo,然后ansible-playbook针对该内容运行

Assuming you load balance your checkout location, ansible-pull scales essentially infinitely.

假设您对结帐位置进行负载均衡,则ansible-pull无限扩展。

Run ansible-pull --help for details.

运行详细信息。ansible-pull --help

There’s also a clever playbook available to configure ansible-pull via a crontab from push mode.

还有一个聪明的手册可以ansible-pull通过推送模式从crontab 进行配置

Tips and Tricks

提示和技巧

To check the syntax of a playbook, use ansible-playbook with the --syntax-check flag. This will run the playbook file through the parser to ensure its included files, roles, etc. have no syntax problems.

要检查剧本的语法,使用ansible-playbook--syntax-check标志。这将通过解析器运行playbook文件,以确保其包含的文件,角色等没有语法问题。

Look at the bottom of the playbook execution for a summary of the nodes that were targeted and how they performed. General failures and fatal “unreachable” communication attempts are kept separate in the counts.

查看playbook执行的底部,了解目标节点及其执行方式的摘要。一般失败和致命的“无法到达”的通信尝试在计数中保持分开。

If you ever want to see detailed output from successful modules as well as unsuccessful ones, use the --verbose flag. This is available in Ansible 0.5 and later.

如果您想查看成功模块以及不成功模块的详细输出,请使用该--verbose标志。这在Ansible 0.5及更高版本中可用。

To see what hosts would be affected by a playbook before you run it, you can do this:

要在运行之前查看哪个主机会受到剧本的影响,您可以执行以下操作:

ansible-playbook playbook.yml --list-hosts

See also 也可以看看

YAML Syntax
Learn about YAML syntax 了解YAML语法
Best Practices
Various tips about managing playbooks in the real world 关于在现实世界中管理剧本的各种提示
All modules
Learn about available modules 了解可用的模块
Developing Modules
Learn how to extend Ansible by writing your own modules 了解如何通过编写自己的模块来扩展Ansible
Working with Patterns 
Learn about how to select hosts 了解如何选择主机
Github examples directory
Complete end-to-end playbook examples 完整的端到端剧本示例
Mailing List
Questions? Help? Ideas? Stop by the list on Google Groups 有问题吗?帮帮我?想法?停止在Google网上论坛列表中
posted on 2018-09-01 20:56  CevinChen  阅读(205)  评论(0编辑  收藏  举报