Giter VIP home page Giter VIP logo

puppet-vault_lookup's Introduction

vault_lookup

Build Status Release Puppet Forge Puppet Forge - downloads Puppet Forge - endorsement Puppet Forge - scores puppetmodule.info docs Apache-2 License

Module to integrate Puppet 6 (and newer) and Puppet Enterprise 2019 (and newer) agents with Hashicorp Vault.

Table of Contents

  1. Description
  2. Requirements
  3. Usage, Configuration, and Examples
  4. Authentication Methods

Description

For Puppet 6+ or Puppet Enterprise 2019+ users wanting to use secrets from Hashicorp Vault on their Puppet agents, this Puppet module provides the vault_lookup::lookup() function.

When used with Puppet 6's Deferred type, the function allows agents to retrieve secrets from Vault when a catalog is applied rather than compiled. In this way, the secret data is not embedded in the catalog and the Puppetserver does not need permissions to read all your Vault secrets.

Requirements

This modules assumes the following:

  1. Puppet 6+
  2. An existing Vault infrastructure

The vault_lookup::lookup() function is expected to be run with the Deferred type; as such, Puppet 6 or later is required.

And as this function is meant to read secrets from Vault, an existing Vault infrastructure is assumed to be up and reachable by your Puppet agents.

Usage

Install this module as you would in any other; the necessary code will be distributed to Puppet agents via pluginsync.

In your manifests, call the vault_lookup::lookup() function using the Deferred type. For example:

$d = Deferred('vault_lookup::lookup', ["secret/test", 'https://vault.hostname:8200'])

node default {
  notify { example :
    message => $d
  }
}

The lookup function will be run on the agent and the value of $d will be resolved when the catalog is applied. This will make a call to https://vault.hostname:8200/v1/secret/test and wrap the result in Puppet's Sensitive type, which prevents the value from being logged.

You can also choose not to specify the Vault URL, and then Puppet will use the VAULT_ADDR environment variable. This will be either set on the command line, or set in the service config file for Puppet, on Debian /etc/default/puppet, on RedHat /etc/sysconfig/puppet:

$d = Deferred('vault_lookup::lookup', ["secret/test"])

node default {
  notify { example :
    message => $d
  }
}

Configuring the Vault lookup

The lookup done by vault_lookup::lookup() can be configured in three ways: positional arguments, a hash of options, and/or environment variables.

In all cases, the path to the secret is the first positional argument and is required. All other arguments are optional. Arguments in [square brackets] below are optional.

Positional Arguments

vault_lookup::lookup( <path>, [<vault_addr>], [<cert_path_segment>], [<cert_role>], [<namespace>], [<field>], [<auth_method>], [<role_id>], [<secret_id>], [<approle_path_segment>], [<agent_sink_file>] )

Options Hash

vault_lookup::lookup( <path>, [<options_hash>] )

Environment Variables

Not all options can be set with environment variables. Use the table below to find the matching env var, if available. Also note that environment variables are only used if the option is not supplied to the function.

Option Name Environment Variable
vault_addr VAULT_ADDR
cert_path_segment ----
cert_role ----
namespace VAULT_NAMESPACE
field ----
auth_method VAULT_AUTH_METHOD
role_id VAULT_ROLE_ID
secret_id VAULT_SECRET_ID
approle_path_segment ----
agent_sink_file VAULT_AGENT_SINK_FILE

Usage Examples

Here are some examples of each method:

# Positional arguments

## Using the default 'cert' auth method.
$data_1a = vault_lookup::lookup('secret/db/password', 'https://vault.corp.net:8200')

## Using the 'approle' auth method.
$data_2a = vault_lookup::lookup('secret/db/blah', 'https://vault.corp.net:8200', undef, undef, undef, undef, 'approle', 'team_a', 'abcd1234!@#')

## Pulling out a specific field.
$password = vault_lookup::lookup('secret/test', 'http://vault.corp.net:8200', undef, undef, undef, 'password')
# Options hash

## Using the default 'cert' auth method.
$data_1b = vault_lookup::lookup('secret/db/password', { 'vault_addr' => 'https://vault.corp.net:8200' })

## Using the 'approle' auth method.
$data_2b = vault_lookup::lookup('secret/db/blah', {
  'vault_addr'  => 'https://vault.corp.net:8200',
  'auth_method' => 'approle',
  'role_id'     => 'team_a',
  'secret_id'   => 'abcd1234!@#',
})

# Using 'field' to pull out a specific field from the data.
$password = vault_lookup::lookup('secret/test', {'vault_addr' => 'http://127.0.0.1:8200', 'field' => 'password'})

# Using Deferred is simpler with the options hash.
$password_deferred = Deferred('vault_lookup::lookup', ["secret/test", {
  vault_addr => 'http://127.0.0.1:8200',
  field      => 'password',
}])

A note about caching

The vault_lookup::lookup() function caches the result of a lookup and will use that cached result for the life of the catalog application (when using Deferred) or catalog compilation (when not using Deferred).

Looked up values are cached based on a combination of their:

  • Path in the Vault URI
  • Vault Address
  • Namespace
  • Field

This means that you can call vault_lookup::lookup() multiple times for the same piece of data or refer to the same Deferred value multiple times and there will only be a single fetch from Vault. This helps to reduce the amount of back-and-forth network traffic to your Vault cluster.

For example, in the code below, due to caching, the secret/db/password value is only looked up once even though the function is called twice:

# Wrap the function in Deferred, and save it to a variable.
#
# Since the path, vault_addr, and namespace don't change, only one Vault lookup
# will be made regardless of how many times the $db_password variable is used.
#
$db_password = Deferred('vault_lookup::lookup', [
  'secret/db/password',
  {'vault_addr' => 'https://vault.corp.net:8200'},
])

# Call the deferred function once.
file { '/etc/db.conf':
  ensure  => file,
  content => $db_password,
}

# Call the deferred function twice.
notify { 'show the DB password':
  message => $db_password,
}

But if the path, the Vault address, or the namespace change, a new lookup to Vault will happen. For example, in the code below, even though the path is the same in both of these lookups (secret/db/password), the namespace is different, so a separate lookup will be made rather than the cached value from the first lookup of secret/db/password being used.

# Fetch a value from Vault without using a namespace.
$db_password = Deferred('vault_lookup::lookup', [
  'secret/db/password',
  {'vault_addr' => 'https://vault.corp.net:8200'},
])

# Fetch a value from Vault in the 'dev' namespace.
$db_password_namespaced = Deferred('vault_lookup::lookup', [
  'secret/db/password',
  {'vault_addr' => 'https://vault.corp.net:8200', 'namespace' => 'dev'},
])

file { '/etc/db.conf':
  ensure  => file,
  content => $db_password,
}

notify { 'show the dev namespace DB password':
  message => $db_password_namespaced,
}

A note about spec testing Puppet code that uses this function

When spec testing Puppet code that uses the vault_lookup::lookup() function, you'll probably want to stub the function so that it doesn't hit your real Vault servers. Below is an example of how to do that. This is particularly useful when spec testing a class or define that defers the function call.

Two things that will need to be configured are 1) a require_relative of the internal puppet_x module. Note that this assumes you're pulling the module down into a spec/fixtures/ directory.

require_relative '../fixtures/modules/vault_lookup/lib/puppet_x/vault_lookup/lookup'

and 2) a stub on the PuppetX::VaultLookup::Lookup class's :lookup method:

before(:each) do
  allow(PuppetX::VaultLookup::Lookup).to receive(:lookup)
    .and_return(Puppet::Pops::Types::PSensitiveType::Sensitive.new('hello world'))
end

Here's a complete example:

require 'spec_helper'
require_relative '../fixtures/modules/vault_lookup/lib/puppet_x/vault_lookup/lookup'

describe 'some::class' do
  on_supported_os.each do |os, os_facts|
    context "on #{os}" do
      let(:facts) { os_facts }

      before(:each) do
        allow(PuppetX::VaultLookup::Lookup).to receive(:lookup)
          .and_return(sensitive('hello world'))
      end

      context 'with all defaults' do
        it { is_expected.to compile }
        it { is_expected.to contain_file('/etc/credentials.txt').with_content(sensitive('hello world')) }
      end
    end
  end
end

Authentication Methods

The vault_lookup::lookup() function can authenticate to Vault in a number of ways. This table shows the currently supported auth_method types:

auth_method Description
cert (this is the default) Uses the Puppet agent's certificate via the TLS Certificates auth method.
approle Uses the AppRole auth method.
agent Uses a local Vault Agent's auto-auth token and caching proxy.
agent_sink Uses a local Vault Agent's auto-auth file sink.

Puppetserver CA and agent certificates

The vault_lookup::lookup() function by default will use the Puppet agent's certificates to authenticate to the Vault server. This means that before any agents contact a Vault server, you must configure the Vault server with the Puppet Server's CA certificate, and Vault must be part of the same certificate infrastructure.

  1. Set up Vault using Puppet certs (if not already set up this way). If the Vault host has a Puppet agent on it then you can just its existing host certificates. Otherwise generate a new certificate with puppetserver ca and copy the files.

    $ puppetserver ca generate --certname my-vault.my-domain.me
    

    In the Vault listener configuration, set tls_client_ca_file as the Puppet CA cert, tls_cert_file as the agent's or generated certificate, and tls_key_file as the agent's or generated private key.

  2. Enable the cert auth backend in Vault.

    $ vault auth enable cert
    
  3. Upload the Puppet Server CA certificate to Vault. After cert auth has been enabled for Vault, upload the CA certificate from your Puppet Server to Vault, and add it as a trusted certificate.

    $ vault write auth/cert/certs/puppetserver \
        display_name=puppet \
        policies=prod,test \
        certificate=@/path/to/puppetserver/ca.pem \
        ttl=3600
    

Once the certificate has been uploaded, any Puppet agent with a signed certificate will be able to authenticate with Vault.

AppRole

vault:vault_lookup() can also use AppRole authentication to authenticate against Vault with a valid role_id and secret_id. See The Approle Vault Documentation for detailed explanations of creating and obtaining the security credentials. You will need the Role ID (non sensitive) and the Secret ID (sensitive!). The Secret ID can be provided as an argument to the vault:vault_lookup() function but it is recommended to pass this as an environment variable and not bake this into code.

Example:

$ vault read auth/approle/role/puppet/role-id
Key        Value
---        -----
role_id    XXXXX-XXXX-XXX-XX-XXXXXXXXXX
# vault write -f auth/approle/role/puppet/secret-id
Key                   Value
---                   -----
secret_id             YYYYY-YYYY-YYY-YY-YYYYYYYYYYY
secret_id_accessor    ZZZZZ-ZZZZZZ-ZZZZZZ-ZZZZZZZZ-ZZZZ
secret_id_ttl         0s

In order to use the AppRole auth method, either set the VAULT_AUTH_METHOD environment variable on the Puppet process to approle or set the auth_method option to approle when calling the function:

export VAULT_AUTH_METHOD=approle
export VAULT_ROLE_ID=XXXXX-XXXX-XXX-XX-XXXXXXXXXX
export VAULT_SECRET_ID=YYYYY-YYYY-YYY-YY-YYYYYYYYYYY

Vault Agent: auto-auth token

This method of authentication relies on a local Vault Agent running on the Puppet agent host. The Vault Agent handles authenticating to your Vault server, and the vault_lookup::lookup() function just needs to make requests through the local Vault Agent's caching proxy. The Vault Agent in this scenario must be using Auto Auth, have Caching enabled, and have use_auto_auth_token set to true.

https://developer.hashicorp.com/vault/docs/agent/caching#using-auto-auth-token

An example Vault Agent config for this scenario is shown below:

vault {
  address = "https://vault.corp.net:8200"
}

listener "tcp" {
  address = "127.0.0.1:8100"
  tls_disable = true
}

auto_auth {
  # Some type of auto_auth configuration from:
  # https://developer.hashicorp.com/vault/docs/agent/autoauth
}

cache {
  use_auto_auth_token = true
}

And here's how the vault_lookup::lookup() function can be used to talk to the local Vault agent and use its token for authentication:

# Talk to the local Vault Agent that has "use_auto_auth_token = true"
$data = Deferred('vault_lookup::lookup', ["secret/test", {
  vault_addr  => 'http://127.0.0.1:8200',
  auth_method => 'agent',
  field       => 'password',
}])

file { '/tmp/secret_data.txt':
  ensure  => file,
  owner   => 'app',
  group   => 'app',
  mode    => '0440',
  content => $data,
}

A benefit of this method is that is uses the Vault Agent's cached token rather than generating a new token for each call of the function. This reduces the load on your Vault servers as token generation can be an expensive operation.

Vault Agent: auto-auth file sink

This method of authentication relies on a local Vault Agent running on the Puppet agent host. The Vault Agent handles authenticating to your Vault server, and the vault_lookup::lookup() function reads the cached token from a sink file managed by the Vault Agent. Optionally, the lookup could also talk through your Vault Agent's caching proxy if enabled.

The Vault Agent in this scenario must be using Auto Auth and an unencrypted, non-response-wrapped File Sink for the token.

https://developer.hashicorp.com/vault/docs/agent/autoauth/sinks/file

An example Vault Agent config for this scenario is shown below:

vault {
  address = "https://vault.corp.net:8200"
}

# The listener is optional here, but could be used for the 'vault_addr' in
# the vault_lookup::lookup() Puppet function.
listener "tcp" {
  address     = "127.0.0.1:8100"
  tls_disable = true
}

auto_auth {
  # Some type of auto_auth method from:
  # https://developer.hashicorp.com/vault/docs/agent/autoauth/methods
  method { }

  sink {
    type = "file"
    config = {
      path = "/path/to/vault-token
    }
  }
}

And here's how the vault_lookup::lookup() function can be configured to use the token from the auto-auth file sink for authentication:

# Use the token from the local Vault Agent's auto-auth file sink.
$data = Deferred('vault_lookup::lookup', ["secret/test", {
  # This doesn't have to be the local Vault agent's proxy, but using it can
  # provide additional caching.
  vault_addr      => 'http://127.0.0.1:8200',
  auth_method     => 'agent_sink',
  agent_sink_file => '/path/to/vault-token',
  field           => 'password',
}])

file { '/tmp/secret_data.txt':
  ensure  => file,
  owner   => 'app',
  group   => 'app',
  mode    => '0440',
  content => $data,
}

A benefit of this method is that is uses the Vault Agent's cached token rather than generating a new token for each call of the function. This reduces the load on your Vault servers as token generation can be an expensive operation.

puppet-vault_lookup's People

Contributors

augustin-fl avatar b4ldr avatar bastelfreak avatar binford2k avatar crayfishx avatar ekohl avatar firstnevyn avatar ghoneycutt avatar natemccurdy avatar pcarlisle avatar petems avatar phaedriel avatar root-expert avatar rwaffen avatar smortex avatar treydock avatar turbodog avatar tvpartytonight avatar zilchms avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

puppet-vault_lookup's Issues

Contact Vault with Self-signed CA

Hello,

First of all, thanks for the module.

I'm trying to make this module work with a Vault Cluster exposing port 8200 with a Self-signed CA .

For the Deferred mode, It work after modifying the puppet.conf of the agent , by adding localcacert pointing to my CA, in the main section.

But for the "Puppet server mode" (without Deferred), (which I need because the configuration file that I want to deploy is a ERB template and the Deferred seem not work in this mode because its created on the server side.)

It give us Java errors :

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I tried adding the CA and even the vault node certificate in the Java Keystore, but it seem ignored. (after server restart)

Any feedback on this ?

I read that we need to use puppet'CA, but in my case, we have a specific CA different from the puppet one, and have to use it.

Optionally prevent vault lookup from raising exceptions

If the lookup function throws an exception when used within an agent-side function (Deferred type), the whole catalog application will fail. This may not always be desirable, so we should allow the user to pass a flag disabling exceptions. When exceptions are disabled, the lookup function should log the error and return nil, instead of throwing.

Disable Cache

Is it possible to disable the check with a new key?

Scenario: Function is using cached results because cache_hash didn't change, which is correct, but in vault the password was changed. Since the field name hasn't changed, lookup is still using the cached key.

Can't load environment variables from /etc/sysconfig/puppet

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: puppetserver version: 7.13.0
  • Distribution: Centos9

How to reproduce (e.g Puppet code you use)

I've happened the following lines in /etc/sysconfig/puppet on the puppet server
VAULT_ADDR=https://xxxx:8200/
VAULT_NAMESPACE=admin/puppet
VAULT_AUTH_METHOD=approle
VAULT_ROLE_ID=xxxxxx..xxxx
VAULT_SECRET_ID=xxxx..xxx

What are you seeing

The module does not load the environment variable.

What behaviour did you expect instead

For the module to load these environment variables

Features: Token caching and rate-limit

Hello,

I'd like to start by saying thank you for this Puppet function.
It's really useful to integrate easily with Vault without needing to deploy additional tools like Vault agent etc...

We plan on deploying this function and use it on a fairly large scale.
Thus I studied the code quite thoroughly.
I noticed some features that could be added and about which I'd like your opinion.
I'm happy to contribute if you feel these ideas are useful !

Reuse Vault token and handle lifecycle of the identity token.

Currently the secrets are cached for the duration of the catalog compilation or application depending if deferred or not.
It is not the case for the token though, each secret lookup will result in a POST call to the login endpoint to get a new token.
Tokens are not revoked after the lookup either.

What do you think about caching the token as well (opt-in) ?
This would bring some additional complexities if we want to handle the lifecycle of the token (renew, extend TTL...).
But we could say that the token is cached for the duration of the catalog application, not extended nor renewed to avoid too many difficulties.
I do think revoking the token upon catalog completion could be nice no matter the decision about the token caching.

Handle HTTP rate-limit

Vault allows administrators to define some quotas above which clients will receive 429 responses.
Additionally Vault can be configured to send back rate-limit headers Retry-After, X-Ratelimit-Limit, X-Ratelimit-Remaining and X-Ratelimit-Reset as per RFC 9110.
These could be used to do intelligent retries without killing the backing Vault service.
It would of course need a max deadline to avoid hanging puppet for hours.
This max deadline should be configurable as well.

Let me know what you think about these ideas, again happy to contribute.

Getting the following puppet deprecation when reusing your code

Hi there,

I've been using your code to pull not-so-secret bits of data out of the vault to use as facts. When I run facter, I get the following deprecation warning out of Puppet:

Warning: Puppet::SSL::Host is deprecated and will be removed in a future release of Puppet. (location: /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/ssl/host.rb:235:in initialize')
`
I'm getting this warning on puppet agent version 6.11.1. I expect your code will also be affected once V7 of puppet is released.

Cheers,
Nick

Add local vault mode

Until now, an vault server configured with ssl is needed.
But when the vault server runs on the agent system itself, then an normal none ssl session is ok.
And the needed token can be read from an locale file from the client, to which only root has access.
To there are only 2 additional parameters needed.
One boolean for local_mode and the second for the path to the token file.

Issue authenticating to Vault using AppRole method

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: v7.2.4
  • Ruby:
  • Distribution:
  • Module version:

How to reproduce (e.g Puppet code you use)

use approle with HashiCorp Vault

What are you seeing

Unable to authenticate (403 error)

What behaviour did you expect instead

Authenticate.

Output log

Any additional information you'd like to impart

Fix is in lib/puppet_x/vault_lookup/lookup.rb

Depending on the version depends on the line, but in current code, line 48

      approle_path_segment = 'v1/auth/approle'

should be
approle_path_segment = 'v1/auth/approle/'

(Missing / after approle)

Feature: allow generation of secrets if missing in Vault

It would be nice to have some sort of a password generation option to the vault_lookup function.

some usecases:

  • lookup key has the hostname of the server "root/password/${hostname}" if the key and the secrect does not exists. vault_lookup will generate a new password and save it to Vault. So every server has a different root password
  • bootstrap a new MySQL/MariaDB Server with a new mysql root password

The idea of this feature request to have Vault with the features of trocla (https://github.com/duritong/trocla). Trocla allows autogenerating a password if it does not exist.

Update function for work with Vault secured with Letsencrypt certificates

Hi there,

your function works well with Vault port secured with Puppet certificates, however we needed to use Vault with multiple Puppet masters. For that I've made a fork of your repository, and updated it to use newer "HTTP::Client" library so that it will work with Vault secured with Letsencrypt certificates. I've tested it and can provide documentation as well. Can you please add me as a contributor, so that I can submit my changes as Pull Request ? I've created separate branch as "nikola".

Thanks

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 7.10.0
  • Ruby:
  • Distribution:
  • Module version:

How to reproduce (e.g Puppet code you use)

What are you seeing

What behaviour did you expect instead

Output log

Any additional information you'd like to impart

[Feature Request] Ability not to do cert auth login as part of lookup

Since the 1.1.0 release of Vault, it has the ability to do auto-auth lookup as a daemonized agent. This includes certs, so the approach in the function stays the same, but the auth token would be cached and automaticaly renewed when needed. Also, it would mean that lookups for certain secrets that have a long lease time.

I did a write-up of the whole process here: https://petersouter.xyz/vault-caching-with-auto-auth-and-puppet/

However, this only works if the token is not given during lookup time, so the logic that does the cert auth and gets the token needs to be disabled for this to work.

I'm not sure how best to do this: a parameter that disables the token lookup (eg. $d = Deferred('vault_lookup::lookup', ["secret/test", 'https://vault.hostname:8200', :cert_auth => disabled])) or a new function that has the same logic but is named differently (eg. $d = Deferred('vault_lookup::lookup_agent', ["secret/test"]) that defaults to localhost:8200 or something like that

This would also resolve the issue of #7 & #16

[Feature Request] Ability to use a list of Vault nodes

Hi,

It would be useful (for me at least) if lookup could use a list of node URL's, instead of a single one.
Then, in two situations it could automatically try the next node in the list:

  • in case there's no response from the node (maybe it's down or unreachable) (connection exception)
  • in case the node is sealed (response exception)

Thanks.

Per-client cert policies possible?

I've set this module up and it seems to work as far as allowing all Puppet agents to use the same policy by setting it at the auth/cert/certs/puppetserver as documented.

Is it possible with this method to give specific agents specific policies? If so, some documentation would be appreciated.

Retreiving a field value fails.

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 6.28.0
  • Ruby:
  • Distribution: Windows Server 2019
  • Module version: 0.6.0

How to reproduce (e.g Puppet code you use)

$v = vault_lookup::lookup('ad/creds/puppet',
  "https://vault.${trusted['domain']}:8200",
  'v1/auth/cert',
  'wsus',
  nil,
  'current_password'
)

What are you seeing

Error: Failed to apply catalog: Error parsing json secret data from vault response

What behaviour did you expect instead

Compiled catalog and value of current_password field retrieved.

Output log

Any additional information you'd like to impart

Agent unable to connect to Vault because of cert issue

I'm having a problem with a puppet agent connecting to the vault cluster because of a cert issue. The vault endpoint is a puppet agent as well under the same primary server.
The vault listener is setup with a cert that was created off of our root issuing cert infra, but the puppet CA cert is separate.
The agent is setup to trust any cert signed by the root cert, but it appears the Puppet HTTP client is not trusting the cert.
I have tried adding the vault cert to the agent's CA bundle as described here: https://support.puppet.com/hc/en-us/articles/115000390993-Add-certificates-to-the-Puppet-certificate-bundle-in-Puppet-Enterprise
(I know I'm trying the approle auth that was just released but I suspect I would have this same issue with cert auth.)

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 2019.8.11 / 6.27.0
  • Distribution: RHEL 8
  • Module version: d00dda5

How to reproduce (e.g Puppet code you use)

  $role_id = 'xxxxxx'
  $secret_id = 'yyyyy'

  $d = Deferred('vault_lookup::lookup', ['aws/creds/build_role', 'https://vault:8200', nil, nil, nil, nil, 'approle', $role_id, $secret_id, nil])

  notify { 'vault':
    message => $d,
  }

Vault tcp listener

      "tcp": {
        "address": "<ipaddr>:8200",
        "tls_cert_file": "/etc/vault/vault.cer",
        "tls_key_file": "/etc/vault/vault.key"
      }

What are you seeing

when puppet is run:

Failed to apply catalog: certificate verify failed [unable to get local issuer certificate for ,CN=vault,OU=....]

What behaviour did you expect instead

successful puppet run

error: "client certificate must be supplied"

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 7.16.0 (PE 2021.6.0)
  • Ruby: bunlded PE
  • Distribution: RHEL6 and RHEL8
  • Module version: 0.5

How to reproduce (e.g Puppet code you use)

Vault listener using Lets Encrypt cert
Vault listener config:
"tcp": {
"address": "0.0.0.0:8201",
"tls_disable": false,
"tls_cert_file": "/etc/letsencrypt/live/vault/fullchain.pem",
"tls_key_file": "/etc/letsencrypt/live/vault/privkey.pem",
"tls_client_ca_file": "/etc/puppetlabs/puppet/ssl/certs/ca.pem",
}
Run puppet agent -t with the code in readme

What are you seeing

Puppet shows Error: Failed to apply catalog: Received 400 response code from vault at https://:8201/v1/auth/cert/login for authentication (api errors: ["client certificate must be supplied"])

However connecting via curl works as expected. I am able to get a auth token
curl --request POST --cert /etc/puppetlabs/puppet/ssl/certs/<agent_cert>.pem --key /etc/puppetlabs/puppet/ssl/private_keys/<agent_key>.pem --data '' -vvv https://<vault_server>:8201/v1/auth/cert/login

What behaviour did you expect instead

For at least the authentication step to be completed

Any additional information you'd like to impart

Vault audit log confirms the puppet isn't proceeding past the auth stage

The Puppet CA is the default config for PE, there is no external CA.

Allow Vault configuration from VAULT_ADDR environment variable

What are you seeing

The Vault address has to be provided within the Puppet code to use the lookup. It would be nicer if this was an optional parameter, and the Puppet agent could use the VAULT_ADDR environment variable to find the Vault address instead.

What behaviour did you expect instead

cat /etc/sysconfig/puppet
VAULT_ADDR=http://vault.example.com:8200

THen we dont have to specify

$d = Deferred('vault_lookup::lookup', ["secret/test"])

node default {
  notify { example :
    message => $d
  }
}

Output log

Any additional information you'd like to impart

tvpartytonight/vault_lookup migration

  • https://github.com/pcarlisle added to the modules/admin team
  • Repository transferred
  • Github issues enabled
  • Verify that all webhooks except travis are disabled
  • Release a copy of your module to the ‘puppet’ forge account - to be done by @pcarlisle
  • Add the module to our modulesync setup
  • Add the module to our plumbing repository(handles travis secrets)
  • Ask an admin to add the collaborators team to the module’s Collaborators & Teams ‘Teams’ list with Write permissions
  • Execute modulesync for this module
  • Sync labels

bolt with approle

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 7.17.0
  • Ruby: 3.1.2p20
  • Distribution: Fedora/Ubuntu
  • Module version: latest

How to reproduce (e.g Puppet code you use)

I am trying to use this fuction with puppet bolt and no puppet-ca setup. So I am trying to use the approle auth for vault. If I curl with role_id and secret_id I can get a token so vault side is perfectly working.
I can also access my vault both via http and https (self signed cert).

Bolt plan:

plan project::class (
  TargetSpec $targets
 ) {
  $system_facts = run_plan('facts', 'targets' => $targets)
  $apply_result = apply($targets, '_description' => 'apply class') {
    $d = vault_lookup::lookup(
      'path/to/secret',
      'http(s)://vault.example.com',
      'approle',
    )

    notify { example :
      message => $d,
    }
  }

  $apply_result.each |$result| {
    $result.report['logs'].each |$log| {
      out::message("${log['level']}: ${log['message']}")
      out::message("--${log['source']}")
    }
  }

  return $apply_result
}

What are you seeing

When trying to read a secret from vault via https I get:
certificate verify failed unable to get local issuer certificate.
But the root ca is definatley trusted by linux.

When trying to read a secret from vault via http I get:
Received 404 response code from vault at http://vault.example.com/approle/login for authentication.
I exported environment variables as described in the documentation.

What behaviour did you expect instead

It is expected to read a secret from vault.

Any additional information you'd like to impart

I feel like environment variables are not beeing used, cause I have to set auth_method to approle as a function parameter otherwise I get redirected to http://vault.example.com/cert/login.

Would be nice if anyone could help me!

Error: Failed to apply catalog: undefined method `http_ssl_instance' for Puppet::Network::HttpPool:Module

Hello everyone,

I'm trying to use this module and get deprecation error.

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 7.2.1
  • Ruby:
  • Distribution: Centos 7
  • Module version: 0.1.1

How to reproduce (e.g Puppet code you use)

To check if module works, i'm trying to use code exact same with example in Readme.

What are you seeing

on line $d = Deferred('vault_lookup::lookup', ["secret/test", 'https://vault.hostname:8200'])
agent falls and I see an error:

Error: Failed to apply catalog: undefined method `http_ssl_instance' for Puppet::Network::HttpPool:Module Did you mean? http_instance

Looks like, module's code uses a deprecated ruby's module. I'm not really familiar with ruby, so I can't inspect this issue closer. Is there any solution?

undefined local variable or method 'vault_role_id'

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 7
  • Distribution: Debian 11
  • Module version: master branch

How to reproduce (e.g Puppet code you use)

When i use the master branch code i have this exception - "undefined local variable or method 'vault_role_id'"
I think it's a omission during modification names vault_role_id to role_id and vault_secret_id to secret_id

Specifying different login endpoint

The login endpoint is currently hardcoded as /v1/auth/cert/login. I think this differs between Vault setups, so this doesn't work for everyone. I'll be honest, I don't manage the Vault instance I'm hitting so I'm not sure what the difference is (something to do with AppRole? seems this also requires a name field in the request body).

  • Does it seem reasonable to allow the login endpoint to be passed in?
  • Can this be done without adding an argument/making a breaking change?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.