我有一本有多个角色,主持人和小组的剧本。我正在尝试开发回滚功能,该功能可以在所有主机上运行。我目前的障碍是我看不到将角色,阻止或任务集委派给主机组的方法
这是我现在所拥有的剧本文件(简化版)
- hosts: all
any_errors_fatal: true
vars_prompt:
- name: "remote_user_p"
prompt: "Remote user running the playbook"
default: "root"
private: no
- name: "service_user_p"
prompt: "Specify user to run non-root tasks"
default: "user"
private: no
tasks:
- set_fact:
playbook_type: "upgrade"
- import_role:
name: 0_pre_check
run_once: true
remote_user: "{{ remote_user_p }}"
become_user: "{{ service_user_p }}"
become_method: su
become: yes
- block:
- import_role:
name: 1_os
- import_role:
name: 2_mysql
when: inventory_hostname in groups['mysql'] | default("")
- import_role:
name: 3_web
when: inventory_hostname in groups['web'] | default("")
...
rescue:
- block:
- name: run rollback
import_tasks: ../common/roles/5_rollback/tasks/rollback.yml
remote_user: "{{ remote_user }}"
become_user: "{{ service_user }}"
become_method: su
become: yes
这是rollback.yml中的一些示例代码:
- block:
- name: rollback symlinks to config dir
file:
src: "{{ current_config_path }}"
dest: "{{ install_dir }}/static/cfg"
owner: "{{ service_user }}"
group: "{{ service_user_primary_group }}"
state: link
when: current_new_configs | default("N") == "Y"
delegate_to: "{{ item }}"
with_items:
- "{{ ansible_play_hosts }}"
- block:
- name: return config files
shell: test -f '{{ item.1.current_ver_file_path }}' && cp -p {{ item.1.current_ver_file_path }} {{ item.1.old_config_location }}
args:
warn: false
register: return_config_files
failed_when: return_config_files.rc >= 2
when:
- roolback_moved_cfg | default('N') == "Y"
- inventory_hostname in groups[item.0.group]
- item.1.old_config_location != ""
- item.1.current_ver_file_path != ""
with_subelements:
- "{{ config_files }}"
- files
become_user: root
become_method: sudo
become: yes
- name: systemctl daemon-reload
shell: systemctl daemon-reload
failed_when: false
when: root_rights == "Y"
args:
warn: false
delegate_to: "{{ item }}"
with_items:
- "{{ ansible_play_hosts }}"
when: root_rights == "Y"
become_user: root
become_method: sudo
become: yes
- fail:
msg: "Upgrade failed. Symbolic links were set to the previous version. Fix the issues and try again. If you wish to cancel the upgrade, restore the database backup manually."
如您所见,现在我通过引入
使用la脚的解决方法 delegate_to: "{{ item }}"
with_items:
- "{{ ansible_play_hosts }}"
在每个任务之后。
这里有两个问题:
1.在任务return config files
之后,我不能使用相同的方法,因为它已经使用了一个循环
2.这通常是la脚的代码重复,我讨厌它
为什么我完全需要它:例如,如果剧本执行在mysql
角色的某个地方失败,则rescue
块将仅在该mysql
角色的主机上执行(并且顺便说一句,在运行救援块时,将继续执行下一个角色的任务-尽管执行了所有工作,但任务量相同),而我希望它运行在所有主机上。
答案 0 :(得分:0)
我终于可以用一个丑陋的骇客解决这个问题。用过的戏剧不只是角色-现在有10多种戏剧。不要判断我,我花了很多心思来使它变得不错):
示例游戏,然后进行检查-彼此相同。
- hosts: mysql
any_errors_fatal: true
tasks:
- block:
- import_role:
name: 2_mysql
when: not rollback | default(false)
rescue:
- block:
- name: set fact for rollback
set_fact:
rollback: "yes"
delegate_to: "{{ item }}"
delegate_facts: true
with_items: "{{ groups['all'] }}"
- hosts: all
any_errors_fatal: true
tasks:
- name: run rollback
import_tasks: ../common/roles/5_rollback/tasks/rollback.yml
when: rollback | default(false)
答案 1 :(得分:0)
include_role
不接受delegate_to
实际上是。
使用ansible-core 2.8:
- name: "call my/role with host '{{ansible_hostname}}' for hosts in '{{ansible_play_hosts}}'"
include_role:
name: my/role
apply:
delegate_to: "{{current_host}}"
with_items: "{{ansible_play_hosts}}"
loop_control:
loop_var: current_host
对于ansible-core 2.5到2.7,请参见2.5: delegate_to, include_role with loops中提到的George Shuklin中的“ ansible/ansible
issue 35398”
- name: "call my/role with host '{{ansible_hostname}}' for items in '{{ansible_play_hosts}}'"
include_tasks: loop.yml
with_items: "{{ansible_play_hosts}}"
loop_control:
loop_var: current_host
通过loop.yml
在其自己的文件中执行其他任务:
- name: "Import my/role for '{{current_host}}'"
import_role: name=my/role
delegate_to: "{{current_host}}"
因此,在两个文件(具有ansible-core 2.7)或一个文件(2.8)中,您可以担任all角色,并且其任务在委托的服务器上运行。