2016-12-15 37 views
4

我正在嘗試使用Ansible來提供AWS EC2安全組。將Ansible變量替換爲EC2安全組規則

我希望其中一些組擁有多個規則。一些規則將僅適用於我的內部VPC,而其他規則則向全世界開放。

我想在一個從列表變量讀取配置的循環中創建安全組,但我不想硬編碼內部VPC的CIDR。我寧願從我的VPC事實中獲得CIDR,但我還沒有找到一種令人滿意的方式將CIDR替換爲規則。

爲了使這更清楚,這裏是一個(人爲的)例子。我原來的組列表中有所有硬編碼的CIDRs的:

aws_security_groups: 
    - name: Webservers 
    description: Security group for webservers 
    region: my_aws_region 
    rules: 
     - proto: tcp 
     from_port: 22 
     to_port: 22 
     cidr_ip: 0.0.0.0/0 
     - proto: tcp 
     from_port: 80 
     to_port: 80 
     cidr_ip: 0.0.0.0/0 
    - name: Databases 
    description: Security group for internal database access 
    region: my_aws_region 
    rules: 
     - proto: tcp 
     from_port: 22 
     to_port: 22 
     cidr_ip: 0.0.0.0/0 
     - proto: tcp 
     from_port: 3306 
     to_port: 3306 
     cidr_ip: <vpc.cidr.hard.coded/16> 

發揮原有的作品,是非常簡單的:

- name: Provision EC2 security groups 
    ec2_group: 
    name: "{{ item.name }}" 
    description: "{{ item.description }}" 
    region: "{{ item.region }}" 
    state: present 
    rules: "{{ item.rules }}" 
    with_items: "{{ aws_security_groups }}" 

我可以加上或減去規則,知道組將進行同步。不過,我不想硬編碼CIDRs ......我希望我的團體名單看起來像:

aws_security_groups: 
    - name: Webservers 
    description: Security group for webservers 
    region: my_aws_region 
    rules: 
     - proto: tcp 
     from_port: 22 
     to_port: 22 
     cidr_ip: all 
     - proto: tcp 
     from_port: 80 
     to_port: 80 
     cidr_ip: all 

    - name: Databases 
    description: Security group for internal database access 
    region: my_aws_region 
    rules: 
     - proto: tcp 
     from_port: 22 
     to_port: 22 
     cidr_ip: all 
     - proto: tcp 
     from_port: 3306 
     to_port: 3306 
     cidr_ip: internal 

我目前的策略是使用with_subelements單獨運行一堆ec2_group命令的每個規則:

- name: Gather EC2 VPC facts 
    ec2_vpc_net_facts: 
    region: my_aws_region 
    register: vpcs 

- name: Provision EC2 security groups 
    ec2_group: 
    name: "{{ item.0.name }}" 
    description: "{{ item.0.description }}" 
    region: "{{ item.0.region }}" 
    state: present 
    purge_rules: false 
    rules: 
     - from_port: "{{ item.1.from_port }}" 
     to_port: "{{ item.1.to_port }}" 
     proto: "{{ item.1.proto }}" 
     cidr_ip: "{{ (item.1.cidr_ip == 'internal') | ternary(vpcs.vpcs.0.cidr_block, (item.1.cidr_ip == 'all') | ternary('0.0.0.0/0', item.1.cidr_ip)) }}" 
    with_subelements: 
    - "{{ aws_security_groups }}" 
    - rules 

替換工作,但我堅持一些不舒服的權衡。

首先,我必須關閉purge_rules,因爲如果我不這樣做,每個循環都會刪除以前的規則。正因爲如此,如果我對規則進行修改,我可能會陷入舊規則,我需要跟蹤和清理。

其次,嵌套三元組很尷尬,不容易擴展。

第三,如果一個人足夠多,我會多次打電話。

我覺得我錯過了一些明顯的東西,或者我過分複雜化了這一點。我怎樣才能完成CIDR替換,或者更一般地說,在Ansible playbook中的這種替換?替代更好還是有更好的方法來完成相同的任務?

任何幫助是極大的讚賞。

回答

1

以下方法可以避免purge_rules問題,它更乾淨,恕我直言。

任務:

- set_fact: 
    from_template: "{{ lookup('template', './template.j2') }}" 
    vars: 
    to_template_aws_security_groups: "{{ aws_security_groups }}" 
    to_template_vpcs: "{{ vpcs }}" 

- name: Provision EC2 security groups 
    ec2_group: 
    name: "{{ item.name }}" 
    description: "{{ item.description }}" 
    region: "{{ item.region }}" 
    state: present 
    rules: "{{ item.rules }}" 
    with_items: "{{ from_template.aws_security_groups }}" 

template.j2

{ 
    "aws_security_groups": [ 
    {% for aws_security_group in to_template_aws_security_groups %} 
    { 
     "description": "{{ aws_security_group.description }}", 
     "name": "{{ aws_security_group.name }}", 
     "region": "{{ aws_security_group.region }}", 
     "rules": [ 
     {% for rule in aws_security_group.rules %} 
     { 
      "cidr_ip": "{{ (rule.cidr_ip == 'internal') | ternary(to_template_vpcs.vpcs.0.cidr_block, (rule.cidr_ip == 'all') | ternary('0.0.0.0/0', rule.cidr_ip)) }}", 
      "from_port": "{{ rule.from_port }}", 
      "proto": "{{ rule.proto }}", 
      "to_port": {{ rule.to_port }} 
     }{% if not loop.last %},{% endif %} 
     {% endfor %} 
     ] 
    }{% if not loop.last %},{% endif %} 
    {% endfor %} 
    ] 
} 
+1

作品相當不錯,在現實AWS。哇。一個非常好的解決方案,彙集了一些稀疏文檔的Ansible概念:查找的力量,在任務級別使用'vars',使用文件傳輸之外的模板......這種技術在解決其他類似問題上很有價值。謝謝,我從你的回答中學到了很多東西。 – cmmabee