Book Image

Ansible 2 Cloud Automation Cookbook

By : Aditya Patawari, Vikas Aggarwal
Book Image

Ansible 2 Cloud Automation Cookbook

By: Aditya Patawari, Vikas Aggarwal

Overview of this book

Ansible has a large collection of inbuilt modules to manage various cloud resources. The book begins with the concepts needed to safeguard your credentials and explain how you interact with cloud providers to manage resources. Each chapter begins with an introduction and prerequisites to use the right modules to manage a given cloud provider. Learn about Amazon Web Services, Google Cloud, Microsoft Azure, and other providers. Each chapter shows you how to create basic computing resources, which you can then use to deploy an application. Finally, you will be able to deploy a sample application to demonstrate various usage patterns and utilities of resources.
Table of Contents (11 chapters)

Using dynamic inventory

We have talked about dynamic inventory a little bit in this chapter. Throughout this book, in every chapter, we are going to talk about and use dynamic inventory. So let us explore the concept in a bit more depth.

Reiterating what we wrote earlier, dynamic inventory is useful for infrastructures that are dynamic in nature or for cases where we do not want to or cannot maintain a static inventory. Dynamic inventory queries a datasource and builds the inventory in real time. For the sake of this book, we will query cloud providers to get data and build the inventory. Ansible provides dynamic inventory scripts for most of the popular cloud providers.

However, it is simple to create a dynamic inventory script by ourselves. Any executable script that can return a JSON with a list of inventory host groups and hosts in a predetermined format, when passed with a parameter --list can be used as an inventory script. A very simple inventory would output something like this:

{
"application": ["10.0.0.11", "10.0.0.12"],
"database": ["10.0.1.11"]
}

More elaborate inventory scripts would output much more information like instance tags, names, operating systems, geographical locations, and, also known as host facts.

How to do it...

To present a realistic example, we have created a simple inventory script for Amazon Web Service in Python. The code is available on GitHub (https://github.com/ansible-cookbook/ec2_tags_inventory):

#!/usr/bin/env python
import boto3
import json
import ConfigParser
import os

def get_address(instance):
if "PublicIpAddress" in instance:
address = instance["PublicIpAddress"]
else:
address = instance["PrivateIpAddress"]
return address

if os.path.isfile('ec2.ini'):
config_path = 'ec2.ini'
elif os.path.isfile(os.path.expanduser('~/ec2.ini')):
config_path = os.path.expanduser('~/ec2.ini')

config = ConfigParser.ConfigParser()
config.read(config_path)
id = config.get("credentials", "aws_access_key_id", raw=True)
key = config.get("credentials", "aws_secret_access_key", raw=True)

client = boto3.client('ec2', aws_access_key_id = id, aws_secret_access_key = key, region_name="us-east-1")

inventory = {}

reservations = client.describe_instances()['Reservations']
for reservation in reservations:
for instance in reservation['Instances']:
address = get_address(instance)
for tag in instance['Tags']:
if tag['Key'] == "ansible_role":
roles = tag['Value'].split(",")
for role in roles:
if role in inventory:
inventory[role].append(address)
else:
inventory[role] = [address]
print json.dumps(inventory)

This script reads a file called ec2.ini for AWS access and secret key. For the sake of simplicity, we have hardcoded the region to us-east-1 but this can be changed easily. The script goes through AWS EC2 in the us-east-1 region and looks for any instance that has a tag with the name ansible_role and any valid value like webserver or database. It will add the IP addresses of those instances to the Python dictionary variable called inventory. In the end, this variable is dumped as JSON as output.

We can test this by executing:

$ python ec2_tags_inventory.py --list
{"application": ["10.0.0.11", "10.0.0.12"], "database": ["10.0.1.11"]}

Note that output may vary depending on the instances that are tagged in EC2. To use this in an Ansible command, we need to make it executable and just pass the script instead of inventory file to -i flag like this:

$ chmod +x ec2_tags_inventory.py
$ ansible -i ec2_tags_inventory.py database -m ping
database | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}

Needless to say, this is a very simple example and the actual dynamic inventory script provided by Ansible is much more comprehensive and it looks beyond EC2 to other services, such as RDS.