Configuring ELB access for EC2 instances with Ansible

7 May 2015, Rhodri Pugh

We use Ansible to manage our security group configuration in EC2, but there is currently a limitation with the ec2_group module that doesn’t allow you to work with groups from other accounts. This poses a problem when you need to allow ELB to access your web servers for example. We’ve worked around this problem for a while now by manually tweaking the security groups when needed, but today I decided to look into a more automated workaround.

AWS CLI

The AWS CLI provides access to EC2 security groups with the following commands:

  • authorize-security-group-ingess
  • revoke-security-group-ingress

(With matching egress versions)

So I thought I’d use these to take away the need for the manual tweaking we’re currently living with.

Authorising

It took me a little while to work out which parameters I needed, as (to me at least) the names the AWS CLI has chosen for them don’t match up with anything I’ve become familiar with using the web console.

Here’s a working example:

1
2
3
4
5
6
7
aws ec2 authorize-security-group-ingress \
        --region "$REGION" \
        --group-name "$INSTANCE_SG_NAME" \
        --protocol tcp \
        --port 80 \
        --source-group "$ELB_SG" \
        --group-owner amazon-elb

What I then decided to in my Ansible playbook was to do a revoke before I applied my security rules (as ec2_group will crash if there’s a rule from another account found) and authorize it afterwards.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
---

- name: Apply Security Groups
  hosts: 127.0.0.1
  connection: local
  gather_facts: no
  tasks:

      - name: Remove ELB Rule
        shell: aws ec2 revoke-security-group-ingress \
                 --region "{{ region }}" \
                 --group-name "{{ instance_sg_name }}" \
                 --protocol tcp \
                 --port 80 \
                 --source-group "{{ elb_sg }}" \
                 --group-owner amazon-elb
        ignore_errors: yes

      # use ec2_group to purge old rules and apply new ones here, then...

      - name: Add ELB Rule
        shell: aws ec2 authorize-security-group-ingress \
                 --region "{{ region }}" \
                 --group-name "{{ instance_sg_name }}" \
                 --protocol tcp \
                 --port 80 \
                 --source-group "{{ elb_sg }}" \
                 --group-owner amazon-elb

We ignore any errors if the revoke fails just incase it didn’t exist in the first place (this can probably be improved to only not fail if the error is that it doesn’t exist).

Summary

I’m writing this blog post not because this is anything revolutionary, but because it took me a lot of Googling to find out what the issue was here, and a bit more again trying to work out how to use the AWS CLI. So hopefully this will save someone a little head scratching.