Puppet Bolt Vault Inventory Plugin

Post image

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

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 privatekey=@bolt_id_rsa

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"]
}

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

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"]

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

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

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

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

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

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

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

You May Also Like