The subnets role

Now that we have our VPC, we can start to populate it. The first thing we are going to configure is the 10 subnets. If you recall, we need the following:

  • Three EC2 instances
  • Three ELB instances
  • Two RDS instances
  • Two EFS instances

Create the role by running the following command from your working directory:

$ ansible-galaxy init roles/subnets

Now, in roles/subnets/defaults/main.yml, enter the following:

the_subnets:
- { use: 'ec2', az: 'a', subnet: '10.0.10.0/24' }
- { use: 'ec2', az: 'b', subnet: '10.0.11.0/24' }
- { use: 'ec2', az: 'c', subnet: '10.0.12.0/24' }
- { use: 'elb', az: 'a', subnet: '10.0.20.0/24' }
- { use: 'elb', az: 'b', subnet: '10.0.21.0/24' }
- { use: 'elb', az: 'c', subnet: '10.0.22.0/24' }
- { use: 'rds', az: 'a', subnet: '10.0.30.0/24' }
- { use: 'rds', az: 'b', subnet: '10.0.31.0/24' }
- { use: 'efs', az: 'b', subnet: '10.0.40.0/24' }
- { use: 'efs', az: 'c', subnet: '10.0.41.0/24' }

As you can see, we have a list of variables containing what the subnet is being used for (ec2, elb, rds, or efs), which availability zone the subnet should be created in (a, b, or c), and then the subnet itself. Here we are using a /24 for each of the availability zones.

Grouping the subnets like this should remove some of the repetition when it comes to creating the subnets. However, it doesn't remove it all, as we can see from the content of roles/subnets/tasks/main.yml:

- name: ensure that the subnets are present
ec2_vpc_subnet:
region: "{{ ec2_region }}"
state: present
vpc_id: "{{ vpc_info.vpc.id }}"
cidr: "{{ item.subnet }}"
az: "{{ ec2_region }}{{ item.az }}"
resource_tags:
"Name" : "{{ environment_name }}_{{ item.use }}_{{ ec2_region }}{{ item.az }}"
"Environment" : "{{ environment_name }}"
"Use" : "{{ item.use }}"
with_items: "{{ the_subnets }}"

The task starts off pretty simple: here we are using the ec2_vpc_subnet module to create subnets by looping through the the_subnets variable. As you can see, we are using the variable we registered in the previous role to correctly deploy the subnets into our VPC; this is vpc_info.vpc.id.

You may have noticed that we are not registering the results of this task; this is because, if we did, we would have had information on all ten subnets. Instead, we want to break this information down based on what the subnet is being used for. To find this information out, we can use the ec2_vpc_subnet_facts module to gather information based on our filtering using the Environment and Use tag we set when creating the subnets:

- name: gather information about the ec2 subnets
ec2_vpc_subnet_facts:
region: "{{ ec2_region }}"
filters:
"tag:Use": "ec2"
"tag:Environment": "{{ environment_name }}"
register: subnets_ec2

- name: gather information about the elb subnets
ec2_vpc_subnet_facts:
region: "{{ ec2_region }}"
filters:
"tag:Use": "elb"
"tag:Environment": "{{ environment_name }}"
register: subnets_elb

- name: gather information about the rds subnets
ec2_vpc_subnet_facts:
region: "{{ ec2_region }}"
filters:
"tag:Use": "rds"
"tag:Environment": "{{ environment_name }}"
register: subnets_rds

- name: gather information about the efs subnets
ec2_vpc_subnet_facts:
region: "{{ ec2_region }}"
filters:
"tag:Use": "efs"
"tag:Environment": "{{ environment_name }}"
register: subnets_efs

As you can see, here we are filtering the use of and registering four different sets of information: subnets_ec2, subnets_elbsubnets_rds, and subnets_efs. We are not quite there yet, however, because we only want to know the subnet IDs rather than all of the information about each of the subnets.

To do this, we need to use the set_fact module and some Jinja2 filtering:

- name: register just the IDs for each of the subnets
set_fact:
subnet_ec2_ids: "{{ subnets_ec2.subnets | map(attribute='id') | list }}"
subnet_elb_ids: "{{ subnets_elb.subnets | map(attribute='id') | list }}"
subnet_rds_ids: "{{ subnets_rds.subnets | map(attribute='id') | list }}"
subnet_efs_ids: "{{ subnets_efs.subnets | map(attribute='id') | list }}"

Finally, we can print out all of the IDs to the screen in one big list by joining the variables together:

# - name: print all the ids we have registered
# debug:
# msg: "{{ subnet_ec2_ids + subnet_elb_ids + subnet_rds_ids
+ subnet_efs_ids }}"

Now that we have all of the parts of our role together, let's run it. Update the site.yml file so it looks like the following:

- name: Create and configure an Amazon VPC
hosts: localhost
connection: local
gather_facts: True

vars_files:
- group_vars/common.yml

roles:
- roles/vpc
- roles/subnets

Then run the playbook using:

$ ansible-playbook site.yml

Before running the playbook, I commented out the debug task in the VPC role. Your output should look something like the output that follows; you may have noticed that the VPC role returns an ok as our VPC is there:

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [Create and configure an Amazon VPC] *******************************************************

TASK [Gathering Facts] **************************************************************************
ok: [localhost]

TASK [roles/vpc : ensure that the VPC is present] ***********************************************
ok: [localhost]

TASK [roles/subnets : ensure that the subnets are present] **************************************
changed: [localhost] => (item={u'subnet': u'10.0.10.0/24', u'use': u'ec2', u'az': u'a'})
changed: [localhost] => (item={u'subnet': u'10.0.11.0/24', u'use': u'ec2', u'az': u'b'})
changed: [localhost] => (item={u'subnet': u'10.0.12.0/24', u'use': u'ec2', u'az': u'c'})
changed: [localhost] => (item={u'subnet': u'10.0.20.0/24', u'use': u'elb', u'az': u'a'})
changed: [localhost] => (item={u'subnet': u'10.0.21.0/24', u'use': u'elb', u'az': u'b'})
changed: [localhost] => (item={u'subnet': u'10.0.22.0/24', u'use': u'elb', u'az': u'c'})
changed: [localhost] => (item={u'subnet': u'10.0.30.0/24', u'use': u'rds', u'az': u'a'})
changed: [localhost] => (item={u'subnet': u'10.0.31.0/24', u'use': u'rds', u'az': u'b'})
changed: [localhost] => (item={u'subnet': u'10.0.40.0/24', u'use': u'efs', u'az': u'b'})
changed: [localhost] => (item={u'subnet': u'10.0.41.0/24', u'use': u'efs', u'az': u'c'})

TASK [roles/subnets : gather information about the ec2 subnets] *********************************
ok: [localhost]

TASK [roles/subnets : gather information about the elb subnets] *********************************
ok: [localhost]

TASK [roles/subnets : gather information about the rds subnets] *********************************
ok: [localhost]

TASK [roles/subnets : gather information about the efs subnets] *********************************
ok: [localhost]

TASK [roles/subnets : register just the IDs for each of the subnets] ****************************
ok: [localhost]

TASK [roles/subnets : print all the ids we have registered] *************************************
ok: [localhost] => {
"msg": [
"subnet-2951e761",
"subnet-24ea4a42",
"subnet-fce80ba6",
"subnet-6744f22f",
"subnet-64eb083e",
"subnet-51f15137",
"subnet-154ef85d",
"subnet-19e9497f",
"subnet-4340f60b",
"subnet-5aea0900"
]
}

PLAY RECAP **************************************************************************************
localhost : ok=9 changed=1 unreachable=0 failed=0

The only change recorded is the addition of the subnets; if we were to run it again, then this would also return an ok as the subnets exist. As you can also see, we have ten subnet IDs returned and this is also reflected in the AWS console:

Now that we have our subnets, we need to make sure that the EC2 instances can route to the internet.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.103.10