From charlesreid1

(Created page with "==How to use Ansible Hosts File with AWS== The hosts inventory file is treated as static when managing our own infrastructure, but with AWS this information will become out o...")
 
No edit summary
Line 1: Line 1:
==How to use Ansible Hosts File with AWS==
{{Main|Ansible/Hosts}}
 
List of user-contributed Ansible scripts to interface with other machine-managing services (like AWS): https://github.com/ansible/ansible/tree/devel/contrib/inventory
 
==How to use Ansible hosts file with AWS==


The hosts inventory file is treated as static when managing our own infrastructure, but with AWS this information will become out of date quickly. Ansible can get information via the AWS API, but has to know to do that.
The hosts inventory file is treated as static when managing our own infrastructure, but with AWS this information will become out of date quickly. Ansible can get information via the AWS API, but has to know to do that.
Line 22: Line 26:
</pre>
</pre>


==Example dynamic inventory script==
===Example executable dynamic inventory script===


Let's walk through an example.
Let's walk through an example.
Line 94: Line 98:
</pre>
</pre>


==How to manage static and dynamic inventory==
To have a regular static inventory file and a dynamic inventory script, or any combination of the above, put them all in a directory, and tell Ansible to use this directory for inventory in the Ansible configuration file or on the command line.
If our directory structure is:
<pre>
playbooks/inventory/hosts
playbooks/inventory/vagrant.py
</pre>
we would have an <code>ansible.cfg</code> with the contents:
<pre>
[defaults]
inventory = inventory
</pre>








=Flags=


[[Category:Ansible]]
[[Category:Ansible]]

Revision as of 19:42, 8 November 2018

List of user-contributed Ansible scripts to interface with other machine-managing services (like AWS): https://github.com/ansible/ansible/tree/devel/contrib/inventory

How to use Ansible hosts file with AWS

The hosts inventory file is treated as static when managing our own infrastructure, but with AWS this information will become out of date quickly. Ansible can get information via the AWS API, but has to know to do that.

Ansible can be put in dynamic inventory mode by making the inventory file (playbooks/hosts executable):

chmod +x playbooks/hosts

The script must accept two command line flags:

--host=<hostname>   show host details
--list              list groups

For example, Ansible will call the inventory script like so:

$ ./dynamic.py --host=vagrant2

Example executable dynamic inventory script

Let's walk through an example.

List of hosts:

For vagrant machines, vagrant status gives output about which machines are running. This is information we want to provide to the dynamic inventory file to create a list of hosts.

vagrant status --machine-readable

which is a lot of info in CSV format that can be parsed.

Next, we can use the vagrant ssh-config command, which outputs information that is formatted for an SSH config file, and parse it using pamiko (a Python library for doing SSH-related things - in this case, parsing an SSH config file and turning it into a python dictionary).

#!/usr/bin/env python
# Adapted from Mark Mandel's implementation
# https://github.com/ansible/ansible/blob/stable-2.1/contrib/inventory/vagrant.py
# License: GNU General Public License, Version 3 <http://www.gnu.org/licenses/>
import argparse
import json
import paramiko
import subprocess
import sys


def parse_args():
    parser = argparse.ArgumentParser(description="Vagrant inventory script")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--list', action='store_true')
    group.add_argument('--host')
    return parser.parse_args()


def list_running_hosts():
    cmd = "vagrant status --machine-readable"
    status = subprocess.check_output(cmd.split()).rstrip()
    hosts = []
    for line in status.split('\n'):
        (_, host, key, value) = line.split(',')[:4]
        if key == 'state' and value == 'running':
            hosts.append(host)
    return hosts


def get_host_details(host):
    cmd = "vagrant ssh-config {}".format(host)
    p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
    config = paramiko.SSHConfig()
    config.parse(p.stdout)
    c = config.lookup(host)
    return {'ansible_host': c['hostname'],
            'ansible_port': c['port'],
            'ansible_user': c['user'],
            'ansible_private_key_file': c['identityfile'][0]}


def main():
    args = parse_args()
    if args.list:
        hosts = list_running_hosts()
        json.dump({'vagrant': hosts}, sys.stdout)
    else:
        details = get_host_details(args.host)
        json.dump(details, sys.stdout)

if __name__ == '__main__':
    main()


How to manage static and dynamic inventory

To have a regular static inventory file and a dynamic inventory script, or any combination of the above, put them all in a directory, and tell Ansible to use this directory for inventory in the Ansible configuration file or on the command line.

If our directory structure is:

playbooks/inventory/hosts
playbooks/inventory/vagrant.py

we would have an ansible.cfg with the contents:

[defaults]
inventory = inventory



Flags