Managing AWS resources using Ansible Dynamic Inventory…

Ansible is a great tool for provisioning servers but when it comes to the creation of infrastructure it doesn’t perform as well as Terraform. It is true, was never meant for such a  purpose. However, for provisioning a server it works very well.

In this post, I’m going to discuss how to use AWS resources using Ansible with the help of Dynamic Inventory.

This is a short post to show you how to get you started on.

What is Ansible Dynamic Inventory?

While provisioning resources, we store the details of our servers in the inventory file. We group them and assign IP etc. However, in the cloud, we can’t manually manage it.

Requirements

  • Download ec2.py (python script which gets the resources from AWS) and ec2.ini (configuration file) place both files in the same directory.
  • The “boto” library.  pip install boto

Configuring Ansible to use ec2.py as the inventory resource

In-order fully rely on AWS resources, we would need to configure our “ansible.cfg” inventory to point to the “ec2.py” file

[defaults]
inventory = ./ec2.py

 

Now, that we have our inventory pointed to the “Dynamic Inventory” file, let’s try to ping all our EC2 instances.

Pinging all our EC2 instances

ansible all -m ping

If you have noticed, we have not mentioned any IP addresses. This is the advantage of Dynamic Inventory. Ansible will ping to all our EC2 instances

Great! Let’s do more.

Listing AWS resources

To list AWS resources execute the below command:

./ec2.py --list

This will return the entire list of AWS resources in JSON.

{
  "_meta": {
    "hostvars": {
      "65.201.11.219": {
        "ansible_host": "34.201.11.219",
        "ec2__in_monitoring_element": false,
        "ec2_account_id": "209518873002",
        "ec2_ami_launch_index": "0",
        "ec2_architecture": "x86_64",
        "ec2_block_devices": {
          "xvda": "vol-008e156f7bc2d99ad"
        },
        "ec2_client_token": "",
        "ec2_dns_name": "ec2-65-201-11-219.compute-1.amazonaws.com",
        "ec2_ebs_optimized": false,
        "ec2_eventsSet": "",
        "ec2_group_name": "",
        "ec2_hypervisor": "xen",
        "ec2_id": "i-09689b6635c10f3cf2",
        "ec2_image_id": "ami-467ca739",
        "ec2_instance_profile": "",
        "ec2_instance_type": "t2.micro",
        "ec2_ip_address": "34.222.11.219",
        "ec2_item": "",
        "ec2_kernel": "",
        "ec2_key_name": "ec2_private.pem",
        "ec2_launch_time": "2018-07-04T20:10:57.000Z"
}}}}

So far we are able to list the AWS resources and ping all our EC2 instances. but how are we going to utilize Dynamic Inventory in a playbook?

Destroying AWS resources in Ansible

Creating AWS resources in Ansible is extremely easy but the challenge is destroying it. Ansible does not store the state of the infrastructure like Terraform, so if we want to destroy resources we have to utilize the Dynamic Inventory feature.

Creating AWS EC2 instance

 - name: Create EC2 Instance in the public subnet
   ec2:
    image: ami-467ca739
    wait: yes
    instance_type: t2.micro
    region: "{{ region }}"
    group_id: "{{ security_group.group_id }}"
    vpc_subnet_id: "{{ subnet.subnet.id }}"
    key_name: "{{ keypair.key.name  }}"
    count_tag: "{{ ec2_tag }}"
    exact_count: 1
    instance_tags:
      tool: "env"
      env: "stage"
    
 

We need to tag the EC2 server creation as it is important while managing AWS resources in Ansible. This is how Ansible retrieves information of resources by querying the info of tag.
So to delete the server we will declare the host’s name to match the tag attributes

hosts: "tag_env_stage"

Any tasks executed below will be performed on the resources with the tag “env:stage”. This is great! We no longer need to maintain the IP addresses of our EC2 instances in the inventory file. This is where Dynamic Inventory shines.

If you have any other suggestions, please drop a comment 🙂