1
2
3
4
5
作者:李晓辉

微信联系:Lxh_Chat

联系邮箱: 939958092@qq.com

Ansible Playbook的最佳实践

当您处理更为⾼级的功能和更⼤、更复杂的项⽬时,管理和维护 Ansible Playbook 或有效使⽤它们将变得更加困难。有效使⽤ Ansible 取决于三个关键实践:

  • 保持简单
  • 井然有序
  • 经常测试

Ansible 的⼀⼤⻓处是简洁性。 简单的 playbook 更易于使⽤、修改和理解。

增加可读性

  • 添加注释:清晰的注释可以帮助理解代码的目的和每个步骤的功能。

  • 逻辑之间空行隔开:通过适当的空行让代码更清晰,便于阅读和维护。

  • 为 Play 和 Task 起一个有意义的名称:命名应该能准确描述其功能,避免模糊的名称。

  • 保持风格统一:使用统一的格式,比如相同的空格数量、变量命名规则、注释要求等。

  • 利用角色提高效率:角色可以帮助将 Playbook 模块化,使代码更加清晰、可重用,并方便维护。

  • 遵循 YAML 的原生语法:尽量不要将所有参数放在一行,遵循 YAML 格式的标准,以增强可读性。

语法对比

推荐使用的原生语法如下:

1
2
3
4
5
6
7
8
9
- name: Postfix is installed and updated
ansible.builtin.yum:
name: postfix
state: latest
notify: update_postfix
- name: Postfix is running
ansible.builtin.service:
name: postfix
state: started

以下为不推荐的写法:

1
2
3
4
5
- name: Postfix is installed and updated
ansible.builtin.yum: name=postfix state=latest
notify: restart_postfix
- name: Postfix is running
ansible.builtin.service: name=postfix state=started

正确命名变量

  • 变量的命名应该清晰地表达其含义,确保变量名能够准确反映它存储的数据。

  • 为了提高变量的可读性,最好使用描述性强的名字,例如使用 apache_tls_port 作为变量名,而不是使用单一字母如 p

  • 如果某个角色的名称是 myapp,则可以在变量前加上 myapp_ 前缀,这样可以更容易地识别变量与角色的关联。

使用模块而不是命令

Ansible Playbook 本身是幂等的,也就是说,无论运行多少次,它的结果都是一致的。然而,如果使用 ansible.builtin.commandansible.builtin.shellansible.builtin.raw 等模块,可能会破坏幂等性,因为这些模块在每次执行时都会直接执行命令或脚本,没有检查系统的当前状态。因此,我们应尽量减少使用这三种特殊的模块。

在调试时,ansible.builtin.debug 模块非常有用。它可以帮助你打印出变量的值或某些调试信息,帮助分析 Playbook 的执行过程。

此外,许多 Ansible 模块都有类似于 state 的参数,应该显式地指定这些参数的值,而不是依赖于默认行为。这样做不仅有助于提高 Playbook 的可读性,还能避免后期 Ansible 版本中默认行为的变更可能导致的负面影响。

使用集合或角色复用内容

角色和集合是让 Playbook 简单高效的好帮手。它们就像把常用的代码打包成模块,这样你就可以在不同项目之间复用,省了不少力气。如果需要的话,你还可以创建一个自定义的自动化执行环境,进一步提高代码的重用性和一致性。

通常,你可以从这些地方获取角色或集合:

  1. 红帽官方网站 - 这里有官方支持的集合和角色,适合企业级的环境。
  2. Ansible Galaxy - 这是 Ansible 社区的宝库,你可以找到成千上万的社区贡献代码。
  3. GitHub - 很多开发者会在 GitHub 上分享他们的 Ansible 角色和集合,你可以直接用或者根据需要修改。
  4. 公司内部仓库 - 如果你们公司有自己的仓库,那就能找到一些专门为公司定制的集合和角色,方便使用。

集中运行Playbook

你可以考虑使用一个专门的控制节点,让所有 Ansible Playbook 都通过它来执行。最好还是使用 自动化控制器,理由也很简单:Ansible 需要对被管理的机器有控制权限。如果你频繁更换控制节点,可能会导致 Playbook 无法正常运行,甚至引发一些安全问题。所以,统一管理控制节点,不仅能确保 Playbook 的顺利执行,还能降低出错和安全风险。

动态清单介绍

在被管理主机不是一尘不变时,可以用动态清单来获取具体的主机列表,然后再运行playbook

也可以用group_by模块来动态生成主机组,提高playbook运行效率

1
2
3
4
5
6
7
8
9
10
- name: Generate dynamic groups
hosts: all
tasks:
- name: Generate dynamic groups based on architecture
ansible.builtin.group_by:
key: arch_"{{ ansible_facts['architecture'] }}"
- name: Configure x86_64 systems
hosts: arch_x86_64
tasks:
- name: First task for x86_64 configuration

测试任务的结果

除了使用debug模块之外,还可以使用uri模块用于验证web类型的服务是否正常

1
2
3
4
5
6
7
8
9
10
- name: Start web server
ansible.builtin.service:
name: httpd
status: started
- name: Check web site from web server
ansible.builtin.uri:
url: http://{{ ansible_fqdn }}
return_content: true
register: example_webpage
failed_when: example_webpage.status != 200

Block 和 Rescue

1
2
3
4
5
6
7
8
9
10
11
12
- block:
- name: Check web site from web server
ansible.builtin.uri:
url: http://{{ ansible_fqdn }}
return_content: true
register: example_webpage
failed_when: example_webpage.status != 200
rescue:
- name: Restart web server
ansible.builtin.service:
name: httpd
status: restarted

使⽤测试⼯具

语法检查:

1
[student@workstation ~]$ ansible-navigator run playbook --syntax-check -m stdout

分析playbook错误:

1
2
[student@workstation ~]$ ansible-lint xxx.yaml
[student@workstation ~]$ yamllint xxx.yaml

新版本测试

即使你不打算在生产环境中使用 Ansible Core 的最新版本,也应该定期在最新版本上测试你的 Playbook。这样做能帮助你避开因 Ansible 模块和功能不断变化而出现的问题。

如果你的 Playbook 在运行时显示警告或弃用信息,那就得注意了!这些提示可能表明某些功能即将被删除或改变。通常,Ansible 会提前四个版本通知你该功能被弃用,因此你应该及时调整代码,避免将来遇到问题。