Chathan Driehuys
Chathan Driehuys

Reputation: 1213

How to add a temporary rule to an EC2 security group with Ansible

I have an Ansible role to handle creation of an RDS instance and the databases on that instance. The role allows a security group to be specified for the database. I want to be able to add a rule to the security group at the beginning of the role that allows access from the current host so that Ansible can run some database creation/maintenance tasks. I then want to remove this rule from the security group while maintaining the existing groups.

What I've done so far is used the ec2_group_facts module to get information about the given security group which I save in the security_group variable. I then add a rule with a task similar to the following:

- name: Add hole to security group
  local_action:
    module: ec2_group
    name: "{{ security_group.group_name }}"
    purge_rules: no
    rules:
      - proto: tcp
        from_port: "{{ db_port }}"
        to_port: "{{ db_port }}"
        cidr_ip: 0.0.0.0/0

This all works properly. The issue is that at the end of the role, when I want to restore the existing rules, the format of the rules returned by ec2_group_facts is not accepted by the ec2_group module. The information saved about security_group is in the following format:

{
  "group_id": "sg-1234abcd", 
  "group_name": "security-group", 
  "ip_permissions": [
    {
      "from_port": 1234, 
      "ip_protocol": "tcp", 
      "ip_ranges": [
        {
          "cidr_ip": "0.0.0.0/0"
        }
      ], 
      "ipv6_ranges": [], 
      "prefix_list_ids": [], 
      "to_port": 1234, 
      "user_id_group_pairs": []
    }
  ], 
  "ip_permissions_egress": [], 
  "owner_id": "123456789012", 
  "tags": {
    "Name": ""
  }, 
  "vpc_id": "vpc-1234abcd"
}

The rules argument of the ec2_group module needs a list of objects with proto, from_port, to_port, and cidr_ip attributes, so how would I map the data above to the required format?

Edit: I guess one solution would be to add a temporary security group that allows access from the current host. If my understanding of EC2 security groups is correct, the most permissive rule of the security groups associated with an instance is applied so this would achieve what I want. However this would require editing the security groups attached to an existing RDS instance, so I would prefer to edit the rules of an existing security group if possible.

Edit 2: Travis CI publishes the IP addresses used to run builds. I could just add these to the security group permanently, although I'm not sure what the security implications of this are.

ec2_group docs
ec2_group_facts docs

Upvotes: 2

Views: 1868

Answers (1)

Hammett
Hammett

Reputation: 385

When running playbooks you want a consistent state and from the sounds of things you don't have a consistent state throughout your play.

I would suggest that the additional task that you would like to perform on the database could be run from some other instance that is more trusted (perhaps the place you're running ansible from?).

Consider what will happen if a playbook is run twice at the same time. Perhaps this isn't something your workflow allows for but you should still consider this case.

If this isn't an option or you would rather not change your implementation then your edit's suggestion sounds more suitable. Apply your standard rules and when required add to your rules (or create a new security group for this purpose) and then destroy or modify when no longer required.

Upvotes: 1

Related Questions