Generating an Ansible Inventory

The main goal of this topic is to describe and give some examples about how to automatize your software deployment with Ansible.

Before reading this topic, you need to know how to use and create a playbook for Ansible. If you do not, see Ansible documentation.

Step 1: Create the Infrastructure

  1. Using for example the OUTSCALE Python SDK, create VMs with two reservations with the following characteristics based on front and database roles:

    reservation_front = gw.CreateVms(
        MinVmsCount=2,
        MaxVmsCount=3,
        ImageId="ami-xxxxxxx",
        VmType="t2.medium",
        KeypairName="my_keypair",
        SecurityGroupIds=["sg-xxxxxx"],
    )
    reservation_database = gw.CreateVms(
        MinVmsCount=2,
        MaxVmsCount=2,
        ImageId="ami-xxxxxxx",
        VmType="tinav5.c4r12p2",
        KeypairName="my_keypair",
        SecurityGroupIds=["sg-yyyyyy"],
    )
  2. For each VM, add the following roles tags:

    for vm in reservation_front["Vms"]:
        gw.CreateTags(
            ResourceIds=[vm["VmId"]],
            Tags=[{"Key": "roles", "Value": "monitoring_agent,front_web"}],
        )
    for vm in reservation_database["Vms"]:
        gw.CreateTags(
            ResourceIds=[vm["VmId"]],
            Tags=[{"Key": "roles", "Value": "monitoring_agent,database"}],
        )

Step 2: Generate the Inventory

To generate the inventory, you can use your Ansible playbook, based on the previous deployment on the OUTSCALE Cloud. The playbook requires the following elements:

  • All security groups need to allow the VM running the playbook on SSH port 22

  • The VM running the playbook needs to have the private key of the VMs

  • The playbook needs to run from within the Net if you target a Net deployment

Code
from configparser import ConfigParser


conf = ConfigParser(allow_no_value=True)

for vm in gw.ReadVms()["Vms"]:
    for tag in vm["Tags"]:
        if tag["Key"] == "role":
            for role in tag["Value"].split(","):
                if role not in conf.sections():
                    conf.add_section(role)
                print(vm["PrivateIp"])

with open("inventory", "w") as inv:
    conf.write(inv)
Output
[database]
10.0.1.243
10.0.2.153
10.0.2.53
[front_web]
10.0.2.104
10.0.2.156
[rabbit_mq]
10.0.2.6
[intel]
10.0.2.154
10.0.2.203
10.0.2.155
10.0.2.243