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 token and userpass Vault authentication methods. Documentation for the plugin can be found here – https://forge.puppet.com/puppetlabs/vault/readme.

Vault Setup

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 (https://learn.hashicorp.com/vault).

Write the Windows administrator password to Vault.

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

vault kv put secret/credentials/windows password=Puppet123

view raw
windows-password.sh
hosted with ❤ by GitHub

Write the Linux SSH private key to Vault

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.

vault kv put secret/credentials/linux [email protected]_id_rsa

view raw
linux-privatekey.sh
hosted with ❤ by GitHub

Create a Vault Policy

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.

path "secret/data/credentials/*" {
capabilities = ["read"]
}
path "secret/metadata/credentials/*" {
capabilities = ["list","read"]
}

view raw
bolt-policy.hcl
hosted with ❤ by GitHub

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

vault policy write bolt bolt-policy.hcl

Token Authentication

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.

Generate Token

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

vault token create -policy=bolt

view raw
generate-token.sh
hosted with ❤ by GitHub

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

Key Value
— —–
token s.3649w1Fh80RtwSteoDzWuDUi
token_accessor Ki4onGqPfwdnMVJQFX40ddqZ
token_duration 768h
token_renewable true
token_policies ["bolt" "default"]
identity_policies []
policies ["bolt" "default"]

view raw
token-gen-output.sh
hosted with ❤ by GitHub

Bolt Configuration File

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 PKCS7 to avoid the token being in plaintext in the Bolt config file.

modulepath: "~/.puppetlabs/bolt-code/modules:~/.puppetlabs/bolt-code/site-modules"
concurrency: 10
format: human
winrm:
ssl: false
ssh:
host-key-check: false
plugins:
vault:
server_url: http://127.0.0.1:8200
auth:
method: token
token: s.3649w1Fh80RtwSteoDzWuDUi

view raw
bolt-token.yaml
hosted with ❤ by GitHub

 

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.

Human Interaction

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.

  • LDAP
  • Okta
  • Radius
  • Github

Machine Interaction

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.

  • AWS
  • Kubernetes
  • TLS
  • Azure
  • AppRole

UserPass Authentication

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.

Enable UserPass Authentication

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

vault auth enable userpass

view raw
userpass-enable.sh
hosted with ❤ by GitHub

Create a user account

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.

vault write auth/userpass/users/puppetbolt password=Password123 policies=bolt

view raw
userpass-create.sh
hosted with ❤ by GitHub

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

vault login -method=userpass username=puppetbolt

view raw
userpass-login.sh
hosted with ❤ by GitHub

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

Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
— —–
token s.Xd4v1qoCtnKEnDHjzYTRm1KC
token_accessor 1ZRZUUYfWRJOGNBj8qnbRGvf
token_duration 768h
token_renewable true
token_policies ["bolt" "default"]
identity_policies []
policies ["bolt" "default"]
token_meta_username puppetbolt

Bolt Configuration File

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 PKCS7 to avoid the password being in plaintext in the Bolt config file.

modulepath: "~/.puppetlabs/bolt-code/modules:~/.puppetlabs/bolt-code/site-modules"
concurrency: 10
format: human
winrm:
ssl: false
ssh:
host-key-check: false
plugins:
vault:
server_url: http://127.0.0.1:8200
auth:
method: userpass
user: puppetbolt
pass: Password123

view raw
bolt-userpass.yaml
hosted with ❤ by GitHub

Bolt Inventory File

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.

Windows

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.

version: 2
targets:
uri: winnode1
config:
transport: winrm
winrm:
user: administrator
password:
_plugin: vault
path: secret/credentials/windows
field: password
version: 2

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

bolt plan run facts -i inventory.yaml –targets=winnode1

Linux

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.

version: 2
targets:
uri: linuxnode1
config:
transport: ssh
ssh:
user: root
private-key:
key-data:
_plugin: vault
path: secret/credentials/linux
field: privatekey
version: 2

view raw
linux-inventory.yaml
hosted with ❤ by GitHub

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

bolt plan run facts -i inventory.yaml –targets=linuxnode1

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.

References

Puppet Bolt HashiCorp Vault plugin documentation

https://forge.puppet.com/puppetlabs/vault/readme

Puppet Bolt Inventory File

https://puppet.com/docs/bolt/latest/inventory_file_v2.html