Integrating HashiCorp Vault With Puppet Bolt
Tags: devops, hashicorp, puppet, vault
Published: 2020-07-24 18:28:58

---
title: Integrating HashiCorp Vault With Puppet Bolt
published: true
date: 2019-11-26 21:02:06 UTC
tags: DevOps,HashiCorp,Puppet,Vault
canonical_url: https://www.greenreedtech.com/puppet-bolt-vault-inventory-plugin/
---

In this blog post we'll look at the HashiCorp Vault plugin for Puppet Bolt that enables authentication credentials for Bolt to be retrieved from an instance of HashiCorp Vault. HashiCorp Vault is a secrets management platform that is commonly used to store secrets such as API keys, passwords and SSH private keys. This solution helps to avoid secret sprawl where passwords and credentials are widely distributed across an environment making it difficult to track where they are.

The plugin was added to Puppet Bolt in version 1.28.0 and natively supports <a href="https://www.vaultproject.io/docs/auth/token.html">token</a> and <a href="https://www.vaultproject.io/docs/auth/userpass.html">userpass</a> Vault authentication methods. Documentation for the plugin can be found here - <a href="https://forge.puppet.com/puppetlabs/vault/readme">https://forge.puppet.com/puppetlabs/vault/readme</a>.
<h3>Vault Setup</h3>
We'll configure a development instance of HashiCorp Vault to walk through the plugin's functionality. The following assumes a basic knowledge of how to setup at least a dev instance of HashiCorp Vault. This information can be found on HashiCorp's website if necessary (<a href="https://learn.hashicorp.com/vault">https://learn.hashicorp.com/vault</a>).

<strong>Write the Windows administrator password to Vault.</strong>

We need to write the password for the Windows machine to the secret/credentials/windows path in Vault.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=windows-password.sh %}

<strong>Write the Linux SSH private key to Vault</strong>

We need to write the SSH private key for the Linux machine to the secret/credentials/linux path in Vault. The private key has been saved to a file named bolt_id_rsa which is being uploaded as a secret.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=linux-privatekey.sh %}

<strong>Create a Vault Policy</strong>

We need to create a Vault Policy that allows the token to read the secrets in the "credentials" secret structure but nothing else under the "secret" space. The policy should be saved to a file name bolt-policy.hcl which we'll use in the next command to actually create the policy in Vault.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=bolt-policy.hcl %}

The following command creates a policy named "bolt" using the policy file that was just created in the previous step.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=vault-policy-write-sh %}
<h3>Token Authentication</h3>
HashiCorp Vault supports token authentication that allows a token generated by an existing token or another authentication method to be used for interacting with a Vault instance. When logging into Vault via an authentication method a token is generated which is assigned privileges based upon the policies associated with the token during creation.

<strong>Generate Token</strong>

Logged in with the root token we can generate a token with the bolt policy we created in a previous step associated.

*Logging in with the root token is not recommended for day to day administration in production environments*

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=generate-token.sh %}

The output should be similar to that below and the "token" is what we'll use in our Bolt inventory file to authenticate.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=token-gen-output.sh %}

<strong>Bolt Configuration File</strong>

The Bolt configuration file is used to set the global configuration for Bolt and in this example we're adding the configuration for the Vault plugin to this file. The token has been added in plaintext to the file but we can specify the **"VAULT_TOKEN"** environment variable or use another plugin for encryption such as the <a href="https://puppet.com/docs/bolt/latest/using_plugins.html#ariaid-title15">PKCS7</a> to avoid the token being in plaintext in the Bolt config file.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=bolt-token.yaml %}

&nbsp;

In addition to generating a token using an existing token HashiCorp Vault generates a token upon login when using other authentication methods, such as those covered below.

<strong>Human Interaction</strong>

HashiCorp Vault supports a number of authentication methods that are intended for a human or interactive login. The following methods are commonly utilized but is not a complete list.
<ul>
 	<li>LDAP</li>
 	<li>Okta</li>
 	<li>Radius</li>
 	<li>Github</li>
</ul>
<strong>Machine Interaction</strong>

There is often a need to run automation as part of a pipeline or scheduled task. This means that we can't expect a human to perform a login operation to fetch a token. In this case we need to use one of HashiCorp Vault's authentication methods intended for non-human interaction.

The following authentication methods are intended for non-human authentication.
<ul>
 	<li>AWS</li>
 	<li>Kubernetes</li>
 	<li>TLS</li>
 	<li>Azure</li>
 	<li>AppRole</li>
</ul>
<h3>UserPass Authentication</h3>
In addition to the token authentication method the plugin also supports userpass authentication. HashiCorp Vault supports a userpass authentication method that is a local user database in Vault that utilizes a username and password for authentication.

<strong>Enable UserPass Authentication</strong>

The authentication engine or backend needs to be enabled before we can use that authentication method.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=userpass-enable.sh %}

<strong>Create a user account</strong>

The userpass authentication method has been enabled and now we need to create a user account with a password and associate the Bolt Vault policy.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=userpass-create.sh %}

We can validate that the user was successfully created and that the bolt policy is associated by running the vault login command below, a password prompt will be presented

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=userpass-login.sh %}

Output similar to that shown below will be displayed and we can see that the "bolt" policy is associated with the credentials.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=userpass-login-output.sh %}

<strong>Bolt Configuration File</strong>

The Bolt configuration file is used to set the global configuration for Bolt and in this example we’re adding the configuration for the Vault plugin to this file. The username and password have been added in plaintext to the file. Similar to the token authentication method we can use another plugin for encryption such as the <a href="https://puppet.com/docs/bolt/latest/using_plugins.html#ariaid-title15">PKCS7</a> to avoid the password being in plaintext in the Bolt config file.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=bolt-userpass.yaml %}
<h3>Bolt Inventory File</h3>
With either the authentication method configured for the Vault plugin now we just need to create an inventory file for specifying the path in Vault where Bolt will fetch the secret from.

<strong>Windows</strong>

The Bolt inventory file below is an example of using the plugin to retrieve the password used by Bolt for connecting to Windows nodes via WinRM.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=windows-inventory.yaml %}

With the inventory file created we can run a simple command to check that the plugin is able to fetch the credentials from Vault.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=bolt-windows-command.sh %}

<strong>Linux</strong>

The Bolt inventory file below is an example of using the plugin to retrieve the SSH private key used by Bolt for connecting to Linux nodes via SSH.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=linux-inventory.yaml %}

With the inventory file created we can run a simple command to check that the plugin is able to fetch the credentials from Vault.

{% gist https://gist.github.com/martezr/69b4c5f4ec5a85f372750fc50246b3d3 file=bolt-linux-command.sh %}

The plugin provides the ability to allow Puppet Bolt to offload a critical component of any automation process to a dedicated platform in Vault. This enables a more robust solution for managing secrets in a secure and automated manner.
<h3>References</h3>
Puppet Bolt HashiCorp Vault plugin documentation

<a href="https://forge.puppet.com/puppetlabs/vault/readme">https://forge.puppet.com/puppetlabs/vault/readme</a>

Puppet Bolt Inventory File

<a href="https://puppet.com/docs/bolt/latest/inventory_file_v2.html">https://puppet.com/docs/bolt/latest/inventory_file_v2.html</a>