- Installing Ansible on CentOS 7.7
- Create an Azure Service Principal that we will use to allow Ansible to authenticate to Azure via Dynamic Inventories.
- Set up a basic Azure Dynamic Inventory filtering on “include_vm_resource_groups” to test pinging a VM as well as find out the name Ansible uses to refer to this Virtual Machine in order to capture Ansible hostvars.
- Capture information via the Metadata Instance Service in order to see how Ansible hostvars pulls information from the VM.
- Capture the Ansible Hostvars of an Azure Virtual Machine. These variables will then be used throughout this article series to filter what Virtual Machines we want to target.
- Install Azure CLI
- Deploy a Virtual Machine Scale Set (VMSS) into an existing VNET
- Modify our Azure Dynamic Inventory filtering for “include_vmss_resource_groups” to test connectivity to VMSS Instances (VM Nodes) within the VMSS.
- Install a Second VM
- Configure Tags on VMs in Preparation of using Keyed_Groups
- Using Keyed_Groups to filter on Tags’ Key/Value Pair
- Using Keyed_Groups to filter on OS Type using Jinja2 Standard Dot Notation
- Filter out specific VMs using exclude_host_filters
Part 4
- Using Conditional_Groups to filter on specific criteria
- Using Hostvar_Expressions to make modifications to specific hostvar values
Modifying our Dynamic Inventory File to use Conditional Groups
Let’s say we have a need to make changes to all of our SQL Servers or all of our Web Servers. Is there an identifying factor in hostvars for all of our SQL Servers and all of our Web Servers? How can we categorize these servers into groups so we can run ansible groupname on them and have them target all of our SQL Servers, our Web Servers, etc…
That is where conditional_groups in the Dynamic Inventory File come into play.
Let’s pretend that any server with the name vmblog in it is a database server. Let’s modify the Dynamic Inventory File to have the following:
plugin: azure_rm
# places a host in the named group if the associated condition evaluates to true
conditional_groups:
# if the VM's "name" variable contains "dbserver", it will be placed in the 'db_hosts' group
db_hosts: "'vmblog' in name"
auth_source: auto
It’s fairly simple and straightforward.
Modifying our Dynamic Inventory File to use Hostvar Expressions
Hostvar Expressions let’s you modify a hostvar value using a static value or a custom Jinja2 value. For example, if we wanted to change our vmblog01. For example, if you want to change the ansible_user to ‘newuser, you can specify the following
"ansible_user": "newuser"
There are certain cases where we may want to change a value on a specific VM for a hostvar such as the ansible_host hostvar. For example, if our machine uses multiple public IPs and we want to set the ansible_host value to a different public IP. By default, Ansible sets ansible_host to the first public IP address found (preferring the primary NIC). If no public IPs are found, the first private IP (also preferring the primary NIC).
We have two Public IPs on vmblog01.
If we look at the hostvars for vmblog01 that is in Part 1, we can see the ansible_host hostvar is as follows:
"ansible_host": "23.100.235.135"
Let’s modify our Dynamic Inventory File to filter just on vmblog01 and to change the ansible_host value to become 52.252.241.26.
plugin: azure_rm
# places a host in the named group if the associated condition evaluates to true
conditional_groups:
# if the VM's "name" variable contains "vmblog01", it will be placed in the 'vmblog01' group
vmblog01: "'vmblog01' in name"
# adds variables to each host found by this inventory plugin, whose values are the result of the associated expression
hostvar_expressions:
my_host_var:
# A statically-valued expression has to be both single and double-quoted, or use escaped quotes, since the outer
# layer of quotes will be consumed by YAML. Without the second set of quotes, it interprets 'staticvalue' as a
# variable instead of a string literal.
ansible_host: "'52.252.241.26'"
auth_source: auto
Let’s execute the following command. Since we’re calling the Dynamic Inventory File, the ansible_host value will be changed and the debug output will show us the new value. Since we have a conditional_group called vmblog01 that filters on VMs that have vmblog01 in the name, our change will only be made on the vmblog01 VM.
ansible vmblog01 -m debug -a 'var=hostvars' -i ansible_azure_rm.yml
Here’s the response just from vmblog01. If you look at ansible_host, we can see it is no longer 23.100.235.135. Rather, it is now 52.252.241.26.
"ansible_host": "52.252.241.26",
hostvar_expressions does fully support Jinja2 custom expressions. So rather than using a static value, you can use something else such as:
(hostvar1 + hostvar2)
Thanks for reading all the way to the end. Hopefully you found this valuable. And if you have any questions, as always, feel free to comment.
Michael Chambers says
Brilliant article – extremely helpful. I myself was also looking at finding a means to limit playbooks on Azure key values and this is exactly what was needed.
Raghav says
Hey,
Thanks for this wonderful article. This explains how to execute ansible ad-hoc command. Can you please advise on how to execute “ansible-playbook” by using keyed groups ?
Elan Shudnow says
Thanks for the nice comment on the article. When using ansible-playbook, you would do the following based on how I structured Part 2:
ansible-playbook -i ./ansible_azure_rm.yml playbookname.yml –limit=tag_Owner_John