Custom Dynamic Inventory for Ansible to Find IP address of ec2 Instances using Tag

Hi Folks!

As you may know, I am writing my test-cases, especially how to automate our AWS infrastructure using any form of scripts. 

In this tutorial, I am gonna cover-up custom dynamic inventory for Ansible to Find the IP address of ec2 instances using Tag.

We know each time ec2 instances have restarted AWSautomatically assigns public IP to the restarted instance(No EIP). And also Ansible provides external dynamic inventory to find out the information about ec2 instances with the help of ec2.py

BUT, it provides a bunch of information that we don't need.

Scenario: Let's say I have 3 instances (2 app instances and a db instance with tag name app and db respectively) and I want to ping each instance by group (app and db) name using Ansible. So, I create a dynamic inventory to find the IP address of instances with the tag name.

Prerequisites: For making a successful API call to AWS, we need to configure Boto (the Python interface to AWS). There are a variety of methods available, but the simplest is to export the following environment variables:
export AWS_ACCESS_KEY_ID=’AK123′

export AWS_SECRET_ACCESS_KEY=’abc123′

Let's dive in,

Step 1: Create find-ip-by-tag.py
Create a python find-ip-by-tag.py file in which provide the location of the python directory, import boto3 to provide python interface to AWS and import Jason to make Jason base library output later
!#/bin/python
import boto3
import jason
Step 2: Create a  main function to invoke python methods
if __name__=="__main__":
        main()

Step 3: Create find-ip method before we create the python main method.
create the method which takes arguments AWS SDK object,  tag key, and tag value
!#/bin/python
import boto3
import jason
def find-ip(client,tagkey,tagvalue):
    response = client.describe_instances(
    Filters=[{
            'Name': 'instance-state-name',
            'Values': [
                'running',
            ]
         },
  {
            'Name': 'tagkey',
            'Values': [
                'tagvalue',
            ]
        }],DryRun=TRUE
    )
if __name__=="__main__":
        main()
 There is a lot going on there, inside find-ip method response = client.describe_instances() basically, return all the information about the instances in a given region. Along with the code, we used filter function to return instances by tag names that are currently running to response variable.
Now create a loop function to get a list of the public IP address of the Instance for the given tag name
!#/bin/python
import boto3
import jason


def find-ip(client,tagkey,tagvalue):
    response = client.describe_instances(
    Filters=[{
            'Name': 'instance-state-name',
            'Values': [
                'running',
            ]
         },
  {
            'Name': 'tagkey',
            'Values': [
                'tagvalue',
            ]
        }],DryRun=TRUE
    )
    instance-ip-list = []
    for res in (respones["Reservations"]):
        for instance in reservation["Instances"]:
            instance-ip-list.append(instance["PublicIpAddress"])
    return instance-ip-list
Please refer the boto document to get describe_instance() output.
Step 4: Create main method to return ip for given tag name
def main():
    client = boto3.client('ec2')
    db-group-ip=find-ip(client,"tag:Env","db")
    app-group-ip=find-ip(client,"tag:Env","app")
    jason-group={'db':db-group-ip,'app':app-group-ip}
    #it create jason data
    print(jason.dumps(jason-group))
    return None
if you look at the code, jason-group={'db':db-group-ip,'app':app-group-ip}  it creates a library with tag group and group's IP address
And then we print Jason output to the user.

Step 5: ping instances with dynamic inventory
ansible -i find-ip-by-tag.py db -m ping
Now, We can able to see that ansible is pinging the db group instances.

Find the repo here

That's pretty much guys! peace!


No comments:

Post a Comment