Ansible playbook variable substitution for EC2 security group rules

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? ?

.

+4
1

purge_rules , imho.

:

- 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

Source: https://habr.com/ru/post/1663793/


All Articles