在播放之間共享 ansible 變數
這是對這個問題的跟進。
我有一個配置一堆 EC2 實例的遊戲。必要時,該
hosts
值是localhost
(因為當它執行時沒有主機),並且該播放組裝了一個名為的新主機列表ec2hosts
,並生成主機 ip 到主機名映射*,因為這是第一次也是唯一一次提供該資訊*,並且使用set_fact
. 這個主機列表是後續遊戲的主題。問題是我需要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 文件,它說在劇本中定義的變數在該劇本之外不可用,除非它被應用於同一組主機。在這種情況下這是不可能的,所以我需要使用具有全域範圍的 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 object’沒有屬性u'18.184.109.70’
奇怪的是,即使我沒有全域定義變數,我也會得到相同的調試輸出和錯誤。
我讀過的其他文章都建議應該在 中明確列舉值
vars
,但我不能這樣做,因為數據是動態的,直到執行時才知道。同樣,出於同樣的原因,我無法extra_vars
在命令行上使用它。如何在第二次播放中使此變數可用?我想避免笨拙的解決方案,例如將本地文件寫出然後再將其讀回!
我也願意接受以完全不同的方式執行此操作的建議,其中“this”是:創建任意數量的 EC2 實例並為它們分配從靜態列表中獲取的主機名。
您設置的值
set_fact
將在不同的播放之間可用。請記住, set_fact 是為特定主機設置的。您的第一個遊戲是針對localhost執行的,因此事實是 localhosts 變數的一部分。因此,在接下來的遊戲中,您應該能夠通過這樣的任務訪問它。- debug: var: hostvars['localhost']['hostmap']
您可以使用虛擬主機,它將在add_host的幫助下儲存您想要共享的所有變數。然後只需使用hostvars訪問您的變數
- hosts: "18.184.109.70" user: ubuntu tasks: - name: set a variable set_fact: shared_variable: "Some value" - name: add variables to dummy host add_host: name: "variable_holder" shared_variable: "{{ shared_variable }}" - hosts: "18.196.135.59" user: ubuntu vars: shared_variable: "{{ hostvars['variable_holder']['shared_variable'] }}" tasks: - debug: msg: "{{ shared_variable }}"