Ansible:如何通过在主机上附加文件的任务实现幂等性(w/o 恢复到初始状态)
Ansible: how to achieve idempotence with tasks that append files on host (w/o reverting to initial state)
我很难了解如何根据文档创建遵循最佳实践的 Ansible 角色。我正在查看的以下用例是例如在主机上启用 Filebeat。可以通过将模块定义放在 /etc/filebeat/modules.d
文件夹中来配置 Filebeat。
添加模块时它工作正常。每次,幂等性在角色(剧本)的每个 运行 上起作用,启用一组给定的模块。
但是当我决定不再需要某个模块时我应该怎么做?我将其从角色中删除,重新 运行 剧本,以便启用所有 other 模块。 但是:之前的运行启用了一个模块,我在更改后没有直接安装角色。所以我的服务器状态仍然以不同于角色强加的方式改变。
我的问题是:我是否应该在应用模块之前注意删除模块,以便我始终从新状态开始?
例如:
- name: Remove modules
file:
dest: "/etc/filebeat/modules.d/{{ item }}"
state: absent
loop:
- "module1.yml"
- "module2.yml"
- "module3.yml" # It was being installed in previous role, but not now
- name: Enable modules via 'modules.d' directory
template:
src: "modules.d/{{ item }}"
dest: "/etc/filebeat/modules.d/{{ item }}"
mode: '0644'
loop:
- "module1.yml"
- "module2.yml"
所以我把module3.yml
去掉了,因为我记得以前装过,装module1.yml
和module2.yml
.
而不是只安装我需要的,不管之前安装过什么:
- name: Enable modules via 'modules.d' directory
template:
src: "modules.d/{{ item }}"
dest: "/etc/filebeat/modules.d/{{ item }}"
mode: '0644'
loop:
- "module1.yml"
- "module2.yml"
留给我 module1.yml
和 module2.yml
(期望),不幸的是:module3.yml
(来自以前的角色)。
如何管理以避免这种情况?并避免将服务器视为一台大型有状态机器,即使我 运行 一个角色,输出也与预期不同,因为之前已经完成了一些我在当前 Ansible 角色代码中看不到的事情。
您是否在 Ansible 工作流程中编写 revert
剧本以在需要时恢复到初始状态?
我很好奇。预先感谢您的回复。
简而言之:
- name: Configure filebeat modules
hosts: all
vars:
fb_modules_d:
- file: module1.yml
state: present
- file: module2.yml
state: present
- file: module3.yml
state: absent
tasks:
- name: Make sure all needed module files are present
template:
src: "modules.d/{{ item.file }}"
dest: "/etc/filebeat/modules.d/{{ item.file }}"
mode: '0644'
loop: "{{ fb_modules_d | selectattr('state', '==', 'present') }}"
notifiy: restart_filebeat
- name: Make sure all disabled modules are removed
file:
dest: "/etc/filebeat/modules.d/{{ item.file }}"
state: "{{ item.state }}"
loop: loop: "{{ fb_modules_d | selectattr('state', '==', 'absent') }}"
notify: restart_filebeat
handlers:
- name: Restart filebeat service
listen: restart_filebeat
systemd:
name: filebeat
state: restarted
注意:我在该示例的剧本中声明了变量,但那个变量很可能应该进入您的库存(组或主机级别),当然不在角色中(文档默认值除外)
一个更简单、更可靠的解决方案是删除所有未列出的文件。当您不知道目录的当前状态是什么时,这将特别有用。例如给定目录(相对于PWD进行测试)
shell> tree etc/filebeat/modules.d
etc/filebeat/modules.d
└── module99.yml
下面的剧本
shell> cat playbook.yml
- name: Configure filebeat modules
hosts: localhost
vars:
fb_modules_path: etc/filebeat/modules.d
fb_modules_d:
- module1.yml
- module2.yml
- module3.yml
tasks:
- name: Create modules
template:
src: "modules.d/{{ item }}"
dest: "{{ fb_modules_path }}/{{ item }}"
mode: '0644'
loop: "{{ fb_modules_d }}"
notify: restart_filebeat
- name: Remove modules
file:
dest: "{{ fb_modules_path }}/{{ item }}"
state: absent
loop: "{{ query('fileglob', fb_modules_path ~ '/*')|
map('basename')|
difference(fb_modules_d) }}"
notify: restart_filebeat
handlers:
- name: Restart filebeat service
listen: restart_filebeat
# systemd:
# name: filebeat
# state: restarted
debug:
msg: Restart filebeat
从列表中创建文件并删除其他文件
TASK [Create modules] ***************************************************
changed: [localhost] => (item=module1.yml)
changed: [localhost] => (item=module2.yml)
changed: [localhost] => (item=module3.yml)
TASK [Remove modules] ***************************************************
changed: [localhost] => (item=module99.yml)
RUNNING HANDLER [Restart filebeat service] ******************************
ok: [localhost] =>
msg: Restart filebeat
shell> tree etc/filebeat/modules.d
etc/filebeat/modules.d
├── module1.yml
├── module2.yml
└── module3.yml
剧本是幂等的。
我很难了解如何根据文档创建遵循最佳实践的 Ansible 角色。我正在查看的以下用例是例如在主机上启用 Filebeat。可以通过将模块定义放在 /etc/filebeat/modules.d
文件夹中来配置 Filebeat。
添加模块时它工作正常。每次,幂等性在角色(剧本)的每个 运行 上起作用,启用一组给定的模块。
但是当我决定不再需要某个模块时我应该怎么做?我将其从角色中删除,重新 运行 剧本,以便启用所有 other 模块。 但是:之前的运行启用了一个模块,我在更改后没有直接安装角色。所以我的服务器状态仍然以不同于角色强加的方式改变。
我的问题是:我是否应该在应用模块之前注意删除模块,以便我始终从新状态开始?
例如:
- name: Remove modules
file:
dest: "/etc/filebeat/modules.d/{{ item }}"
state: absent
loop:
- "module1.yml"
- "module2.yml"
- "module3.yml" # It was being installed in previous role, but not now
- name: Enable modules via 'modules.d' directory
template:
src: "modules.d/{{ item }}"
dest: "/etc/filebeat/modules.d/{{ item }}"
mode: '0644'
loop:
- "module1.yml"
- "module2.yml"
所以我把module3.yml
去掉了,因为我记得以前装过,装module1.yml
和module2.yml
.
而不是只安装我需要的,不管之前安装过什么:
- name: Enable modules via 'modules.d' directory
template:
src: "modules.d/{{ item }}"
dest: "/etc/filebeat/modules.d/{{ item }}"
mode: '0644'
loop:
- "module1.yml"
- "module2.yml"
留给我 module1.yml
和 module2.yml
(期望),不幸的是:module3.yml
(来自以前的角色)。
如何管理以避免这种情况?并避免将服务器视为一台大型有状态机器,即使我 运行 一个角色,输出也与预期不同,因为之前已经完成了一些我在当前 Ansible 角色代码中看不到的事情。
您是否在 Ansible 工作流程中编写 revert
剧本以在需要时恢复到初始状态?
我很好奇。预先感谢您的回复。
简而言之:
- name: Configure filebeat modules
hosts: all
vars:
fb_modules_d:
- file: module1.yml
state: present
- file: module2.yml
state: present
- file: module3.yml
state: absent
tasks:
- name: Make sure all needed module files are present
template:
src: "modules.d/{{ item.file }}"
dest: "/etc/filebeat/modules.d/{{ item.file }}"
mode: '0644'
loop: "{{ fb_modules_d | selectattr('state', '==', 'present') }}"
notifiy: restart_filebeat
- name: Make sure all disabled modules are removed
file:
dest: "/etc/filebeat/modules.d/{{ item.file }}"
state: "{{ item.state }}"
loop: loop: "{{ fb_modules_d | selectattr('state', '==', 'absent') }}"
notify: restart_filebeat
handlers:
- name: Restart filebeat service
listen: restart_filebeat
systemd:
name: filebeat
state: restarted
注意:我在该示例的剧本中声明了变量,但那个变量很可能应该进入您的库存(组或主机级别),当然不在角色中(文档默认值除外)
一个更简单、更可靠的解决方案是删除所有未列出的文件。当您不知道目录的当前状态是什么时,这将特别有用。例如给定目录(相对于PWD进行测试)
shell> tree etc/filebeat/modules.d
etc/filebeat/modules.d
└── module99.yml
下面的剧本
shell> cat playbook.yml
- name: Configure filebeat modules
hosts: localhost
vars:
fb_modules_path: etc/filebeat/modules.d
fb_modules_d:
- module1.yml
- module2.yml
- module3.yml
tasks:
- name: Create modules
template:
src: "modules.d/{{ item }}"
dest: "{{ fb_modules_path }}/{{ item }}"
mode: '0644'
loop: "{{ fb_modules_d }}"
notify: restart_filebeat
- name: Remove modules
file:
dest: "{{ fb_modules_path }}/{{ item }}"
state: absent
loop: "{{ query('fileglob', fb_modules_path ~ '/*')|
map('basename')|
difference(fb_modules_d) }}"
notify: restart_filebeat
handlers:
- name: Restart filebeat service
listen: restart_filebeat
# systemd:
# name: filebeat
# state: restarted
debug:
msg: Restart filebeat
从列表中创建文件并删除其他文件
TASK [Create modules] ***************************************************
changed: [localhost] => (item=module1.yml)
changed: [localhost] => (item=module2.yml)
changed: [localhost] => (item=module3.yml)
TASK [Remove modules] ***************************************************
changed: [localhost] => (item=module99.yml)
RUNNING HANDLER [Restart filebeat service] ******************************
ok: [localhost] =>
msg: Restart filebeat
shell> tree etc/filebeat/modules.d
etc/filebeat/modules.d
├── module1.yml
├── module2.yml
└── module3.yml
剧本是幂等的。