속성 목록에 변수가 있는지 확인 가능

속성 목록에 변수가 있는지 확인 가능

내 네트워크에 호스트 컴퓨터의 세부 정보가 포함된 변수('hostlist'라고 함)가 있습니다. 이것을 사전이라고 부르는 것 같지만 용어는 잘 모르겠습니다. 변수는 group_vars/all의 파일에 정의되어 있으므로 다음과 같습니다. 모든 플레이북에서 사용할 수 있습니다(중요한지는 확실하지 않음).

ansible_hostname이 호스트 목록의 호스트 이름 목록에 없는 경우에만 실행하고 싶은 플레이가 있습니다. 호스트 목록의 호스트 이름은 변수의 속성 중 하나이지만 "속성"이 올바른 용어인지 확실하지 않습니다.

호스트 목록은 다음과 같이 정의됩니다.

hostlist:
  - { name: 'host1', ip_addr: '192.168.2.31', hostgrp: 'physical_workstation' }
  - { name: 'host2', ip_addr: '192.168.2.32', hostgrp: 'physical_workstation' }
  - { name: 'host3', ip_addr: '192.168.2.33', hostgrp: 'virtual_machine' }

이 작업을 수행하기 위해 내가 사용하는 플레이는 다음과 같습니다.

- name: Conditional test
  debug:
    msg: "ansible_hostname not found in hostlist."
  when: ansible_hostname not in hostlist.name

조건에 필요한 구문이 확실하지 않거나, 내가 원하는 것이 이런 방식으로 달성 가능한지 확실하지 않습니다.

답변1

아마도 더 우아한 방법이 있을 것입니다. 그러나 다음과 같은 방법이 제게는 효과적입니다.

재고 파일이 다음과 같은 경우

host1
host2
host3
host4

host4그런 다음 다음 콘텐츠가 포함된 플레이북은 호스트 목록 var에서 일치하지 않기 때문에 해당 플레이북에 대해서만 실행됩니다 .
$ cat test.yml

- hosts: all
  vars:
    hostlist:
      - { name: 'host1', ip_addr: '192.168.2.31', hostgrp: 'physical_workstation' }
      - { name: 'host2', ip_addr: '192.168.2.32', hostgrp: 'physical_workstation' }
      - { name: 'host3', ip_addr: '192.168.2.33', hostgrp: 'virtual_machine' }
  tasks:

    - name: Conditional test
      debug:
        msg: "ansible_hostname not found in hostlist."
      when: hostlist|selectattr("name", "equalto", ansible_hostname)|list|length == 0

다음과 같이 호출할 때:

ansible-playbook test.yml

이는 호스트4만이 작업 블록을 실행한다는 것을 의미합니다....

PLAY [all] *************************************************

TASK [Gathering Facts] *************************************
ok: [host1]
ok: [host2]
ok: [host3]
ok: [host4]

TASK [debug] ***********************************************
ok: [host4] => {
    "msg": "hostname not in hostlist name list"
}
skipping: [host1]
skipping: [host2]
skipping: [host3]

답변2

선택적으로 이 상태가 더 깨끗합니다.

    when: inventory_hostname not in hostlist|map(attribute="name")|list

인벤토리 별칭 목록과 비교하려면 inventory_hostname대신을 사용하세요 . ansible_hostname보다Inventory_hostname과 ansible_hostname의 차이점은 무엇입니까?.

답변3

대체 솔루션은 (질문에 대한 설명에서 제안한 대로) 다음과 같이 호스트 목록을 인벤토리로 리팩터링하는 것입니다.

[physical_workstation]
host1 ansible_host=192.168.2.31
host2 ansible_host=192.168.2.32

[virtual_machine]
host3 ansible_host=192.168.2.33

[all]
host4 ansible_host=192.168.2.34

그런 다음 다른 그룹에 속하지 않는 ungrouped호스트를 선택하는 특수 그룹을 사용하여 그룹에 속하지 않는 호스트에 대해 플레이를 실행하도록 플레이북을 단순화할 수 있습니다 .all

- hosts: ungrouped
  tasks:
    - name: only ungrouped
      debug:
        msg: "host not found in any other group."

또는 그룹의 특정 호스트에 대해 작업을 실행하십시오.

- hosts: physical_workstation:virtual_machine
  tasks:
    - name: only in specified groups
      debug:
        msg: |
          This will run on machines that are in groups:
          physical_workstation or virtual_machine

출력

PLAY [ungrouped] ***********************************************

TASK [only ungrouped] ******************************************
ok: [host4] => {
    "msg": "host not found in any other group."
}

PLAY [physical_workstation:virtual_machine] ********************

TASK [only in specified groups] ********************************
ok: [host1] => {
    "msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}
ok: [host2] => {
    "msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}
ok: [host3] => {
    "msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}

관련 정보