最佳实践

    你能在我们的 .找到展示这些最佳实践的 playbook 样例.(注意: 这些示例用的也许不是最新版的中所有特性,但它们仍旧是极佳的参考.)

    接下来的章节将向你展示一种组织 playbook 内容方式.

    你对 Ansible 的使用应该符合你的需求而不是我们的,所以请随意根据你的需求来组织修改接下来的示例.

    有件事绝对是你想要做的,那就是使用 “roles” 组织特性.它作为主要的 playbook 的主要部分被文档化.详情参见 Playbook Roles and Include Statements. 你绝对应该使用 roles.roles 是极好的. 快去使用 roles! roles! 重要的事情要重复说!roles 是极好的.(译者:..老外也知道重要的事情重复三遍啊!~~~)

    顶层目录结构应当包括下列文件和目录:

    Use Dynamic Inventory With Clouds

    如果你正在使用云服务,你不应该在一个静态文件管理你的清单.详见 .

    这不仅适用于云环境 – 如果你的基础设施中还有其他系统维护着一系列标准系统,使用 动态清单 会是个好主意.

    If managing static inventory, it is frequently asked how to differentiate different types of environments. The following exampleshows a good way to do this. Similar methods of grouping could be adapted to dynamic inventory (for instance, consider applying the AWStag “environment:production”, and you’ll get a group of systems automatically discovered named “ec2_tag_environment_production”.

    如果你管理着静态清单,如何区分不同的环境类型是个常见的问题.接下来的示例会做一个很好地说明.

    Let’s show a static inventory example though. Below, the production file contains the inventory of all of your production hosts.

    It is suggested that you define groups based on purpose of the host (roles) and also geography or datacenter location (if applicable):

    1. # file: production
    2.  
    3. [atlanta-webservers]
    4. www-atl-1.example.com
    5. www-atl-2.example.com
    6.  
    7. [boston-webservers]
    8. www-bos-1.example.com
    9. www-bos-2.example.com
    10.  
    11. [atlanta-dbservers]
    12. db-atl-1.example.com
    13. db-atl-2.example.com
    14.  
    15. [boston-dbservers]
    16. db-bos-1.example.com
    17.  
    18. # webservers in all geos
    19. [webservers:children]
    20. atlanta-webservers
    21. boston-webservers
    22.  
    23. # dbservers in all geos
    24. [dbservers:children]
    25. atlanta-dbservers
    26. boston-dbservers
    27.  
    28. # everything in the atlanta geo
    29. [atlanta:children]
    30. atlanta-dbservers
    31.  
    32. # everything in the boston geo
    33. [boston:children]
    34. boston-webservers
    35. boston-dbservers

    Group And Host Variables

    本章节内容基于前一章节示例.

    分组有利于组织结构,但不是所有的分组都是有益的.你也可以给他们赋值!比如说亚特兰大有它自己的网络时间协议,所以当配置 ntp.conf 时,我们就该使用它.让我们现在设置它们:

    1. ---
    2. # file: group_vars/atlanta
    3. ntp: ntp-atlanta.example.com
    4. backup: backup-atlanta.example.com

    Variables aren’t just for geographic information either! Maybe the webservers have some configuration that doesn’t make sense for the database servers:

    1. ---
    2. # file: group_vars/webservers
    3. apacheMaxRequestsPerChild: 3000
    4. apacheMaxClients: 900

    If we had any default values, or values that were universally true, we would put them in a file called group_vars/all:

    1. ---
    2. # file: group_vars/all
    3. ntp: ntp-boston.example.com
    4. backup: backup-boston.example.com

    We can define specific hardware variance in systems in a host_vars file, but avoid doing this unless you need to:

    1. ---
    2. # file: host_vars/db-bos-1.example.com
    3. foo_agent_port: 86
    4. bar_agent_port: 99

    Again, if we are using dynamic inventory sources, many dynamic groups are automatically created. So a tag like “class:webserver” would load invariables from the file “group_vars/ec2_tag_class_webserver” automatically.

    1. ---
    2. # file: site.yml
    3. - include: webservers.yml
    4. - include: dbservers.yml

    在诸如 like webservers.yml 的文件中(同样也在顶层结构),我们仅仅将 Web 服务器组与对应的 role 行为做映射.同样值得注意的是这也非常的短小精悍.例如:

    理念是我们能够通过 “运行”(running) site.yml 来选择整个基础设施的配置.或者我们能够通过运行其子集 webservers.yml 来配置.这与 Ansible 的 “–limit” 类似,而且相对的更为显式:

    1. ansible-playbook site.yml --limit webservers
    2. ansible-playbook webservers.yml

    Task And Handler Organization For A Role

    接下来的示例任务文件展示了一个 role 是如何工作的.我们这里的普通 role 仅仅用来配置 NTP,但是如果我们想的话,它可以做更多:

    1. ---
    2. # file: roles/common/tasks/main.yml
    3.  
    4. - name: be sure ntp is installed
    5. yum: pkg=ntp state=installed
    6. tags: ntp
    7.  
    8. - name: be sure ntp is configured
    9. template: src=ntp.conf.j2 dest=/etc/ntp.conf
    10. notify:
    11. - restart ntpd
    12. tags: ntp
    13.  
    14. - name: be sure ntpd is running and enabled
    15. service: name=ntpd state=running enabled=yes
    16. tags: ntp

    这是个处理文件样例.作为一种审核,它只有当特定的任务报告发生变化时会被触发,并在每个 play 结束时运行:

    1. ---
    2. # file: roles/common/handlers/main.yml
    3. - name: restart ntpd
    4. service: name=ntpd state=restarted

    详情请参阅 Playbook Roles and Include Statements.

    我们在前文分享了我们基础的组织结构.

    那这种结构适用于何种应用场景? 很多!若我想重新配置整个基础设施,如此即可:

      那只重新配置所有的 NTP 呢?太容易了.:

      1. ansible-playbook -i production site.yml --tags ntp

      只重新配置我的 Web 服务器呢?:

      1. ansible-playbook -i production webservers.yml

      只重新配置我在波士顿的 Web服务器呢?:

      前10台 和 接下来的10台呢?

      当然,只使用基础的 ad-hoc 也是 OK 的啦.:

      1. ansible boston -i production -m ping
      2. ansible boston -i production -m command -a '/sbin/reboot'

      这里还有些有用的命令你需要知道(版本至少 1.1 或更高):

      1. # confirm what task names would be run if I ran this command and said "just ntp tasks"
      2. ansible-playbook -i production webservers.yml --tags ntp --list-tasks
      3.  
      4. # confirm what hostnames might be communicated with if I said "limit to boston"
      5. ansible-playbook -i production webservers.yml --limit boston --list-hosts

      Deployment vs Configuration Organization

      The above setup models a typical configuration topology. When doing multi-tier deployments, there are goingto be some additional playbooks that hop between tiers to roll out an application. In this case, ‘site.yml’may be augmented by playbooks like ‘deploy_exampledotcom.yml’ but the general concepts can still apply.

      Consider “playbooks” as a sports metaphor – you don’t have to just have one set of plays to use against your infrastructureall the time – you can have situational plays that you use at different times and for different purposes.

      Ansible allows you to deploy and configure using the same tool, so you would likely reuse groups and justkeep the OS configuration in separate playbooks from the app deployment.

      Stage vs Production

      如前所述,通过使用不同的清单文件来分离你的 stage 和 生产环境是个好方法.你可以通过 -i 来指定.把它们放在同一个文件中会有惊喜哦!在部署到生产环境之前,先在 stage 环境中做测试是个好主意.你的环境不必保持同样的大小,你可以通过 分组变量来对不同的环境进行控制.

      Rolling Updates

      See .

      parameter in your playbooks to make it clear, especially as some modules support additional states.对于很多模块来说 ‘state’ 参数是可选的.无论是 ‘state=present’ 亦或 ‘state=absent’ ,你最好在 playbook 中显式指定该参数,毕竟有些模块是支持附加的 ‘state’ 参数.

      Group By Roles

      在这条贴士中,我们某种程度上在重复自己,但这是值得的.一个系统可能被分成多分组.详情请查阅 Inventory文件 和 .在样例中,分组名之后的 webserversdbservers ,它们因为是很重要的概念所以反复出现.(译者:恩,重要的事情要重复三遍!)一个系统可以出现在多个分组中.

      通过给 role 赋予特定的变量,这允许 playbooks 能基于角色来锁定机器.

      See Playbook Roles and Include Statements.

      Operating System and Distribution Variance

      当处理在不同操作系统间参数值不同的参数时,使用 group_by 模块是个好主意.

      这使宿主机的动态分组有了匹配的标准,即使该分组尚未在清单文件中被定义

      1. ---
      2.  
      3. # talk to all hosts just so we can learn about them
      4. - hosts: all
      5. tasks:
      6. - group_by: key=os_{{ ansible_distribution }}
      7.  
      8. # now just on the CentOS hosts...
      9.  
      10. - hosts: os_CentOS
      11. gather_facts: False
      12. tasks:
      13. - # tasks that only happen on CentOS go here

      这会抛出所有基于操作系统名的分组.

      如果需要对特定分组做设定,这也是可以的.例:

      1. ---
      2. # file: group_vars/all
      3. asdf: 10
      4.  
      5. ---
      6. # file: group_vars/os_CentOS
      7. asdf: 42

      在上述的例子中, CentOS 的机器获取的 asdf 的值为 42,但其他机器获得是 ‘10’.这不止可以用于设置变量,也可以将特定的 role 应用于特定的操作系统.

      相对的,如果只需要变量:

      1. - hosts: all
      2. tasks:
      3. - include_vars: "os_{{ ansible_distribution }}.yml"
      4. - debug: var=asdf

      这将根据操作系统名来拉取相应的值.

      如果一个 playbook 有一个与它 YMAL 文件相关的 ”./library” 目录,该目录可以用于添加 Ansible 模块,它会被自动添加到 Ansible 模块的路径中.这是一个将playbook 与其模块放置在一起的方式.如下面的目录结构样例所展示:

      1. .. _whitespace:

      Whitespace and Comments

      鼓励使用空格来分隔内容,用 ‘#’ 来写注释.

      Always Name Tasks

      虽然推荐提供关于为什么要这么做的描述,但是直接给一个给定任务命名也是可以的.名字会在 playbook 运行时显示.

      当你能简单的搞定某事时,就简单的搞定.不要试图一次性使用 Ansible 的所有的特性.仅仅使用对你有用的即可.比如说你基本上不会需要一次性使用 , , 和 同时还是用一个外部的节点配置文件.

      如果你感觉任务很复杂时,它可能真的很复杂,这也许是个简化它的好机会.

      Version Control

      See also

      • Learn about YAML syntax
      • Playbooks
      • Review the basic playbook features
      • Learn about available modules
      • Developing Modules
      • Learn how to extend Ansible by writing your own modules
      • Learn about how to select hosts
      • GitHub examples directory
      • Complete playbook files from the github project source
      • Questions? Help? Ideas? Stop by the list on Google Groups