コマンドラインからの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と上書きhosts: webからserver.yml、この脚本を実行します[droplets]

server.yml直接編集せずに、1回限りの変更としてオーバーライドできますか?

ありがとう。

回答:


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
WHEN(つまり、どのような順序で)にansible解析変数変数を行いgroup_vars/all表示され解析される後にhosts:脚本のライン。ただし、変数in vars:および変数in vars_files:は、hosts:行の前に解析されますか?注意私はいない優先さについて尋ねます。
フェリペアルバレス2017年

2
-e代わりにも使用できます--extra-vars
名詞

詳細については他の回答をご覧ください
Anand Varkey Philips

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の命名には注意してください。私はこれを使用play_hostsしてこれをテストしていましたplay_hostsが、それが現在のプレイのすべてのホストの内部Ansible変数であることを忘れたため、予期した結果が得られませんでした。
ライアンフィッシャー

上記の答えのようにデフォルトを設定する必要があると思います。
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に非常に慣れていませんが、これは非常に効果的なソリューションであり、他のソリューションよりもはるかにコンパクトです。なぜ反対票が投じられたのですか?
アレッサンドロデンテラ2017年

16
これは危険です。limitプレイブックに影響を与えたホストのリストを忘れた場合、多くのダメージを与える可能性があります。
Alexander Shcheblikin 2017年

3
--extra-vars "variable_host=newtarget(s)"受け入れられているソリューションと同じように使用することは、危険でより複雑なソリューションであることがわかりました。ここでは、のweb代わりに適用できるデフォルトのホストを使用していますall。厳密なホストグループをデフォルトとして使用して間違いを回避し、--list-hostsフラグを使用して、影響を受けるホストを明確に理解することができます。
ジョナサンハメル2017年

3
extra-varsを使用したソリューションでは、空のグループ(または存在しないグループ)をデフォルト値として指定できます。したがって、コマンドラインを介して変数を指定し忘れても、何も悪いことは起こりません。Playbookがホストのデフォルト値として空のグループを使用できなかったため、「-limit」オプションを使用したソリューションはより危険です。オプション「--llmit」はホスト値に適用されるため、空のグループに適用され、空の結果が提供されます。したがって、デフォルト値として「すべて」またはその他の空でないホストを使用する必要があります。そしていつか「--limit」引数を提供するのを忘れ、プレイブックがすべてのホストに適用されます。
グレゴリーペトホフ2018年

4
これを@TmTronの回答と組み合わせて、呼び出し元が提供できなかったケースをキャッチする必要があり--limitます(そうしないと、すべての可能なホストに影響しますが、これは希望する動作ではない可能性があります)
ncoghlan

14

単純なfailタスクを使用して、ユーザーにAnsible limitオプションを指定するように強制します。これにより、デフォルト/事故ですべてのホスト上で実行されなくなります。

私が見つけた最も簡単な方法はこれです:

---
- 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

オプションドキュメントの制限

1つ以上のホストに制限これは、ホストグループに対してプレイブックを実行したいが、そのグループの1つ以上のメンバーに対してのみ必要な場合に必要です。

1つのホストに制限

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

それを実行するには、2つの演劇を備えたプレイブックが必要です。

  • 最初のプレイはlocalhostで実行され、インメモリインベントリの既知のグループに(指定された変数から)ホストを追加します
  • 2番目のプレイはこの既知のグループで実行されます

実際の例(それをコピーして、前のコマンドで実行します):

- 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

私はデフォルトでホストなしに変更し、それを確認するチェックをしました。このようにして、ユーザーまたはcronは単一のホストまたはグループなどを提供する必要があります。@ wallydragからのコメントのロジックが好きです。のempty_groupインベントリにはホストが含まれていません。

-ホスト:「{{variable_host | default( 'empty_group')}}」

次に、チェックインタスクを追加します。

   タスク:
   -名前:必要なvariable_hostパラメータがない場合はスクリプトを失敗
     不合格:
       msg: "--extra-vars = 'variable_host ='を追加する必要があります"
     とき:(variable_host is not defined)または(variable_host == "")

5

ちょうどこのグーグルの解決策に出くわしました。実際、Ansible 2.5には1つあります。次の--inventoryように、インベントリファイルをで指定できます。ansible --inventory configs/hosts --list-hosts all


私はこれが私たちの主の年2019で最も正しい答えだと思います-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY specify inventory host path or comma separated host list. --inventory-file is deprecated
。Ansible2.8.4

3

ホストに関連付けられているタスクを別のホストで実行する場合は、delegate_toを試してください。

あなたの場合、あなたはあなたのローカルホスト(アンシブルマスター)に委任し、ansible-playbookコマンドを呼び出す必要があります


2

私はansible 2.5(正確には2.5.3)を使用しており、hostsパラメータが実行される前に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.