How to Secure Ansible Playbook Credentials using Hashicorp Vault

Isolate any target host’s credentials (hostname, user, password) from Ansible Playbook. And let the playbook retrieve those information from secret management tools (Hashicorp Vault) during targets provisioning.

Sharing is caring!

Overview

When you are using Ansible, there must be a moment which you have stored credentials in your playbook. For that cases, usually we use Ansible Vault to encrypt the credential’s values. It is a very good Ansible feature, so we can keep the values inside a variable file.

However, sometimes it is not enough. Especially in the enterprise, where you have different team between infra, who do provisioning and security team, for managing credentials. For this case, one of the tools out there is Hashicorp Vault

Hashicorp Vault

Hashicorp Vault is a tools for managing secrets and protect sensitive data. You can access the data by using CLI, UI and REST API.

Please note that this article does not discuss how to use Hashicorp Vault in details. I assume you have already had basic knowledge about Hashicorp Vault.

For more information, please visit https://www.vaultproject.io.

Use Case

For this article, I want to simulate creating linux users, with username vault, in two remote machines using Ansible. The challenge is I do not have any credentials information about the remote machines. All the information is stored inside Hashicorp Vault. Ansible will connect to Vault by using TLS authentication mode, and retrieve access token via REST API.

Use case


  1. Ansible asks for an access token to Vault

  2. Vault returns the access token

  3. Ansible asks machine credentials to Vault by using access token

  4. Vault return the stored credentials

  5. Ansible uses the credentials to provision the server via SSH

  6. Server 1 is provisioned

  7. Server 2 is provisioned

Assumptions:

  • Vault is already up and running on address https://127.0.0.1:8200.
  • The remote machines alias inside inventory file areĀ host1 and host2.

Secret Engine and Policy

The secret engine location is under ansible/host1 and ansible/host2.

Please beware that the secret engine location is mapped with the remote machine alias in inventory files.

First, enable the ansible secret engine and populate values inside the engine.

Next create policy for ansible, put it in a file with name ansible.hcl

And stored it into Vault

Certificate

Because we are using TLS authentication method, at first we need to enable it first.

Generate certificate using openssl command

Configure the certificate into Vault

Then stored the certificate into your playbook or you can store anywhere on your machine.

Ansible Playbook

Two main focus in the ansible-playbook are:

site.yml

This file contains the logic how to get access token as well as credentials with the benefit of URI module. The execution is in the local machine. OnceĀ  the credentials are retrieved, then they are stored into dictionary objects, which in this example are dict_host, dict_user and dict_pass.

Next continue to provision the remote servers.

inventory

In the inventory file, put the alias similar with key inside secret engine, which are host1 and host2. Then retrieve the ansible_host, ansible_user and ansible_password by accessing the dictionary objects.

Run It!

Now run the playbook!

Once it finished, it would create a user with username vault inside each server.

Conclusion

In this example, the access token is only valid for 1 hour (because it is default ttl value in my Vault configuration). You can change the ttl value, let say only 15 minutes. Because most of provisioning should be done in a short time. Therefore, we set the token into the short-lived one then will be invalid after 15 minutes. Or, you can set the access token can only be valid after several requests to Vault. Everything depends on your needs.

Also, I only write about retrieving Linux credentials. But it is not limited for that sole purpose. Another case, for instance you need to provision a database server and you need to retrieve the database username and password in order to make first installation (I’m thinking about SYS user for Oracle). Of course you can store those information into Vault as well. And many more.

Lastly, you can check the source code in my github. Have a nice day/night!

Author: ru rocker

I have been a professional software developer since 2004. Java, Python, NodeJS, and Go-lang are my favorite programming languages. I also have an interest in DevOps. I hold professional certifications: SCJP, SCWCD, PSM 1, AWS Solution Architect Associate, and AWS Solution Architect Professional.

Leave a Reply

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