Hello again, Chris Wallen here and in this post, I’m going to show you how to use a managed identity to manage resources using Azure dynamic inventory with Ansible. If you’re not familiar with managed identities, see this overview of managed identities for Azure resources. Basically, they just provide a method of authenticating to Azure without the need to store credentials in code or on any local resource. Now, before we get into the technical details, let’s go over the different sources of Azure credentials that Ansible can use to authenticate when using dynamic inventory:
When using dynamic inventory, you can use any of the following methods to provide your Azure credentials to Ansible
Obviously, the first option is the least secure as your credentials are stored in a flat-file that could be read by anyone with access. The second option is more secure; however, it requires you to either create more automation to set the environment variables for the ansible user, permanently set them in the user profile, which requires you again to store them in plain text, or set the variables manually. The third option is also secure, but does not lend itself to automation as you have to manually sign in to the CLI each time you want to use dynamic inventory. This just leaves us with option 4. This is the most secure as you’re not required to store credentials anywhere in code or on the local machine nor do you have to take any manual steps to authenticate. The only requirement is that your Ansible control server must be running in Azure. Once the managed identity is assigned, you can easily control the level of access to resources by using role-based access. Ok, now that we have that out of the way, let’s talk about the prerequisites.
Now, on to the dynamic inventory configuration. First, we’ll need a managed identity to assign to our Ansible control server.
You can use either a system-assigned or user-assigned identity. To decide which type is best for you, see the differences between a system-assigned and user-assigned managed identity. Regardless of which type you choose; we’ll need to first create the identity using Azure CLI in Azure Cloud Shell.
NOTE: If you already have an identity created, skip to the section titled “Assign RBAC rights to the managed identity”
To create a new user-assigned identity, run the below command, replacing RG-NAME with the name of the resource group for the identity, and IDENTITY-NAME with the name of the identity.
az identity create -g RG-NAME -n IDENTITY-NAME
For a system-assigned identity, run the following command, where RG-NAME is the name of the resource group and VMNAME is the name of the Ansible control server
az vm identity assign -g RG -n VMNAME
Now that we have the identity created, we need to assign it rights to Azure resources. I chose to give mine Reader rights on the resource group that I’ll be using for dynamic inventory. If you want to use multiple resource groups for your inventory, you’ll need to follow this procedure for each one.
To assign Reader for a resource group to a user-assigned identity, run the below commands in the Cloud Shell. To run the commands, you’ll need to replace IDENTITY-NAME with the name of the managed identity you created in the previous step and replace the scope with the resource id of the resource group to assign the rights to (found under properties blade of the resource group)
spID=$(az identity show -n IDENTITY-NAME -g RG --query '[principalId]' -o tsv)
az role assignment create --assignee $spID --role ‘Reader’ --scope /subscriptions/SUBID/resourceGroups/RG-NAME
Example:
az role assignment create --assignee $spID --role ‘Reader’ --scope /subscriptions/ fddda745-b9e7-43e4-9a2a-45fa890210ed /resourceGroups/myDemoRG
To assign Reader rights for a resource group to a system-assigned identity, run the following commands in the Cloud Shell. To run the commands, replace ANSIBLE-VM with the name of the Ansible VM as it appears in the portal and replace the scope with the resource id of the resource group to assign the rights to (found under properties blade of the resource group
spID=$(az resource list -n VM-NAME --query [*].identity.principalId --out tsv)
az role assignment create --assignee $spID --role ‘Reader’ --scope /subscriptions/SUBID/resourceGroups/RG-NAME
Example:
az role assignment create --assignee $spID --role ‘Reader’ --scope /subscriptions/ fddda745-b9e7-43e4-9a2a-45fa890210ed /resourceGroups/myDemoRG
With Ansible 2.8 and later, dynamic inventory is handled through the azure_rm plugin. To configure the VMs for dynamic inventory, I used this tutorial. I’ll summarize the steps below:
Add a tag to the virtual machines you want to inventory. To create the tag, run the below command. Make sure to replace RG-NAME and VM-NAME with values appropriate for your environment.
az vm update \
--resource-group RG-NAME \
--name VM-NAME \
--set tags.mytag=demo
Use the steps below to setup the Ansible directory and create the inventory file
mkdir -p ~/ansible/inventory
cd ~/ansible/inventory
plugin: azure_rm
include_vm_resource_groups:
- RG-NAME
auth_source: msi
keyed_groups:
- prefix: mytestgroup
key: tags.mytag | default('none')
exclude_host_filters:
- powerstate != 'running'
Before moving on to the next section, let’s take a second and go over the inventory file to make sure all of the parameters are clear.
Now that we have everything setup, it’s time to test our configuration. In order to do so, let’s run an ad-hoc command against the inventory file:
ansible mytestgroup_demo -m ping -i ~/ansible/inventory/demo_azure_rm.yaml
You should see output similar to the following:
NOTE: The ping module will only work against Linux VMs. If testing against Windows, use the win_ping module.
And that’s it. You now have Azure dynamic inventory setup in Ansible. In my next post, I’ll take this a step further and show how you can use dynamic inventory to apply DSC configuration to Windows VMs in Azure.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.