Using the OpenStack inventory helper for Ansible

While Tower makes it easy to manage custom inventory, I still want to develop using the command line. Thus, I want to generate a comparable smart inventory for my Ansible playbook as I get from tower.

THe inventory helpers for Ansible are committed to a contrib subdirectory upstream. For example, the openstack inventory helper is here:

I cloned the git repo and checked out the devel branch (contrib is hidden in release branches) so I could run the script. Then source my keystone.rc file:

. ~/devel/openstack/moc/keystonev3.rc

And make sure I have some hosts:

$ openstack server list
+--------------------------------------+------------------------+--------+------------------------------------------------------+------------------------+-----------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+------------------------+--------+------------------------------------------------------+------------------------+-----------+
| 1ece60af-4fe5-4cb4-9da0-605f0e37b708 | dev1jboss.awx.devstack | ACTIVE | dev1_network=192.168.24.10, 1.1.1.134 | rhel-guest-image-7.5-1 | m1.medium |
| 737c8c9c-4a90-46ed-bf2c-16e042c8547e | datagen.awx.devstack | ACTIVE | causal_network=192.168.24.9, 1.1.1.95 | rhel-guest-image-7.5-1 | m1.xlarge |
| 4992c139-4b21-4c38-8912-3e6f8f6e1e7a | idm.awx.devstack | ACTIVE | awx-private-net_network=192.168.24.12, 1.1.1.132 | rhel-guest-image-7.5-1 | m1.medium |
+--------------------------------------+------------------------+--------+------------------------------------------------------+------------------------+-----------+

(NOTE: I modified the IP addresses for the floating, public accessible hosts)

Now run the script:

 /home/ayoung/devel/ansible/contrib/inventory/openstack_inventory.py --list

And I get a lot of output:

{
  "_meta": {
    "hostvars": {
      "1ece60af-4fe5-4cb4-9da0-605f0e37b708": {
        "ansible_host": "1.1.1.134", 
        "ansible_ssh_host": "1.1.1.134", 
        "openstack": {
...
  "nova": [
    "4992c139-4b21-4c38-8912-3e6f8f6e1e7a", 
    "1ece60af-4fe5-4cb4-9da0-605f0e37b708", 
    "737c8c9c-4a90-46ed-bf2c-16e042c8547e"
  ]
}

Each server as named by Nova gets its own entry. For example, I have a server named dev1jboss.awx.devstack and I can query it via:

$/home/ayoung/devel/ansible/contrib/inventory/openstack_inventory.py --host dev1jboss.awx.devstack | jq '.name'
"dev1jboss.awx.devstack"

I can run an ad-hoc command using the inventory as a parameter:

ansible  --key-file ~/keys/id_rsa  --user cloud-user  -i /home/ayoung/devel/ansible/contrib/inventory/openstack_inventory.py dev1jboss.awx.devstack -m setup

If I have a playbook that can work with all hosts, and I want to limit it to just one, I can use the -l or –limit option. I use that, for example for installing an application on a random host. If I want to install on only Development boxes (versus production) I can run:

ansible-playbook  --key-file ~/keys/id_rsa -e cloud_user=cloud-user  --user cloud-user  -i /home/ayoung/devel/ansible/contrib/inventory/openstack_inventory.py playbooks/jbosseap.yml --limit dev1jboss* -e @~/vault.yml

After working through this, I decided to redo my setup so that the server name was the short version (sso vs sso.awx.devstack) so the host grouping would match what the setup scripts required. I still would like to find a way to set the group information in the OpenStack layer, but it seems like the best bet is to use a hostname regex match in Tower.

Leave a Reply

Your email address will not be published. Required fields are marked *