2016-12-15 9 views
4

私は、AWS EC2セキュリティグループをプロビジョニングするためにAnsibleを使用しようとしています。EC2セキュリティグループのルールのための、危険なプレイブックの変数の置換

これらのグループのいくつかに複数のルールが必要です。一部のルールは社内のVPCにのみ適用され、他のルールは世界中に公開されます。

リスト変数から設定を読み込むループ内にセキュリティグループを作成したいが、内部VPCのCIDRをハードコードしたくない。むしろ私のVPCの事実からCIDRを取得したいと思いますが、私はCIDRをルールに置き換える満足のいく方法を見つけていません。

これをより明確にするために、ここに(考案された)例があります。オリジナルのプレイ作品

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> 

と非常に簡単です:グループの私の元のリストには、ハードコーディングされたのCIDRのすべてを持っていた

- 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 }}" 

私は、加算または減算のルールをし、グループが同期されますことを知ることができます。しかし、私はグループの私のリストが見えるようにしたい...ハードコードするのCIDRをしたくない:

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 

私の現在の戦略は、個別に各ルールのためec2_groupコマンドの束を実行するためにwith_subelementsを使用することです:

- 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をオフにする必要があります。このため、私が規則を変更すると、私は追跡して掃除する必要がある古い規則に固執することがあります。

第2に、ネストされた3進数は扱いにくく、容易に拡張できません。

第3に、私は十分な時に複数の電話をかけています。

私は何か明白でないか、これを過度に複雑にしているように感じます。どのようにして、CIDRの代替を達成することができますか、より一般的には、この種の代替物をAniableプレイブックでどのように達成できますか?代替が望ましいか、同じタスクを達成するためのより良い方法がありますか?

これに関するお手伝いをさせていただきます。

答えて

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に非常によく動作します。ワオ。いくつかあまりにも疎密に文書化されている非常に素晴らしい解決策:ルックアップの力、タスクレベルでのvarsの使用、ファイル転送以外のテンプレートの使用...このテクニックは他の同様の問題を解決するのに有益です。ありがとう、私はあなたの答えからかなり学んだ。 – cmmabee

関連する問題