2015-04-16 34 views
3

我真的很感謝從正確的寄存器中選擇數據的一些幫助。 以下代碼差不多工作... :)從Ansible寄存器中選擇特定的數據

我在這裏創建AWS VPC,我在'vpc'中註冊信息。 然後我參考vpc。

- name: Create VPC and Subnets 
    ec2_vpc: 
     state: present 
     cidr_block: '{{ ip-range}}' 
     resource_tags: { "Name": "{{ vpc_name }}" } 
     region: '{{ region }}' 
     subnets: 
     - cidr: '{{ pub-subneta }}' 
      az: '{{ region }}a' 
      resource_tags: { "Name": "Public Subnet 1" } 

     - cidr: '{{ pub-subnetb }}' 
      az: '{{ region }}b' 
      resource_tags: { "Name": "Public Subnet 2" } 

     - cidr: '{{ priv-subnet1 }}' 
      az: '{{ region }}a' 
      resource_tags: { "Name": "Private Subnet 1" } 

     - cidr: '{{ priv-subnet2 }}' 
      az: '{{ region }}b' 
      resource_tags: { "Name": "Private Subnet 2" } 
     internet_gateway: True 
    register: vpc 

這很好。它使用4個子網創建VPC。 那麼我想在我試圖specifiying子網如下做特定子網啓動NAT實例:

- name: Create NAT instance 
    ec2: 
    state: present 
    key_name: '{{ ssh_key_name }}' 
    instance_type: '{{ nat_instance_type }}' 
    image: '{{ nat_ami }}' 
    region: '{{ region }}' 
    wait: yes 
    instance_tags: 
     Name: "natsrv01" 
     Description: "NAT Server" 
    assign_public_ip: yes 
    source_dest_check: false 
    vpc_subnet_id: '{{ vpc.subnets[0].id }}' 

這是它的意圖不工作。 我假定寄存器將按照它定義/創建的順序包含信息,但事實並非如此。

使用調試我可以看到4個子網在寄存器中是隨機的順序。例如在一次嘗試中,「Public Subnet 2」被「vpc.subnets [0] .id」識別,而另一次嘗試「private Subnet 2」是列表中的第一個。

有人可以建議我怎麼能可靠地&反覆從寄存器中選擇「公共子網1」?

VPC寄存器的完整輸出:

ok: [localhost] => { 
"vpc": { 
    "changed": true, 
    "invocation": { 
     "module_args": "", 
     "module_name": "ec2_vpc" 
    }, 
    "subnets": [ 
     { 
      "az": "eu-west-1b", 
      "cidr": REDACTED, 
      "id": "subnet-REDACTED", 
      "resource_tags": { 
       "Name": "Private Subnet B" 
      } 
     }, 
     { 
      "az": "eu-west-1c", 
      "cidr": REDACTED, 
      "id": "subnet-REDACTED", 
      "resource_tags": { 
       "Name": "Private Subnet C" 
      } 
     }, 
     { 
      "az": "eu-west-1a", 
      "cidr": REDACTED, 
      "id": "subnet-REDACTED", 
      "resource_tags": { 
       "Name": "Public Subnet A" 
      } 
     }, 
     { 
      "az": "eu-west-1c", 
      "cidr": REDACTED, 
      "id": "subnet-REDACTED", 
      "resource_tags": { 
       "Name": "Public Subnet C" 
      } 
     }, 
     { 
      "az": "eu-west-1b", 
      "cidr": REDACTED, 
      "id": "subnet-REDACTED", 
      "resource_tags": { 
       "Name": "Public Subnet B" 
      } 
     }, 
     { 
      "az": "eu-west-1a", 
      "cidr": REDACTED, 
      "id": "subnet-REDACTED", 
      "resource_tags": { 
       "Name": "Private Subnet A" 
      } 
     } 
    ], 
    "vpc": { 
     "cidr_block": "REDACTED", 
     "dhcp_options_id": "dopt-53eb0f36", 
     "id": "vpc-REDACTED", 
     "region": "eu-west-1", 
     "state": "pending" 
    }, 
    "vpc_id": "vpc-REDACTED" 
} 
} 
+1

您可以發佈變量'vpc'的全部內容?例如添加任務' - 調試:var = vpc' – Kashyap

+0

謝謝Kashyap。 我已經用vpc的完整輸出更新了原來的問題。 – Ansiballer

回答

2

像這樣的東西可能會奏效:

- name: Find the first public subnet 
    set_fact: vpc_subnet_id="{{ item.id }}" 
    when: item.resource_tags.Name == "Public Subnet 1" 
    with_items: vpc.subnets 
+1

yupp ..使用' - set_fact:vpc_subnet_id =「{{item.id}}」'它應該有效。 – Kashyap

+0

基於@Kashyap評論編輯答案(這是正確的。沒有模塊稱爲'vpc_subnet_id',我們應該使用set_fact來設置一個新變量。) – Zasz

+0

非常感謝。這提供了我以後的行爲。 我沒有足夠的積分來「迴應」你的答案,否則我會。 再次感謝! – Ansiballer

2

您也可以嘗試寫一個子網過濾器如下:

vpc_subnet_id: "{{ vpc.subnets | subnet_name_filter() }}" 

用此創建文件/ansible_plugins/filter_plugins/core.py:

def subnet_name_filter(list): 
    return [x for x in list if x.resource_tags.Name == "Public Subnet 1"] 

class FilterModule(object): 
    def filters(self): 
    return {   
     'subnet_name_filter': subnet_name_filter 
    } 

編輯ansible.cfg和uncomment the line,在那裏啓用自定義filter_plugins。該路徑可以是相對的,並且ansible會查找相對於找到ansible.cfg的地方的插件。例如,我有我的ansible.cfg和所有插件檢入我的git倉庫。

編輯:

你也可以,如果你喜歡重構刪除硬編碼在定製插件:

def subnet_name_filter(list, restagname): 
    return [x for x in list if x.resource_tags.Name == restagname] 

,並使用

vpc_subnet_id: "{{ vpc.subnets | subnet_name_filter('Public Subnet 1') }}" 
+0

我總是討厭強制我們創建這種無用的/特定於我的大小寫的4521 filter_plugins。 – Kashyap

+0

所有的[jinja's builtin filters](http://jinja.pocoo.org/docs/dev/templates/#builtin-filters)也是不可靠的過濾器插件。但不幸的是,所有的忍者的[內建測試](http://jinja.pocoo.org/docs/dev/templates/#builtin-tests)都是不合理的。其中一些測試已實現爲像|這樣的過濾器跳過失敗更改等。建模測試作爲一個過濾器似乎是錯誤的,並導致所有這些冗長的代碼。 – Zasz

+0

感謝您花時間提供答案,這對我來說很有用,因爲我現在正在學習python。 非常感謝您的幫助。 – Ansiballer