Terraform-provider-vault: Export VAULT_ADDR env variable when calling a token helper

Created on 3 Sep 2019  路  7Comments  路  Source: hashicorp/terraform-provider-vault

Hi there,

I'm not sure if this is possible, but that would be nice if terraform provider (or the vault lib it uses) would export the VAULT_ADDR environmental variable whet it calls the token helper.

My use case is that I use a complex terraform configuration with a lot of root modules. Each root module has its individual vault provider with an address parameter:

# infra-1/main.tf
provider "vault" {
  address = "https://infra-1.example.com"
}
# infra-2/main.tf
provider "vault" {
  address = "https://infra-2.example.com"
}

and so on.

Currently I have to run vault login every time when I switch between directories, because the provider relies on the default token helper (~/.vault-token) by default.

The idea of Token Helpers is very cool, but it is quite useless in the current implementation, because it doesn't define how the Vault cluster address will be passed to the helper executable.

Most of implementations of token helpers (including the example from https://www.hashicorp.com/blog/building-a-vault-token-helper) are relying on VAULT_ADDR env variable.
In my case, I don't use VAULT_ADDR env variable in my shell because I use multiple vaults.
So maybe the provider can define it to the expected Vault server address when calling the helper?

What do you think about it? If it's not possible - do you have suggestions how to orginize the workflow for the case I described above?

Thanks!

P.s. Maybe, the vault provider should have a parameter for defying VAULT_CONFIG instead? Then people with the similar cases could write small shell-scripts which will wrap the actual helper and export the desired env var before that?

Most helpful comment

I would agree that having something in the terraform process manipulate environment variables so that a subprocess (the token helper) invoked by the terraform process can pick up those values feels very weird, and it is not the approach I would've taken in #651 if I could imagine another way of doing it.

As far as I know the only way to configure or pass context to a vault token helper is via environment variables or by having the token helper look at some context stored somewhere locally (such as a ~/.kube/config file, potentially), due to the Vault CLI and Terraform invoking token helpers as $helper_executable get with no arguments, and no data passed to the helper on stdin.

Given that constraint, the only 2 options I can think of for higher level processes, such as terraform in this case, to configure the helper to get a credential for at target vault cluster is to either configure the VAULT_ADDR environment variable before executing Vault calls or to add support for a -address flag to the specification for get/set commands of token helpers.

The Vault docs on token helpers seem to suggest that environment variables are a valid way to configure a Vault token helper with support for storing vault tokens from multiple Vault clusters: https://www.vaultproject.io/docs/commands/token-helper/#example-token-helper

I've not been able to find any discussion directly around adding support for address arguments for token helpers on either the Vault public google group or in existing Vault Github issues beyond this issue comment which just alludes that env vars should be used to provide context to token helpers: https://github.com/hashicorp/vault/issues/2092#issuecomment-290556418.

I think adding support for an -address argument to the token helper specificatoin could be done in a backwards compatible way, and would be advantageous for general Vault CLI usage as well (i.e. currently VAULT_ADDR aware token helpers fail if VAULT_ADDR is not set and the Vault CLI's -address flag is used instead to pass the address). But I also understand if y'all don't want to open the Pandora's box of once one configurable flag is added to the token helper specification, people will request many more.

All that being said -- the approach I took in #651 felt weird to me, but I was comfortable enough with it to go ahead and open the PR to address this issue for 2 reasons:

  1. We're using some similar process environment variable manipulations for this same use case in some internal tooling at my company currently and haven't run into any issues or unexpected side effects with it to date
  2. I was able to pretty surgically limit when the env var was manipulated to just the area of the code that would be make Vault calls, reducing the chances of unexpected behavior later on in the same process.

I'm thinking that the ideal approach would be to encapsulate the changes to the code rather than the outer environment.

Which code did you have in mind for this, the Terraform provider code or the Vault token helper code/spec? As mentioned above, I'm not totally in love with the env var based solution, so if there is a way to pass the context from Terraform (or the Vault CLI) to the external token helper process that I'm missing, I'd be more than happy to go that direction!

All 7 comments

Hey guys, can we get your thoughts here?

Hey everybody. I manage three vault instances and have written myself a token helper that stores/fetches tokens based on VAULT_ADDR, which works good when I use vault-cli.

I know would like to manage two vault instances in one state with terraform... which is not possible, since terraform tries to use the same token for both vaults.

tl;dr I would very much prefer that this gets implemented. If not, what is the workaround here? Except for specifying tokens in the provider section?

PS: Thank you all for your work

Hi! Thank you for opening this issue. @ianferguson has opened a PR implementing the approach of setting the env variable as discussed here, and I want to pull the conversation regarding this approach onto the issue here.

My first thought is, the idea of the application setting outer environment variable seems like it could solve the problem, but also seems rather unusual to me. I'm not familiar with any other application that changes its own environment variables. Is this a common pattern elsewhere that you can point out? My other thought is whether this could have unexpected side effects for other users.

I'm thinking that the ideal approach would be to encapsulate the changes to the code rather than the outer environment. However, I'm flexible and if this approach makes sense and there aren't better alternatives, we can look at it.

Please do let me know your thoughts. :-) Thank you.

I would say that the program is not changing its own environment but the env of programs (in this case the vault token helper) it calls. Also the original env gets restored after the call so it does not seem that odd to me :)

I would agree that having something in the terraform process manipulate environment variables so that a subprocess (the token helper) invoked by the terraform process can pick up those values feels very weird, and it is not the approach I would've taken in #651 if I could imagine another way of doing it.

As far as I know the only way to configure or pass context to a vault token helper is via environment variables or by having the token helper look at some context stored somewhere locally (such as a ~/.kube/config file, potentially), due to the Vault CLI and Terraform invoking token helpers as $helper_executable get with no arguments, and no data passed to the helper on stdin.

Given that constraint, the only 2 options I can think of for higher level processes, such as terraform in this case, to configure the helper to get a credential for at target vault cluster is to either configure the VAULT_ADDR environment variable before executing Vault calls or to add support for a -address flag to the specification for get/set commands of token helpers.

The Vault docs on token helpers seem to suggest that environment variables are a valid way to configure a Vault token helper with support for storing vault tokens from multiple Vault clusters: https://www.vaultproject.io/docs/commands/token-helper/#example-token-helper

I've not been able to find any discussion directly around adding support for address arguments for token helpers on either the Vault public google group or in existing Vault Github issues beyond this issue comment which just alludes that env vars should be used to provide context to token helpers: https://github.com/hashicorp/vault/issues/2092#issuecomment-290556418.

I think adding support for an -address argument to the token helper specificatoin could be done in a backwards compatible way, and would be advantageous for general Vault CLI usage as well (i.e. currently VAULT_ADDR aware token helpers fail if VAULT_ADDR is not set and the Vault CLI's -address flag is used instead to pass the address). But I also understand if y'all don't want to open the Pandora's box of once one configurable flag is added to the token helper specification, people will request many more.

All that being said -- the approach I took in #651 felt weird to me, but I was comfortable enough with it to go ahead and open the PR to address this issue for 2 reasons:

  1. We're using some similar process environment variable manipulations for this same use case in some internal tooling at my company currently and haven't run into any issues or unexpected side effects with it to date
  2. I was able to pretty surgically limit when the env var was manipulated to just the area of the code that would be make Vault calls, reducing the chances of unexpected behavior later on in the same process.

I'm thinking that the ideal approach would be to encapsulate the changes to the code rather than the outer environment.

Which code did you have in mind for this, the Terraform provider code or the Vault token helper code/spec? As mentioned above, I'm not totally in love with the env var based solution, so if there is a way to pass the context from Terraform (or the Vault CLI) to the external token helper process that I'm missing, I'd be more than happy to go that direction!

Hi! Thanks for your thoughts on this. I've finally had a chance to circle back.

After looking at the code more and playing with it, I'd be comfortable with the approach of changing the environment variables. To your point, it does indeed seem to be the best way to approach this given the current state.

Some users may depend on the behavior _as-is_ and I want to ensure this is fully backwards compatible. To that end, in the linked PR, would you be willing to add a flag with a name like override_token_helper (or a better name if you can think of one)? It would be false by default for backwards compatibility, but if set to true, then we'd set the Vault token in the env as the code you've PR'd already does?

Then of course we'll need the other normal things on the PR - test coverage and a docs update. Happy to approve and merge at that point.

Again, a big thanks to you and everyone for bringing this up and talking it through. Much appreciated!

@tyrannosaurus-becks sounds good! I should be able to get the pull request updated later this week.

I'll likely use propagate_vault_addr_to_env or something along those lines for the name, at least for our use case, passing the vault address into the VAULT_ADDR environment is to enable us to utilize a (custom) vault token helper, so override_token_helper would be misleading at least for our use case.

Either way, I'll get the PR updated in the next few days, appreciate you hearing out the issue and working with us on a viable approach

Was this page helpful?
0 / 5 - 0 ratings