Earlier in the year, I wrote about how to create a Python virtual environment on Ansible AWX to run the HashiCorp lookup module.
The last task is to create the credentials to support the Vault lookup, followed by configuring the necessary variables in the inventory.
HashiCorp Vault
Before we can configure our credentials in AWX, we first need to create them in HashiCorp Vault.
To enable AWX to communicate with Vault we will be using the AppRole authentication method.
Login into Vault from the command line. If you haven’t already enabled AppRoles, you can do so by using:
vault auth enable approle
Create a simple policy to allow AWX to query our KV store (substitute accordingly):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
path "credentials/computers/production/*" { | |
capabilities = [ "read" ] | |
} |
Create a new policy in Vault based on the above file:
vault policy write acl_sa_ansible ./acl_sa_ansible.hcl
Create a role which will have the default policy and the one created previously attached (substitute accordingly):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vault write auth/approle/role/sa_ansible \ | |
token_num_uses=0 \ | |
token_ttl=0m \ | |
secret_id_num_uses=0 \ | |
token_no_default_policy=false \ | |
token_policies="acl_sa_ansible" |
Once the role has been created, retrieve the role ID:
vault read auth/approle/role/sa_ansible/role-id
Now create a secret ID:
vault write -f auth/approle/role/sa_ansible/secret-id
Take a note of both values as these will be needed in the next step.
Credentials
Now we have our created our virtual environment and configured it in the system settings, we need to create our HashiCorp credentials.
To do this, login to AWX , select the Credential Types from the left-hand menu and create a new one. Give it a name and use the following input configuration:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fields: | |
– id: vault_server | |
type: string | |
label: URL for Vault Server | |
– id: vault_role_id | |
type: string | |
label: Vault AppRole ID | |
– id: vault_secret_id | |
type: string | |
label: Vault Secret ID | |
secret: true | |
required: | |
– vault_server | |
– vault_role_id | |
– vault_secret_id |
Use the following for the injector configuration:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
env: | |
VAULT_ADDR: '{{ vault_server }}' | |
VAULT_AUTH_METHOD: approle | |
VAULT_ROLE_ID: '{{ vault_role_id }}' | |
VAULT_SECRET_ID: '{{ vault_secret_id }}' |
When complete click Save.
Again, on the left-hand menu, create a new credential and set the type to the one you created above. Give it a name, select the organization, and enter the Vault address, role ID and secret ID. Finally, click Save.
Inventory
The last piece of the puzzle is to enable the actual lookup. Our Vault KV store is configured with the following path:
credentials/computers/production/{{ inventory_hostname }}
Under Production, there is a secret for each Ansible host, and each secret has a key for the Administrator/root username and password.
Create an inventory and add some hosts. You may find it easier to group these.
Either at the individual host or group level, add the following variable string to enable lookups to HashiCorp Vault (substitute accordingly):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
— | |
ansible_become_password: "{{ lookup('hashi_vault', 'secret=credentials/computers/production/{{ inventory_hostname }}:Password')}}" | |
ansible_become_method: su |
I have a group for my Linux hosts and have applied it there.
To verify it works correctly create a template in AWX using the following playbook:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
— | |
– hosts: Linux | |
gather_facts: true | |
tasks: | |
– name: Upgrade all yum packages | |
yum: | |
name: "*" | |
state: latest | |
become: yes |
Important: as well as selecting the machine credential you normally connect to machines with, you also need to select the HashiCorp credential you created above:
Please note: set your template to Check unless you want all your packages to update!
Your template (playbook) will now run, and when the time comes to “become” root, AWX will reach out to Vault to retrieve the root credential and proceed.
Happy automating!!