不同 linux 发行版的 ansible 相同剧本
ansible same playbook for different linux distribution
我们为安装了 Ubuntu 的节点设计了一个 ansible playbook。
现在我们必须为使用 Centos 的不同客户在新机器(节点)上播放相同的 Playbook。
问题是对于 Centos,Ansible 使用 Yum 模块(使用 yum 包管理器安装模块)。在我们的实际剧本中,我们显然正在使用 apt 模块。
Ansible 建议如何更好地管理这种情况?
- 是不是重写一个版本的Centos playbook比较好?
- 还是保持相同的剧本并在 Ubuntu 上动态使用“apt”更好?或 centos 上的 Yum?
- 还有其他更合适的方案吗?
The problem is that for Centos, Ansible uses Yum module (wich use yum package manager to install module). In our actual playbook, we are obviously using apt module.
您最好使用 package
模块,它将 select 一个适合目标机器的合适的包管理器。然后你只需要维护包名称的每个分发列表,但任务本身可以相同。
也就是说,你可以这样写:
- hosts: all
tasks:
- name: Set OS distribution dependent variables
include_vars: "os_{{ ansible_facts['distribution'] }}.yml"
- name: install required packages
package:
name: "{{ required_packages }}"
state: installed
在您的剧本旁边,有文件 os_Ubuntu.yml
和 os_CentOS.yml
,并在这些文件中设置 required_packages
变量。
一种常见的方法是为多个发行版编写一个剧本,剧本中有许多条件,或者只是将特定于发行版的任务分成不同的文件,并将这些文件包含到主要角色中,就像这样
# Perform distro-specific tasks.
- include_tasks: setup-"{{ ansible_distribution }}".yml
因此,在文件 setup-Ubuntu.yml
、setup-CentOS.yml
等中,您将保留特定于特定 Linux 的所有操作。另请参阅 Geerlingguy 的角色,例如 this one 作为合适的示例。
如果您只想安装或删除软件包而不使用 apt 或 yum 的更复杂的功能,您可以使用 package module,这相当简单,但如果这对您来说足够了,那么您将得到相同的结果不同 Linux 口味的代码。
此外,您需要考虑到 Ubuntu 和 CentOS 中的许多文件(包括配置文件和程序二进制文件)位于不同的位置。因此,如果您决定使用 package 模块,您可以通过使用外部文件来处理特定于发行版的事情,如下所示:
- name: Load a variable file based on the OS type, or a default if not found.
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution }}-vars.yaml"
- "{{ ansible_os_family }}-vars.yaml"
- default-vars.yaml
完成此任务后,您可以使用上述文件中定义的变量,这些变量使用特定于您的平台的值初始化,如下所示
- name: Apply some config template
template:
src: my_config_template.j2
dest: "{{ distro_specific_destination }}"
validate: "{{ distro_specific_command }} %s"
我们为安装了 Ubuntu 的节点设计了一个 ansible playbook。
现在我们必须为使用 Centos 的不同客户在新机器(节点)上播放相同的 Playbook。
问题是对于 Centos,Ansible 使用 Yum 模块(使用 yum 包管理器安装模块)。在我们的实际剧本中,我们显然正在使用 apt 模块。
Ansible 建议如何更好地管理这种情况?
- 是不是重写一个版本的Centos playbook比较好?
- 还是保持相同的剧本并在 Ubuntu 上动态使用“apt”更好?或 centos 上的 Yum?
- 还有其他更合适的方案吗?
The problem is that for Centos, Ansible uses Yum module (wich use yum package manager to install module). In our actual playbook, we are obviously using apt module.
您最好使用 package
模块,它将 select 一个适合目标机器的合适的包管理器。然后你只需要维护包名称的每个分发列表,但任务本身可以相同。
也就是说,你可以这样写:
- hosts: all
tasks:
- name: Set OS distribution dependent variables
include_vars: "os_{{ ansible_facts['distribution'] }}.yml"
- name: install required packages
package:
name: "{{ required_packages }}"
state: installed
在您的剧本旁边,有文件 os_Ubuntu.yml
和 os_CentOS.yml
,并在这些文件中设置 required_packages
变量。
一种常见的方法是为多个发行版编写一个剧本,剧本中有许多条件,或者只是将特定于发行版的任务分成不同的文件,并将这些文件包含到主要角色中,就像这样
# Perform distro-specific tasks.
- include_tasks: setup-"{{ ansible_distribution }}".yml
因此,在文件 setup-Ubuntu.yml
、setup-CentOS.yml
等中,您将保留特定于特定 Linux 的所有操作。另请参阅 Geerlingguy 的角色,例如 this one 作为合适的示例。
如果您只想安装或删除软件包而不使用 apt 或 yum 的更复杂的功能,您可以使用 package module,这相当简单,但如果这对您来说足够了,那么您将得到相同的结果不同 Linux 口味的代码。
此外,您需要考虑到 Ubuntu 和 CentOS 中的许多文件(包括配置文件和程序二进制文件)位于不同的位置。因此,如果您决定使用 package 模块,您可以通过使用外部文件来处理特定于发行版的事情,如下所示:
- name: Load a variable file based on the OS type, or a default if not found.
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution }}-vars.yaml"
- "{{ ansible_os_family }}-vars.yaml"
- default-vars.yaml
完成此任务后,您可以使用上述文件中定义的变量,这些变量使用特定于您的平台的值初始化,如下所示
- name: Apply some config template
template:
src: my_config_template.j2
dest: "{{ distro_specific_destination }}"
validate: "{{ distro_specific_command }} %s"