【发布时间】:2017-04-30 12:34:07
【问题描述】:
我正在尝试使用 Ansible 来预置 AWS EC2 安全组。
我希望其中一些组有多个规则。有些规则仅适用于我的内部 VPC,而其他规则则对全世界开放。
我想在从列表变量读取配置的循环中创建安全组,但我不想为内部 VPC 硬编码 CIDR。我宁愿从我的 VPC 事实中获取 CIDR,但我还没有找到一种令人满意的方法来将 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>
原作很有效,很简单:
- 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
我目前的策略是使用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,因为如果我不这样做,每个循环都会删除之前的规则。因此,如果我对规则进行更改,我可能会被旧规则卡住,我需要跟踪和清理这些旧规则。
其次,嵌套的三元组笨拙,不易扩展。
第三,只要一个电话就够了,我会打多个电话。
我觉得我遗漏了一些明显的东西,或者我过于复杂了。如何在 Ansible 剧本中完成 CIDR 替换,或者更一般地说,任何此类替换?替代更可取还是有更好的方法来完成相同的任务?
非常感谢您对此的任何帮助。
【问题讨论】:
标签: amazon-web-services ansible