问题描述
在使用Ansible时,希望在每个角色运行之前和之后执行一些操作。用户已经尝试使用pre_tasks
和post_tasks
,但是找不到一种可以透明地为所有定义的角色/剧本包含它们的方法。用户不想手动将它们添加到所有剧本中,因为这样会导致维护困难。用户还考虑过滥用Ansible通过SSH登录的特性,但是不知道如何区分Ansible登录和普通用户登录。用户的具体问题是:他想在每个角色执行之前和之后触发etckeeper
。
如果你有其他解决这个问题的“开箱即用”的想法,我将非常感谢听到它们。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
你可以使用include_role
模块来实现在每个角色运行之前和之后执行任务。以下是一种可能的实现方式:
1. 创建一个顶层剧本文件,例如main.yml
。
2. 在该文件中定义需要运行的角色。
3. 在每个角色之前和之后添加执行任务的步骤。
下面是一个示例main.yml
文件:
---
- name: Example
hosts: all
tasks:
- name: etckeeper pre-actions
meta: noop
- include_role:
name: first_role
- name: etckeeper post-actions
meta: noop
- include_role:
name: second_role
- name: etckeeper post-actions
meta: noop
- include_role:
name: third_role
- name: etckeeper post-actions
meta: noop
在上面的示例中,我们定义了一个名为Example
的剧本,其中包含了需要运行的角色。在每个角色之前和之后,我们添加了执行etckeeper
任务的步骤。通过使用include_role
模块,我们可以在每个角色运行之前和之后执行自定义的任务。
方案2
另一种方法是创建一个名为wrap_role
的角色,该角色包含在每个角色运行之前和之后执行的任务。以下是一种可能的实现方式:
1. 创建一个名为wrap_role
的角色。
2. 在wrap_role
的tasks/main.yml
文件中定义在每个角色运行之前和之后执行的任务。
3. 在顶层剧本中使用wrap_role
角色,并指定要运行的角色。
下面是一个示例wrap_role
角色的结构:
wrap_role/
├── tasks/
│ └── main.yml
└── meta/
└── main.yml
tasks/main.yml
文件的内容如下:
---
# Replace this task with your actual before-role etckeeper task
- name: etckeeper pre-actions
meta: noop
- include_role:
name: "{{ role_name }}"
# Replace this task with your actual after-role etckeeper task
- name: etckeeper post-actions
meta: noop
在顶层剧本中,你可以像这样使用wrap_role
角色:
---
- name: Example
hosts: all
roles:
- { role: wrap_role, role_name: first_role }
- { role: wrap_role, role_name: second_role }
- { role: wrap_role, role_name: third_role }
在上面的示例中,我们在顶层剧本中使用了wrap_role
角色,并指定了要运行的角色。这样做可以确保在每个角色运行之前和之后执行自定义的任务,同时保持角色的原始定义不变。
请注意,这种方法可能不是理想的解决方案,因为你可能需要修改顶层剧本。但至少它不会影响到角色的原始定义,即使你不得不修改顶层剧本。