Amazon-Ec2

在播放之間共享 ansible 變數

  • September 28, 2020

這是對這個問題的跟進。

我有一個配置一堆 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 }}"

引用自:https://serverfault.com/questions/962040