Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding and removing multiple IP address to AWS security group using Ansible

I was trying to use Ansible to add IP addresses to an AWS security group.

I came up with a task syntax that looks like this:

- hosts: localhost
  gather_facts: False
  vars:
    ip_addresses:
      - 1.2.3.4/32
      - 2.3.4.5/32
  tasks:
    - ec2_group:
        name: security-group-name
        description: Security group description
        vpc_id: vpc-1234567
        region: us-east-1
        profile: profile-name
        purge_rules: false
        rules:
         - proto: tcp
           from_port: 123
           to_port: 123
           cidr_ip: "{{ item }}"
      with_items: ip_addresses

This does not do exactly what I was looking for as it basically runs the ec2_group task multiple times instead of just looping over the rules.

This also does not work if I set the purge_rules to true as then it will purge all existing rules on each iteration, effectively removing all but the last IP address on the list.

I'm wondering if there is something similar to with_items that I can apply to the rules attribute to provide it a list of IP addresses but calling ec2_task only once?

like image 236
MSK Avatar asked Dec 05 '25 17:12

MSK


2 Answers

You can achieve what you want with a custom filter plugin.

Create a directory in the root of your playbook called filter_plugins and create a file in there called make_rules.py with the following contents:

def make_rules(hosts, ports, proto):
    return [{"proto": proto,
             "from_port": port,
             "to_port": port,
             "cidr_ip": host} for host in hosts for port in map(int, ports.split(","))]

class FilterModule(object):
     def filters(self):
         return {'make_rules': make_rules}

Then you can do this:

- hosts: localhost
  gather_facts: False
  vars:
    ip_addresses:
      - 1.2.3.4/32
      - 2.3.4.5/32
  tasks:
    - ec2_group:
        name: security-group-name
        description: Security group description
        vpc_id: vpc-1234567
        region: us-east-1
        profile: profile-name
        purge_rules: true
        rules: {{ ip_addresses | make_rules('123', 'tcp') }}

Taken from: https://gist.github.com/viesti/1febe79938c09cc29501

like image 70
nftw Avatar answered Dec 08 '25 06:12

nftw


This does not do exactly what I was looking for as it basically runs the ec2_group task multiple times instead of just looping over the rules.

Ansible implements loops by invoking the task once for each item in the loop, so that's expected behavior.

I'm wondering if there is something similar to with_items that I can apply to the rules attribute to provide it a list of IP addresses but calling ec2_task only once?

Since the rules property for ec2_group actually takes a list of rules, you should be able to do the following:

- ec2_group:
    name: security-group-name
    description: Security group description
    vpc_id: vpc-1234567
    region: us-east-1
    profile: profile-name
    purge_rules: true
    rules:
     - proto: tcp
       from_port: 123
       to_port: 123
       cidr_ip: 1.2.3.4/32
     - proto: tcp
       from_port: 123
       to_port: 123
       cidr_ip: 2.3.4.5/32

Or, if you want to use pre-defined vars as in your example:

vars:
  my_rules:
     - proto: tcp
       from_port: 123
       to_port: 123
       cidr_ip: 1.2.3.4/32
     - proto: tcp
       from_port: 123
       to_port: 123
       cidr_ip: 2.3.4.5/32

tasks:
  - ec2_group:
      name: security-group-name
     description: Security group description
      vpc_id: vpc-1234567
      region: us-east-1
      profile: profile-name
      purge_rules: true
      rules: my_rules
like image 29
Bruce P Avatar answered Dec 08 '25 07:12

Bruce P



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!