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 的属性。

我想我终于明白了这个问题。我保留了下面的原始答案,仍然可以跳过一个角色


这是我基本理解你想做的事情:

  1. 根据一组条件确定需要使用的主机
  2. 根据上面选择的主机,运行 一部剧或一部其他剧
  3. 终于无条件完成一些其他任务

这是一个非常基本但功能齐全的示例,可以满足您的要求。我将它简化为一组最小的任务,因此它适合一个问题。但是您可以使用完全相同的概念添加您的角色,并将您的实际任务注入 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: