Ansible Playbook:如何 运行 根据 when 条件播放?
Ansible Playbook: How to run Play based on when condition?
我有一本包含多个剧本的剧本。这是它的样子:
- name: Play A
hosts: localhost
roles:
- do task to get either B or C
- name: Play B
hosts: Host B
roles:
- do necessary task
- name: Play C
hosts: Host C
roles:
- do necessary task
- name: Play D
host: localhost
roles:
- create_logs
每当剧本被触发时,它将首先运行第一个剧本获得B或C结果。
结果是判断主机属性运行播放如IP地址和主机OS
之后,根据结果,例如如果结果是B,我将运行播放B并跳过播放C。
否则如果结果是 C,我将跳过播放 B 和 运行 播放 C。
D 局将运行 作为最后一局,无论之前的局数如何。
我该怎么做?我试过使用 'when' 条件,但它说它不是 Play 的属性。
我想我终于明白了这个问题。我保留了下面的原始答案,仍然可以跳过一个角色
这是我基本理解你想做的事情:
- 根据一组条件确定需要使用的主机
- 根据上面选择的主机,运行 一部剧或一部其他剧
- 终于无条件完成一些其他任务
这是一个非常基本但功能齐全的示例,可以满足您的要求。我将它简化为一组最小的任务,因此它适合一个问题。但是您可以使用完全相同的概念添加您的角色,并将您的实际任务注入 select 您的目标。
剧本中的关键是使用add_host
module将所需组中所需的主机推送到内存清单。对于此示例,任何主机都将使用 local
连接,以便它伪装主机但仍使用本地主机连接到 运行。请注意,您可以在多个组中添加多个主机。
我还添加了一个基本检查,以确保我们为这个假主机传递的值 selection 在一组预期值内。默认情况下,剧本使用主机 B
但您可以通过在命令行上传递 -e host_we_need=C
来更改它。
说够了:举个例子!为了避免一些警告,让我们创建一个虚拟 inventory.yml
,其中包含我们需要但为空的两个组:
---
group_B:
group_C:
然后剧本:
---
- name: Determine the hosts we need
hosts: localhost
gather_facts: false
tasks:
- name: dummy task to fake you choice
command: "echo {{ host_we_need | default('B') }}"
register: host_choice
- name: check condition to go on
vars:
allowed_hosts:
- B
- C
assert:
that:
- host_choice.stdout in allowed_hosts
fail_msg:
- "Found host value is: {{ host_choice.stdout }}"
- "It should be one of: {{ allowed_hosts | join(', ') }}"
- name: add the needed host to in-memory inventory
add_host:
name: "{{ host_choice.stdout }}"
groups:
- "group_{{ host_choice.stdout }}"
ansible_connection: local # This is for a fake host for test only.
- name: play tasks for group_B
hosts: group_B
gather_facts: false
tasks:
- debug:
msg: This a task for group_B
- name: play tasks for group_C
hosts: group_C
gather_facts: false
tasks:
- debug:
msg: This is a task for group_C
- name: whatever leftover tasks on localhost
hosts: localhost
gather_facts: false
tasks:
- debug:
msg: leftover localhost tasks
给出(每种情况的示例 运行)
$ ansible-playbook -i add inventory.yml playbook.yml
PLAY [Determine the hosts we need] **********************************
TASK [dummy task to fake you choice] ********************************
changed: [localhost]
TASK [check condition to go on] *************************************
ok: [localhost]
TASK [add the needed host to in-memory inventory] *******************
changed: [localhost]
PLAY [play tasks for group_B] ***************************************
TASK [debug] ********************************************************
ok: [B] => {
"msg": "This a task for group_B"
}
PLAY [play tasks for group_C] ***************************************
skipping: no hosts matched
PLAY [whatever leftover tasks on localhost] *************************
TASK [debug] ********************************************************
ok: [localhost] => {
"msg": "leftover localhost tasks"
}
PLAY RECAP **********************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook -i inventory.yml playbook.yml -e host_we_need=C
PLAY [Determine the hosts we need] **********************************
TASK [dummy task to fake you choice] ********************************
changed: [localhost]
TASK [check condition to go on] *************************************
ok: [localhost]
TASK [add the needed host to in-memory inventory] *******************
changed: [localhost]
PLAY [play tasks for group_B] ***************************************
skipping: no hosts matched
PLAY [play tasks for group_C] ***************************************
TASK [debug] ********************************************************
ok: [C] => {
"msg": "This is a task for group_C"
}
PLAY [whatever leftover tasks on localhost] *************************
TASK [debug] ********************************************************
ok: [localhost] => {
"msg": "leftover localhost tasks"
}
PLAY RECAP **********************************************************
C : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(原始答案不完全符合要求)
您可以将 when
条件添加到您的角色中。
- name: Play B
hosts: Host B
roles:
- role: my_b_role
when: my_condition | bool
缺点是你需要在游戏中的任何角色或任务中添加条件。
您可以将剧本拆分成不同的剧本文件,在剧本 A 中添加一个任务,使用 include
模块有条件地包含剧本 B 或剧本 C。然后添加“include
剧本 D " 任务在“include
播放 B/C” 任务之后。
我没有尝试过,但你可以使用 set_fact 模块将主机设置为第一个播放/角色。所以你可以在后面的剧本中使用这个变量来分配主机。
或者改用动态组:
https://docs.ansible.com/ansible/latest/modules/group_by_module.html
我找到了其他方法。 Host B 和 Host C 的区别仅在于 IP 地址和 OS 类型。
因此,当剧本是 运行 时,我正在编辑 inventory/hosts 文件和 refresh_inventory 剧本完成必要的任务,然后在完成最后一个任务之前,我编辑回inventory/hosts 文件设置为我设置的默认值。
父剧本:
- name: Play A
hosts: localhost
roles:
- do task to get either B or C
- edit/replace ip address & host type for the targeted hosts in inventory/hosts file with using when condition
- refresh_inventory
- name: Play B_C
hosts: switches_host
roles:
- do necessary task
- name: Play D
host: localhost
roles:
- create_logs
- - edit/replace back to initial value
库存:
switches_host:
ansible_host: s.s.s.s
ansible_user: user
ansible_ssh_pass: pswd
ansible_network_os: xo.sx
1 - 您可以添加一个具有分配给 ansible_host 参数的空主机的播放。
在清单中,您有一个名为 xyz 的主机 ansible_host: null
2 - 你可以为每个任务添加一个条件,所以如果你发送一个值,条件应该为真,否则,它将使用空值,在这种情况下,条件为假,任务将被跳过.
示例:
---
- name: NTU CONFIGURATION
hosts: NTU
vars:
ansible_host: "{{ NTU_IP }}"
connection: local
gather_facts: no
tasks:
- name: TASK 1 CREAT VLAN 1000 CONFIGURATION
ios_config:
lines:
- name cust_inet
parents:
- vlan 1000
when:
- NTU == true
- name: another play
hosts: CPE
vars:
ansible_host: "{{ IP_MGMT }}"
connection: local
gather_facts: no
tasks:
我有一本包含多个剧本的剧本。这是它的样子:
- name: Play A
hosts: localhost
roles:
- do task to get either B or C
- name: Play B
hosts: Host B
roles:
- do necessary task
- name: Play C
hosts: Host C
roles:
- do necessary task
- name: Play D
host: localhost
roles:
- create_logs
每当剧本被触发时,它将首先运行第一个剧本获得B或C结果。
结果是判断主机属性运行播放如IP地址和主机OS
之后,根据结果,例如如果结果是B,我将运行播放B并跳过播放C。
否则如果结果是 C,我将跳过播放 B 和 运行 播放 C。
D 局将运行 作为最后一局,无论之前的局数如何。
我该怎么做?我试过使用 'when' 条件,但它说它不是 Play 的属性。
我想我终于明白了这个问题。我保留了下面的原始答案,仍然可以跳过一个角色
这是我基本理解你想做的事情:
- 根据一组条件确定需要使用的主机
- 根据上面选择的主机,运行 一部剧或一部其他剧
- 终于无条件完成一些其他任务
这是一个非常基本但功能齐全的示例,可以满足您的要求。我将它简化为一组最小的任务,因此它适合一个问题。但是您可以使用完全相同的概念添加您的角色,并将您的实际任务注入 select 您的目标。
剧本中的关键是使用add_host
module将所需组中所需的主机推送到内存清单。对于此示例,任何主机都将使用 local
连接,以便它伪装主机但仍使用本地主机连接到 运行。请注意,您可以在多个组中添加多个主机。
我还添加了一个基本检查,以确保我们为这个假主机传递的值 selection 在一组预期值内。默认情况下,剧本使用主机 B
但您可以通过在命令行上传递 -e host_we_need=C
来更改它。
说够了:举个例子!为了避免一些警告,让我们创建一个虚拟 inventory.yml
,其中包含我们需要但为空的两个组:
---
group_B:
group_C:
然后剧本:
---
- name: Determine the hosts we need
hosts: localhost
gather_facts: false
tasks:
- name: dummy task to fake you choice
command: "echo {{ host_we_need | default('B') }}"
register: host_choice
- name: check condition to go on
vars:
allowed_hosts:
- B
- C
assert:
that:
- host_choice.stdout in allowed_hosts
fail_msg:
- "Found host value is: {{ host_choice.stdout }}"
- "It should be one of: {{ allowed_hosts | join(', ') }}"
- name: add the needed host to in-memory inventory
add_host:
name: "{{ host_choice.stdout }}"
groups:
- "group_{{ host_choice.stdout }}"
ansible_connection: local # This is for a fake host for test only.
- name: play tasks for group_B
hosts: group_B
gather_facts: false
tasks:
- debug:
msg: This a task for group_B
- name: play tasks for group_C
hosts: group_C
gather_facts: false
tasks:
- debug:
msg: This is a task for group_C
- name: whatever leftover tasks on localhost
hosts: localhost
gather_facts: false
tasks:
- debug:
msg: leftover localhost tasks
给出(每种情况的示例 运行)
$ ansible-playbook -i add inventory.yml playbook.yml
PLAY [Determine the hosts we need] **********************************
TASK [dummy task to fake you choice] ********************************
changed: [localhost]
TASK [check condition to go on] *************************************
ok: [localhost]
TASK [add the needed host to in-memory inventory] *******************
changed: [localhost]
PLAY [play tasks for group_B] ***************************************
TASK [debug] ********************************************************
ok: [B] => {
"msg": "This a task for group_B"
}
PLAY [play tasks for group_C] ***************************************
skipping: no hosts matched
PLAY [whatever leftover tasks on localhost] *************************
TASK [debug] ********************************************************
ok: [localhost] => {
"msg": "leftover localhost tasks"
}
PLAY RECAP **********************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook -i inventory.yml playbook.yml -e host_we_need=C
PLAY [Determine the hosts we need] **********************************
TASK [dummy task to fake you choice] ********************************
changed: [localhost]
TASK [check condition to go on] *************************************
ok: [localhost]
TASK [add the needed host to in-memory inventory] *******************
changed: [localhost]
PLAY [play tasks for group_B] ***************************************
skipping: no hosts matched
PLAY [play tasks for group_C] ***************************************
TASK [debug] ********************************************************
ok: [C] => {
"msg": "This is a task for group_C"
}
PLAY [whatever leftover tasks on localhost] *************************
TASK [debug] ********************************************************
ok: [localhost] => {
"msg": "leftover localhost tasks"
}
PLAY RECAP **********************************************************
C : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(原始答案不完全符合要求)
您可以将 when
条件添加到您的角色中。
- name: Play B
hosts: Host B
roles:
- role: my_b_role
when: my_condition | bool
缺点是你需要在游戏中的任何角色或任务中添加条件。
您可以将剧本拆分成不同的剧本文件,在剧本 A 中添加一个任务,使用 include
模块有条件地包含剧本 B 或剧本 C。然后添加“include
剧本 D " 任务在“include
播放 B/C” 任务之后。
我没有尝试过,但你可以使用 set_fact 模块将主机设置为第一个播放/角色。所以你可以在后面的剧本中使用这个变量来分配主机。
或者改用动态组: https://docs.ansible.com/ansible/latest/modules/group_by_module.html
我找到了其他方法。 Host B 和 Host C 的区别仅在于 IP 地址和 OS 类型。
因此,当剧本是 运行 时,我正在编辑 inventory/hosts 文件和 refresh_inventory 剧本完成必要的任务,然后在完成最后一个任务之前,我编辑回inventory/hosts 文件设置为我设置的默认值。
父剧本:
- name: Play A
hosts: localhost
roles:
- do task to get either B or C
- edit/replace ip address & host type for the targeted hosts in inventory/hosts file with using when condition
- refresh_inventory
- name: Play B_C
hosts: switches_host
roles:
- do necessary task
- name: Play D
host: localhost
roles:
- create_logs
- - edit/replace back to initial value
库存:
switches_host:
ansible_host: s.s.s.s
ansible_user: user
ansible_ssh_pass: pswd
ansible_network_os: xo.sx
1 - 您可以添加一个具有分配给 ansible_host 参数的空主机的播放。 在清单中,您有一个名为 xyz 的主机 ansible_host: null
2 - 你可以为每个任务添加一个条件,所以如果你发送一个值,条件应该为真,否则,它将使用空值,在这种情况下,条件为假,任务将被跳过.
示例:
---
- name: NTU CONFIGURATION
hosts: NTU
vars:
ansible_host: "{{ NTU_IP }}"
connection: local
gather_facts: no
tasks:
- name: TASK 1 CREAT VLAN 1000 CONFIGURATION
ios_config:
lines:
- name cust_inet
parents:
- vlan 1000
when:
- NTU == true
- name: another play
hosts: CPE
vars:
ansible_host: "{{ IP_MGMT }}"
connection: local
gather_facts: no
tasks: