この質問 のフォローアップです。
一連のEC2インスタンスをプロビジョニングする劇があります。必要に応じて、hosts
値はlocalhost
(実行時にホストがないため)であり、playはec2hosts
と呼ばれる新しいホストリストを作成し、ホストIPを生成してホスト名マップこれは、情報が利用可能になる最初で唯一の時間であるため、set_fact
を使用して保存します。このホストリストは、その後のフォローアップの対象となります。問題は、2回目のプレイでプロビジョニングプレイ中に作成されたhostname_map
辞書を使用する必要があることです。これを行う方法がわかりません。
これが最初の遊びです:
- hosts: localhost
connection: local
gather_facts: False
tasks:
- name: Provision a set of instances
ec2:
key_name: marcus
instance_type: t2.micro
image: "{{ AMI_id }}"
wait: true
exact_count: "{{ server_count }}"
count_tag:
Tutorial: "{{ tutorial_name }}"
instance_tags:
Tutorial: "{{ tutorial_name }}"
groups: ['SSH', 'Web']
register: ec2
- name: Add all instance public IPs to Host group
add_Host:
hostname: "{{ item.public_ip }}"
groups: ec2hosts
loop: "{{ ec2.instances }}"
- name: Build an IP to hostname map
set_fact:
hostname_map: "{{ hostname_map | combine({item.0.public_ip: (item.1 + '.' + tutorial_domain)}) }}"
loop: "{{ ec2.instances|Zip(hostnames)|list }}"
- name: Debug hostname_map
debug:
msg: "{{ hostname_map }}"
この最後に、hostname_map
には次のようなマップが含まれています。
{
"18.184.109.70": "Host1.example.com",
"18.196.135.59": "Host2.example.com"
}
変数スコープに関するansible docsを読むと、同じホストのセットに適用されていない限り、プレイで定義された変数はそのプレイ外では利用できないと述べています。この場合、それは不可能なので、グローバルスコープでvarを使用する必要があります。私が読んだことから、set_fact
が適切な方法です。そのため、/group_vars/all
に空の変数を作成し、その変数がすべての演劇にアクセスできるようにしました。
hostname_map: {}
次の演劇は(動的に作成したホストリストを使用して)新しく作成された各インスタンスに接続し、内部からホスト名を設定します。
- hosts: ec2hosts
gather_facts: yes
tasks:
- name: Debug hostname_map
debug:
msg: "{{ hostname_map }}"
- name: Set hostnames
hostname:
name: "{{ hostname_map[ansible_Host] }}"
ただし、hostname_map
が空であるため、これは失敗します
TASK [Debug hostname_map]
ok: [18.184.109.70] => {
"msg": {}
}
ok: [18.196.135.59] => {
"msg": {}
}
だから私はこのエラーを受け取ります:
致命的:[18.184.109.70]:失敗しました! => {"msg": "タスクに未定義の変数を持つオプションが含まれています。エラーは次のとおりです: 'dictオブジェクト'には属性u'18.184.109.70 'がありません
変数をグローバルに定義しない場合でも、奇妙なことに、同じデバッグ出力とエラーが表示されます。
私がすべて読んだ他の記事では、値をvars
に明示的に列挙する必要があると示唆していますが、データは動的で実行時まで不明であるため、これを行うことはできません。同様に、同じ理由でコマンドラインでextra_vars
を使用して提供することはできません。
2番目のプレイでこの変数を使用できるようにするにはどうすればよいですか?ローカルファイルを書き出してから読み込むといった、不格好な解決策は避けたいです。
また、これを完全に異なる方法で行うための提案も受け入れます。「これ」は、任意の数のEC2インスタンスを作成し、静的リストから取得したホスト名を割り当てることです。
set_fact
で設定した値は、異なるプレイ間で使用できます。 set_factは特定のホストに設定であることに注意してください。最初のプレイはlocalhostに対して実行されるため、事実はlocalhosts変数の一部です。したがって、次のプレイでは、このようなタスクでそれにアクセスできるはずです。
- debug:
var: hostvars['localhost']['hostmap']