I am trying to use Ansible to provide AWS EC2 security groups.
I want some of these groups to have several rules. Some rules will only apply to my internal VPC, while others are open to the world.
I would like to create security groups in a loop that reads the configuration from a list variable, but I do not want to hardcode the CIDR for the internal VPC. I would rather get CIDR from my VPC facts, but I have not found a satisfactory way to replace CIDR with a rule.
To make this clearer, here is an example (contrived). In my original list of groups all CIDRs were written:
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>
The original game works and is very simple:
- 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, , . - , , , .
-, .
-, , .
, - . CIDR , , Ansible? ?
.