[ansible] Ansible Playbook을 단일 컴퓨터로 안전하게 제한합니까?

소규모 컴퓨터 그룹에서 간단한 사용자 관리 작업에 Ansible을 사용하고 있습니다. 현재 플레이 북을 설정했으며 hosts: all호스트 파일은 모든 컴퓨터가 나열된 단일 그룹입니다.

# file: hosts
[office]
imac-1.local
imac-2.local
imac-3.local

하나의 머신을 자주 타겟팅해야한다는 것을 알게되었습니다. 이 ansible-playbook명령은 다음과 같이 재생을 제한 할 수 있습니다.

ansible-playbook --limit imac-2.local user.yml

그러나 이는 잠재적으로 파괴적인 플레이 북에 있어서는 매우 약해 보입니다. limit깃발을 남기면 플레이 북이 어디에서나 실행됩니다. 이 도구는 가끔씩 만 사용되기 때문에 재생을 속이는 조치를 취할 가치가 있으므로 지금부터 몇 달 동안 우연히 핵무기를하지 않습니다.

플레이 북 실행을 단일 컴퓨터로 제한하는 가장 좋은 방법이 있습니까? 중요한 세부 사항이 빠진 경우 플레이 북은 무해해야합니다.



답변

플레이 북에 호스트 이름을 직접 입력 할 수 있으므로 플레이 북을 실행하면 hosts: imac-2.local정상적으로 작동합니다. 그러나 그것은 어색합니다.

더 나은 솔루션은 변수를 사용하여 플레이 북의 호스트를 정의한 다음 다음을 통해 특정 호스트 주소를 전달하는 것입니다 --extra-vars.

# file: user.yml  (playbook)
---
- hosts: '{{ target }}'
  user: ...

플레이 북 실행 :

ansible-playbook user.yml --extra-vars "target=imac-2.local"

만약 {{ target }}정의되지 않은 플레이 북은 아무 작업도 수행하지 않습니다. 필요한 경우 hosts 파일의 그룹도 전달할 수 있습니다. 전반적으로, 이것은 잠재적으로 파괴적인 플레이 북을 구성하는 훨씬 안전한 방법 인 것 같습니다.

단일 호스트를 대상으로하는 플레이 북 :

$ ansible-playbook user.yml --extra-vars "target=imac-2.local" --list-hosts

playbook: user.yml

  play #1 (imac-2.local): host count=1
    imac-2.local

호스트 그룹이있는 플레이 북 :

$ ansible-playbook user.yml --extra-vars "target=office" --list-hosts

playbook: user.yml

  play #1 (office): host count=3
    imac-1.local
    imac-2.local
    imac-3.local

호스트를 정의하는 것을 잊어 버리는 것이 안전합니다!

$ ansible-playbook user.yml --list-hosts

playbook: user.yml

  play #1 ({{target}}): host count=0


답변

또한 중간 인벤토리없이 명령 줄에서 단일 호스트 (또는 여러 호스트)를 지정할 수있는 귀여운 방법이 있습니다.

ansible-playbook -i "imac1-local," user.yml

끝에 쉼표 ( , )를 적어 둡니다 . 이것은 파일이 아니라 목록이라는 것을 나타냅니다.

실수로 실제 인벤토리 파일을 전달하면 보호되지 않으므로 특정 문제에 대한 좋은 해결책이 아닐 수 있습니다. 하지만 알아두면 유용한 트릭입니다!


답변

play_hosts 변수 를 검사하여 둘 이상의 호스트가 제공되면이 방법이 종료됩니다 . 실패 모듈은 단일 호스트 조건이 충족되지 않을 경우 종료하는 데 사용됩니다. 아래 예제는 두 개의 호스트 alice와 bob이있는 호스트 파일을 사용합니다.

user.yml (플레이 북)

---
- hosts: all
  tasks:
    - name: Check for single host
      fail: msg="Single host check failed."
      when: "{{ play_hosts|length }} != 1"
    - debug: msg='I got executed!'

호스트 필터없이 플레이 북 실행

$ ansible-playbook user.yml
PLAY [all] ****************************************************************
TASK: [Check for single host] *********************************************
failed: [alice] => {"failed": true}
msg: Single host check failed.
failed: [bob] => {"failed": true}
msg: Single host check failed.
FATAL: all hosts have already failed -- aborting

단일 호스트에서 플레이 북 실행

$ ansible-playbook user.yml --limit=alice

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

TASK: [Check for single host] *********************************************
skipping: [alice]

TASK: [debug msg='I got executed!'] ***************************************
ok: [alice] => {
    "msg": "I got executed!"
}


답변

IMHO가 더 편리한 방법입니다. 실제로 다음과 같은 덕분에 플레이 북을 적용하려는 컴퓨터를 대화 형으로 사용자에게 프롬프트 할 수 있습니다 vars_prompt.

---

- hosts: "{{ setupHosts }}"
  vars_prompt:
    - name: "setupHosts"
      prompt: "Which hosts would you like to setup?"
      private: no
  tasks:
    […]


답변

joemailer의 답변을 확장하려면 원격 컴퓨터의 하위 집합과 일치하는 패턴 일치 기능을 원할 경우 ansible 명령 원하지만 모든 컴퓨터에서 실수로 플레이 북을 실행하기가 매우 어려워지는 경우 내가 생각해 낸 것 :

다른 답변과 동일한 플레이 북 :

# file: user.yml  (playbook)
---
- hosts: '{{ target }}'
  user: ...

다음과 같은 호스트가 있습니다 :

imac-10.local
imac-11.local
imac-22.local

이제 모든 장치에서 명령을 실행하려면 대상 변수를 “all”로 명시해야합니다.

ansible-playbook user.yml --extra-vars "target=all"

특정 패턴으로 제한하기 위해 target=pattern_here

또는 다음 target=all과 같이 --limit인수를 그대로두고 추가 할 수 있습니다 .

--limit imac-1*

즉.
ansible-playbook user.yml --extra-vars "target=all" --limit imac-1* --list-hosts

결과 :

playbook: user.yml

  play #1 (office): host count=2
    imac-10.local
    imac-11.local


답변

나는 모든 답변이 얼마나 복잡한 지 이해하지 못합니다. 그 방법은 간단합니다.

ansible-playbook user.yml -i hosts/hosts --limit imac-2.local --check

check모드를 사용하면 변경하지 않고 드라 이런 모드로 실행할 수 있습니다.


답변

EC2 외부 인벤토리 스크립트를 사용하는 AWS 사용자는 인스턴스 ID별로 간단히 필터링 할 수 있습니다.

ansible-playbook sample-playbook.yml --limit i-c98d5a71 --list-hosts

이것은 인벤토리 스크립트 가 기본 그룹을 생성 하기 때문에 작동 합니다 .