명령 줄에서 Ansible 플레이 북의 호스트 변수 재정의


110

다음은 내가 사용중인 플레이 북의 일부입니다 ( server.yml).

- name: Determine Remote User
  hosts: web
  gather_facts: false
  roles:
    - { role: remote-user, tags: [remote-user, always] }

내 호스트 파일에는 다른 서버 그룹이 있습니다. 예 :

[web]
x.x.x.x

[droplets]
x.x.x.x

지금은 실행할 ansible-playbook -i hosts/<env> server.yml및 오버라이드 (override) hosts: web에서 server.yml이 작전을 실행합니다 [droplets].

server.yml직접 편집하지 않고 일회성으로 재정의 할 수 있습니까 ?

감사.

답변:


128

Ansible이이 기능을 제공한다고 생각하지 않습니다. 수행 할 수있는 작업은 다음과 같습니다.

hosts: "{{ variable_host | default('web') }}"

variable_host명령 줄 또는 vars 파일에서 전달할 수 있습니다 . 예 :

ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"

3
약간의 수정이 필요합니다. 그것은hosts: "{{ variable_host | default('web')}}"
SPM

16
다음은이 솔루션을 검색하는 ansible 초보자를위한 답변을 완성 할 것이라고 생각하는 메모입니다. 예 :ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"
Frobbit

1
언제 (즉, 어떤 순서)에 ansible 구문 분석 변수 변수를 수행 group_vars/all나타납니다 구문 분석 hosts: 플레이 북의 라인. 그러나의 변수 vars:및 변수 vars_files:hosts:줄 전에 구문 분석 됩니까? 참고 내가 하지 우선 순위에 대한 질문.
Felipe Alvarez

2
-e대신 사용할 수도 있습니다 --extra-vars.
명사

자세한 내용은 다른 답변 봐
아난드 Varkey 필립스에게

63

솔루션을 찾고 계신 분들께.
플레이 북

- hosts: '{{ host }}'
  tasks:
  - debug: msg="Host is {{ ansible_fqdn }}"

목록

[web]
x.x.x.x

[droplets]
x.x.x.x

명령 : ansible-playbook deplyment.yml -i hosts --extra-vars "host=droplets" 따라서 extra-vars에 그룹 이름을 지정할 수 있습니다.


2
var 이름 지정에주의하십시오. 나는 현재 플레이의 모든 호스트에 대한 내부 Ansible 변수를 play_hosts잊었 기 때문에 이것을 사용하여 테스트 했지만 예상 결과를 얻지 play_hosts못했습니다.
Ryan Fisher

위의 대답과 같이 기본값을 설정해야한다고 생각합니다.
kakaz

19

조금 늦었지만 --limit or -l 명령을 하여 패턴을보다 구체적인 호스트로 제한 합니다. (버전 2.3.2.0)

당신은 가질 수 있습니다 - hosts: all (or group) tasks: - some_task

그런 다음 플래그를 ansible-playbook playbook.yml -l some_more_strict_host_or_pattern 사용 --list-hosts하여이 구성이 적용되는 호스트를 확인합니다.


3
저는 ansible을 처음 접했지만 이것이 다른 것보다 훨씬 간결한 매우 효과적인 솔루션이라고 생각합니다. 왜 반대 투표를 했습니까?
Alessandro Dentella

16
이것은 위험합니다. limit영향을받은 호스트 목록을 잊어 버리면 플레이 북이 많은 피해를 입힐 수 있습니다.
Alexander Shcheblikin 2017 년

3
--extra-vars "variable_host=newtarget(s)"받아 들여진 솔루션을 그대로 사용하는 것은 위험하고 더 복잡한 솔루션 이라는 것을 알게 되었습니다. web대신 여기에 적용될 수 있는 기본 호스트를 사용합니다 all. 엄격한 호스트 그룹을 기본값으로 사용하여 실수를 방지하고 --list-hosts플래그를 사용하여 영향을받는 호스트를 명확하게 이해할 수 있습니다.
Jonathan Hamel

3
extra-vars가있는 솔루션을 사용하면 빈 그룹 (또는 존재하지 않는)을 기본값으로 지정할 수 있습니다. 따라서 명령 줄을 통해 변수를 제공하는 것을 잊은 경우 나쁜 일이 발생하지 않습니다. "--limit"옵션이있는 솔루션은 플레이 북이 호스트의 기본값으로 빈 그룹을 사용할 수 없기 때문에 더 위험합니다. 옵션 "--llmit"은 호스트 값에 적용되므로 빈 그룹에 적용되고 빈 결과를 제공합니다. 따라서 "all"또는 비어 있지 않은 다른 호스트를 기본값으로 사용해야합니다. 그리고 언젠가는 "--limit"인수를 제공하는 것을 잊고 플레이 북이 모든 호스트에 적용됩니다.
Gregory Petukhov

4
호출자가 제공하지 못한 곳은 TmTron의 대답은 사건을 잡으려고 @와 결합되어야한다 --limit(그렇지 않으면 당신이 원하는 행동을하지 않을 수있는 모든 호스트에 영향을줍니다)
ncoghlan

14

간단한 실패 작업을 사용하여 사용자가 Ansible 제한 옵션 을 지정하도록 강제 하므로 모든 호스트에서 기본 / 사고로 실행되지 않습니다.

내가 찾은 가장 쉬운 방법은 다음과 같습니다.

---
- name: Force limit
  # 'all' is okay here, because the fail task will force the user to specify a limit on the command line, using -l or --limit
  hosts: 'all'

  tasks:
  - name: checking limit arg
    fail:
      msg: "you must use -l or --limit - when you really want to use all hosts, use -l 'all'"
    when: ansible_limit is not defined
    run_once: true

이제 플레이 북을 실행할 때 -l(= --limit옵션)을 사용해야합니다.

ansible-playbook playbook.yml -l www.example.com

제한 옵션 문서 :

하나 이상의 호스트로 제한 호스트 그룹에 대해 플레이 북을 실행하려는 경우 필요하지만 해당 그룹의 하나 이상의 구성원에 대해서만 필요합니다.

하나의 호스트로 제한

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1"

여러 호스트로 제한

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1,host2"

제한이 무효화되었습니다.
참고 : bash 보간을 방지하려면 작은 따옴표를 사용해야합니다.

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'all:!host1'

호스트 그룹으로 제한

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'group1'


7

인벤토리가 필요하지 않고 다음과 같은 간단한 명령으로 작동하는 다른 접근 방식을 사용하고 있습니다.

ansible-playbook site.yml -e working_host=myhost

이를 수행하려면 두 가지 연극이있는 플레이 북이 필요합니다.

  • 첫 번째 재생은 localhost에서 실행되고 메모리 인벤토리의 알려진 그룹에 호스트 (주어진 변수에서)를 추가합니다.
  • 이 알려진 그룹에서 두 번째 플레이가 실행됩니다.

작업 예제 (복사하고 이전 명령으로 실행) :

- hosts: localhost
  connection: local
  tasks:
  - add_host:
      name: "{{ working_host }}"
      groups: working_group
    changed_when: false

- hosts: working_group
  gather_facts: false
  tasks:
  - debug:
      msg: "I'm on {{ ansible_host }}"

ansible 2.4.3 및 2.3.3을 사용하고 있습니다.


7

나는 기본적으로 호스트 없음으로 변경했고 그것을 잡기 위해 수표를 받았습니다. 이렇게하면 사용자 나 크론이 단일 호스트 또는 그룹 등을 제공하도록 강요받습니다. @wallydrag의 의견에 나오는 논리가 마음에 듭니다. 은 empty_group재고에는 호스트가 포함되어 있지 않습니다.

-호스트 : "{{variable_host | default ( 'empty_group')}}"

그런 다음 체크인 작업을 추가합니다.

   작업 :
   -이름 : 필요한 variable_host 매개 변수가 누락 된 경우 실패 스크립트
     불합격:
       msg : "--extra-vars = 'variable_host ='를 추가해야합니다."
     언제 : (variable_host가 정의되지 않음) 또는 (variable_host == "")

5

해결책을 찾기 위해이 인터넷 검색을 발견했습니다. 실제로 Ansible 2.5에는 하나가 있습니다. 다음과 --inventory같이를 사용하여 인벤토리 파일을 지정할 수 있습니다 .ansible --inventory configs/hosts --list-hosts all


:이 Ansible 2.8.4의 -h에서 우리 주님 2019 년도에 가장 정답이라고 생각-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY specify inventory host path or comma separated host list. --inventory-file is deprecated
pyansharp

3

호스트와 연결되어 있지만 다른 호스트에서 작업을 실행하려면 delegate_to 를 시도해야합니다 .

귀하의 경우에는 로컬 호스트 (ansible 마스터)에 위임하고 ansible-playbook 명령을


2

ansible 2.5 (정확히 2.5.3)를 사용하고 있으며 호스트 매개 변수가 실행되기 전에 vars 파일 이로드 된 것 같습니다 . 따라서 vars.yml 파일에 호스트를 설정하고hosts: {{ host_var }} 플레이 북에 수 있습니다.

예를 들어, 내 playbook.yml에서 :

---
- hosts: "{{ host_name }}"
  become: yes
  vars_files:
    - vars/project.yml
  tasks:
    ... 

그리고 vars / project.yml 내부 :

---

# general
host_name: your-fancy-host-name

0

다음은 --limit옵션을 통해 호스트를 안전하게 지정하기 위해 찾은 멋진 솔루션 입니다. 이 예에서는 --limit옵션을 통해 지정된 호스트없이 플레이 북이 실행 된 경우 플레이가 종료됩니다 .

이것은 Ansible 버전 2.7.10에서 테스트되었습니다.

---
- name: Playbook will fail if hosts not specified via --limit option.
  # Hosts must be set via limit. 
  hosts: "{{ play_hosts }}"
  connection: local
  gather_facts: false
  tasks:
  - set_fact:
      inventory_hosts: []
  - set_fact:
      inventory_hosts: "{{inventory_hosts + [item]}}"
    with_items: "{{hostvars.keys()|list}}"

  - meta: end_play
    when: "(play_hosts|length) == (inventory_hosts|length)"

  - debug:
      msg: "About to execute tasks/roles for {{inventory_hostname}}"

0

다른 해결책은 Ansible의 현재 실행을위한 CLI 옵션 ansible_limit의 내용 인 특수 변수를 사용하는 것 --limit입니다.

- hosts: "{{ ansible_limit | default(omit) }}"

경우 --limit옵션은 다음 Ansible 문제 경고를 생략하지만, 일치하는 어떤 호스트 때문에 아무것도하지 않습니다.

[WARNING]: Could not match supplied host pattern, ignoring: None

PLAY ****************************************************************
skipping: no hosts matched
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.