问题描述
在他的 sites.yml
文件中有两个 plays:
- name: First play
hosts: all
remote_user: root
roles:
- role1
- name: Second Play
hosts: all
remote_user: ansible
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
roles:
- role2
- role3
他的目标是先运行第一个 play,然后再运行第二个 play。他使用如下的命令运行 playbook:
ansible-playbook -i inventory.ini -l web sites.yml --ask-pass -c paramiko
然而,当他运行 playbook 时,它似乎会卡住,因为它首先运行第一个 play,然后尝试运行第二个 play,导致卡住。
解决方案
解决方案1:
在 Ansible 中,playbook 的执行顺序是按照定义的顺序逐个执行的,所以你无需担心 play 之间的顺序问题。如果你有一个 task 在第一个 play 中创建了 ansible 用户,并且第二个 play 需要使用这个用户来连接,只需要确保在第一个 play 中的 role1 中包含一个创建 ansible 用户的 task。这样,在第二个 play 中,你就可以正常使用 ansible 用户连接。
以下是示例的 Ansible 任务,用于在不同的系统中创建 ansible 用户,并将其添加到适当的组以获得 sudo 权限:
- name: Ensure Ansible user is present (RedHat)
user:
name: ansible
comment: "ansible user created by bootstrap playbook"
generate_ssh_key: yes
groups: wheel
tags:
- bootstrap
when: ansible_os_family=="RedHat"
- name: Ensure Ansible user is present (Debian)
user:
name: ansible
comment: "ansible user created by bootstrap playbook"
generate_ssh_key: yes
groups: sudo
tags:
- bootstrap
when: ansible_os_family=="Debian"
- name: update sudoers to ensure ansible user can sudo
lineinfile:
dest: /etc/sudoers
state: present
regexp: '^ansible'
line: 'ansible ALL=(ALL) NOPASSWD: ALL'
tags:
- bootstrap
解决方案2:
如果你仍然希望跳过特定的 play,可以在 play 的定义中使用 when
条件。请注意,when
条件可以在 task 或 role 级别使用,但无法在 play 级别使用。但你可以通过使用 include_role
来绕过这一限制,实现在不同 play 中的条件执行。
以下是一个示例,展示如何在具有特定条件的情况下仅执行特定 play 中的 role:
- name: "Redhat"
hosts: all
become: yes
tasks:
- name: ADD Roles
include_role:
name: "{{role}}"
apply:
ignore_errors: yes
with_items:
- role1
- role2
loop_control:
loop_var: role
when: ansible_os_family=="RedHat"
请注意,when
条件在这个示例中是在 task 级别使用的,用于确保只有在条件满足时才会执行相应的 role。
无论选择哪种方法,都可以确保 playbook 的执行顺序以及特定条件下的跳过行为。
注意:在进行任何更改之前,请始终确保备份您的配置和数据。
希望这些解决方案能够帮助你解决问题!