Ansible tips’n’tricks: using the OCI Dynamic Inventory Plugin in playbooks

After having covered how to configure the Ansible Dynamic Inventory Plugin for Oracle Cloud Infrastructure (OCI) in the previous posts now it’s time to get it to work with my simple-app cloud application. Before I go into more detail, I’d like to add the usual caveat first.

Caveat

As I said in the previous post, the Dynamic Inventory Plugin is a great time saver, especially when used as part of build pipelines. However, as with anything that’s misconfigured and doesn’t adhere to best practices, there is a risk associated. You might run playbooks against hosts you didn’t intend to. Ensure you have proper Identity and Access (IAM) policies in place, and use the principle of last privilege throughout. And use tags to filter hosts, as you see in this and the previous example. And finally, use the ansible toolset (ansible-inventory fwiw) to validate the hosts you target.

Using the Dynamic Inventory Plugin

The Dynamic Inventory Plugin nicely prints all the VMs in my configuration, broken down by tag. If the plugin returns fewer hosts than expected, your configuration might need tweaking as I explained in this post.

[opc@supersecureVM ansible]$ ansible-inventory -vi ougdemo-compartment.oci.yml --graph
@all:
  |--@IHsr_EU-FRANKFURT-1-AD-2:
  |  |--appserver1.app.simpleapp.oraclevcn.com
  |  |--bastion1.bastion.simpleapp.oraclevcn.com
  |--@IHsr_EU-FRANKFURT-1-AD-3:
  |  |--appserver2.app.simpleapp.oraclevcn.com
  |--@all_hosts:
  |  |--appserver1.app.simpleapp.oraclevcn.com
  |  |--appserver2.app.simpleapp.oraclevcn.com
  |  |--bastion1.bastion.simpleapp.oraclevcn.com
  |--@ougdemo-department:
  |  |--appserver1.app.simpleapp.oraclevcn.com
  |  |--appserver2.app.simpleapp.oraclevcn.com
  |  |--bastion1.bastion.simpleapp.oraclevcn.com
  |--@project#name=simple-app:
  |  |--appserver1.app.simpleapp.oraclevcn.com
  |  |--appserver2.app.simpleapp.oraclevcn.com
  |  |--bastion1.bastion.simpleapp.oraclevcn.com
  |--@region_eu-frankfurt-1:
  |  |--appserver1.app.simpleapp.oraclevcn.com
  |  |--appserver2.app.simpleapp.oraclevcn.com
  |  |--bastion1.bastion.simpleapp.oraclevcn.com
  |--@tag_role=appserver:
  |  |--appserver1.app.simpleapp.oraclevcn.com
  |  |--appserver2.app.simpleapp.oraclevcn.com
  |--@tag_role=bastionhost:
  |  |--bastion1.bastion.simpleapp.oraclevcn.com
  |--@ungrouped: 

As you can see there are plenty of tags assigned. Tagging is one of the most important tasks in the cloud, as it is the most convenient way to identify resources.

The logical next step is to make use of that detail! I used free form tags to identify my bastion host and the app servers. So how can I target them with my playbook?

Saying hello to both app servers

I wrote a little playbook as a quick example on how I can use the free form tags to address the app servers. I guess that’s the bare minimum example I can get away with.

[opc@supersecureVM ansible]$ cat hello-appservers.yml 
- hosts: tag_role=appserver
  name: say hello to app servers
  tasks:
  - name: say hello
    debug:
      msg: Hello from {{ ansible_hostname }}
[opc@supersecureVM ansible]$  

You call it just as you would call any other Ansible playbook, substituting the static inventory with the Dynamic Inventory. As you can see the app servers are referenced by their role, indicated by the tags assigned.

[opc@supersecureVM ansible]$ ansible-playbook -i ougdemo-compartment.oci.yml hello-appservers.yml 

[... output showing the inventory is build skipped ...]

PLAY [say hello to app servers] *************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************
ok: [appserver1.app.simpleapp.oraclevcn.com]
ok: [appserver2.app.simpleapp.oraclevcn.com]

TASK [say hello] ****************************************************************************************************************
ok: [appserver1.app.simpleapp.oraclevcn.com] => {}

MSG:

Hello from appserver1
ok: [appserver2.app.simpleapp.oraclevcn.com] => {}

MSG:

Hello from appserver2

PLAY RECAP **********************************************************************************************************************
appserver1.app.simpleapp.oraclevcn.com : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
appserver2.app.simpleapp.oraclevcn.com : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[opc@supersecureVM ansible]$  

Happy automating!