Terraform v0.11.14
Please list the resources as a list, for example:
My module resources:
resource "vault_approle_auth_backend_role" "this" {
count = "${length(keys(var.vault_approles))}"
backend = "${var.approle_auth_backend_path}"
role_name = "${element(keys(var.vault_approles), count.index)}"
token_policies = ["${element(keys(var.vault_approles), count.index)}"]
secret_id_num_uses = 0
secret_id_ttl = "36000"
token_ttl = "36000"
}
resource "vault_approle_auth_backend_role_secret_id" "this" {
depends_on = ["vault_approle_auth_backend_role.this"]
count = "${length(keys(var.vault_approles))}"
backend = "${var.approle_auth_backend_path}"
role_name = "${element(keys(var.vault_approles), count.index)}"
}
resource "vault_policy" "this" {
count = "${length(keys(var.vault_approles))}"
name = "${element(keys(var.vault_approles), count.index)}"
policy = "${element(values(var.vault_approles), count.index)}"
}
Configuration:
module "k8s-sre-approle" {
source = "<path_to_module>"
approle_auth_backend_path = "hub_approle"
vault_approles {
k8s-sre-kv-approle-jenkins = "${data.vault_policy_document.vault_prod_k8s_sre_kv_approle_jenkins.hcl}"
k8s-sre-kv-approle-artifactory = "${data.vault_policy_document.vault_prod_k8s_sre_kv_approle_artifactory.hcl}"
}
}
token_policies argument is assigned with policies after apply and reflected in state.
terraform apply
Terraform will perform the following actions:
+ module.k8s-sre-approle.vault_approle_auth_backend_role.this[0]
id: <computed>
backend: "hub_approle"
bind_secret_id: "true"
role_id: <computed>
role_name: "k8s-sre-kv-approle-artifactory"
secret_id_num_uses: "0"
secret_id_ttl: "36000"
token_policies.#: "1"
token_policies.2374882508: "k8s-sre-kv-approle-artifactory"
token_ttl: "36000"
token_type: "default"
+ module.k8s-sre-approle.vault_approle_auth_backend_role.this[1]
id: <computed>
backend: "hub_approle"
bind_secret_id: "true"
role_id: <computed>
role_name: "k8s-sre-kv-approle-jenkins"
secret_id_num_uses: "0"
secret_id_ttl: "36000"
token_policies.#: "1"
token_policies.2057305492: "k8s-sre-kv-approle-jenkins"
token_ttl: "36000"
token_type: "default"
+ module.k8s-sre-approle.vault_approle_auth_backend_role_secret_id.this[0]
id: <computed>
accessor: <computed>
backend: "hub_approle"
role_name: "k8s-sre-kv-approle-artifactory"
secret_id: <computed>
wrapping_accessor: <computed>
wrapping_token: <computed>
+ module.k8s-sre-approle.vault_approle_auth_backend_role_secret_id.this[1]
id: <computed>
accessor: <computed>
backend: "hub_approle"
role_name: "k8s-sre-kv-approle-jenkins"
secret_id: <computed>
wrapping_accessor: <computed>
wrapping_token: <computed>
+ module.k8s-sre-approle.vault_policy.this[0]
id: <computed>
name: "k8s-sre-kv-approle-artifactory"
policy: "# Policy for k8s-sre Artifactory Approle\npath \"k8s-sre-kv/artifactory/*\" {\n capabilities = [\"read\"]\n}\n"
+ module.k8s-sre-approle.vault_policy.this[1]
id: <computed>
name: "k8s-sre-kv-approle-jenkins"
policy: "# Policy for k8s-sre Jenkins Approle\npath \"k8s-sre-kv/*\" {\n capabilities = [\"read\"]\n}\n"
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
Next subsequents apply shows difference in state:
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
~ module.k8s-sre-approle.vault_approle_auth_backend_role.this[0]
policies.#: "1" => "0"
policies.1971754988: "default" => ""
token_policies.#: "0" => "1"
token_policies.2374882508: "" => "k8s-sre-kv-approle-artifactory"
~ module.k8s-sre-approle.vault_approle_auth_backend_role.this[1]
policies.#: "1" => "0"
policies.1971754988: "default" => ""
token_policies.#: "0" => "1"
token_policies.2057305492: "" => "k8s-sre-kv-approle-jenkins"
Plan: 0 to add, 2 to change, 0 to destroy.
Beggining from provider version 2.0.0 policies argument was changed to token_policies and I wonder why it's present here. Actually, no values are being assigned to token_policies and each subsequent apply show a difference and vault_approle_auth_backend_role token_policies argument is now working at all.
Please list the steps required to reproduce the issue, for example:
terraform apply vault_approle_auth_backend_role resource with token_policies argument defined.terraform apply againEverything works perfect with provider version 2.0.0 and policies argument instead of token_policies
Thanks in advance!
+1
token_policies is for Vault >= 1.2.0.
@lawliet89
token_policies works with Vault 1.1.2 and prover version 2.0.0, but with provider version 2.3.0 the bug is reproduced.
seeing the same bug - any progress?
+1
+1
Adding commentary in case it helps anyone... I set the deprecated policies field rather than the recommended token_policies field, and that resolved a gnarly issue I was having (by way of Vault Agent auto-auth) with the https://github.com/hashicorp/vault-plugin-auth-gcp.
+1
Also, as @StephenWithPH noted, using the deprecated policies field throws a warning, but works, where the recommended token_policies field does not.
This looks like an issue when using Vault < 1.2.0 with token_policies. I recommend upgrading to Vault >= 1.2.0
I was unable to reproduce this with Vault 1.2.0 and provider 2.3.0. However, I decided to try this with Vault 1.1.2 and was able to reproduce the error you were seeing. I also tried using Vault 1.1.2 with provider 2.0.0 but got an error:
Error: module.k8s-sre-approle.vault_approle_auth_backend_role.this[0]: : invalid or unknown key: token_policies
The token_policies fields aren't available prior to Vault 1.2.0. For Vault < 1.2.0, use the policies parameter instead. There is additional information at https://www.terraform.io/docs/providers/vault/r/approle_auth_backend_role.html#deprecated-arguments
Facing this bug too:
Key Value
--- -----
Recovery Seal Type shamir
Initialized true
Sealed false
Total Recovery Shares 5
Threshold 3
Version 1.3.1
[…]
Terraform v0.11.14
- Downloading plugin for provider "vault" (2.7.1)...
resource "vault_approle_auth_backend_role" "tcs" {
role_name = "tcs"
token_policies = ["default", "tcs_app"]
}
md5-cc902d02318e992c705b4ba6a7d9c0c9
vault_approle_auth_backend_role.tcs: Modifying... (ID: auth/approle/role/tcs)
policies.#: "2" => "0"
policies.1971754988: "default" => ""
policies.2311870954: "tcs_app" => ""
token_policies.#: "0" => "2"
token_policies.1971754988: "" => "default"
token_policies.2311870954: "" => "tcs_app"
@yermulnik I can't seem to reproduce this locally. Here's what I've done:
Run vault 1.3.1 in dev mode (pulled from the v1.3.1 tag):
vault server -dev
```
$ vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.3.1
Cluster Name vault-cluster-3f93e9b2
Cluster ID e806ec42-9ee9-3bc6-897a-3fd2572d5a3c
HA Enabled false
I've also run this locally in non-dev mode.
Manually enabled approle auth method:
$ vault auth enable approle
Success! Enabled approle auth method at: approle/
Here's my `main.tf` file:
```hcl
provider "vault" {
version = "2.7.1"
}
resource "vault_approle_auth_backend_role" "tcs" {
role_name = "tcs"
token_policies = ["default", "tcs_app"]
}
(no other files in the folder)
Terraform:
$ terraform init
<successful>
$ terraform version
Terraform v0.11.14
+ provider.vault v2.7.1
terraform apply is successful. Subsequent calls show no changes.
I'm struggling to find what is different from your example.
@pcman312 Hmm, interesting… Thanks for giving it a try.
What if you enable approle backend and create tcs_app policy using Vault as well?
resource "vault_auth_backend" "approle" {
type = "approle"
}
resource "vault_policy" "tcs_app" {
name = "tcs_app"
policy = <<EOT
path "tcs/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
EOT
}
@yermulnik I keep getting issues with the vault_policy you gave me. It's complaining that the endpoint doesn't exist. I'm new to this provider, so I'm unsure exactly the problem there.
If I remove the vault_policy I get the same result as before: terraform apply works and doesn't show any changes on the second run.
@pcman312
It's complaining that the endpoint doesn't exist.
what was the actual error? (so that I can paste code snippet for you to fix)
also would be cool if provider devs could take a look into it — it's quite annoying issue as our CI plans loads of changes every run =(
@yermulnik
Error: Error applying plan:
1 error occurred:
* vault_approle_auth_backend_role.tcs: 1 error occurred:
* vault_approle_auth_backend_role.tcs: error writing AppRole auth backend role "auth/approle/role/tcs": Error making API request.
URL: PUT http://127.0.0.1:8200/v1/auth/approle/role/tcs
Code: 404. Errors:
* no handler for route 'auth/approle/role/tcs'
I tried ordering the vault_policy in different points in the config file with no change.
Here's my main.tf:
provider "vault" {
version = "2.7.1"
}
resource "vault_auth_backend" "approle" {
type = "approle"
}
resource "vault_policy" "tcs_app" {
name = "tcs_app"
policy = <<EOT
path "auth/approle/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
EOT
}
resource "vault_approle_auth_backend_role" "tcs" {
role_name = "tcs"
token_policies = ["default", "tcs_app"]
}
@pcman312 Hmm, looks strange.
What if you define backend for the role explicitly like this (so that it depends on vault_auth_backend and is not attempted to be created before the backend itself):
resource "vault_approle_auth_backend_role" "tcs" {
backend = "${vault_auth_backend.approle.path}"
role_name = "tcs"
token_policies = ["default", "tcs_app"]
}
@yermulnik That seems to have fixed it. Unfortunately I'm still not able to replicate the issue:
Initial apply
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "vault" (2.7.1)...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
vault_policy.tcs_app: Creating...
name: "" => "tcs_app"
policy: "" => "path \"auth/approle/*\" {\n capabilities = [\"create\", \"read\", \"update\", \"delete\", \"list\"]\n}\n"
vault_auth_backend.approle: Creating...
accessor: "" => "<computed>"
default_lease_ttl_seconds: "" => "<computed>"
max_lease_ttl_seconds: "" => "<computed>"
path: "" => "<computed>"
type: "" => "approle"
vault_policy.tcs_app: Creation complete after 0s (ID: tcs_app)
vault_auth_backend.approle: Creation complete after 0s (ID: approle)
vault_approle_auth_backend_role.tcs: Creating...
backend: "" => "approle"
bind_secret_id: "" => "true"
role_id: "" => "<computed>"
role_name: "" => "tcs"
token_policies.#: "" => "2"
token_policies.1971754988: "" => "default"
token_policies.2311870954: "" => "tcs_app"
token_type: "" => "default"
vault_approle_auth_backend_role.tcs: Creation complete after 0s (ID: auth/approle/role/tcs)
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Second run:
vault_auth_backend.approle: Refreshing state... (ID: approle)
vault_policy.tcs_app: Refreshing state... (ID: tcs_app)
vault_approle_auth_backend_role.tcs: Refreshing state... (ID: auth/approle/role/tcs)
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
@pcman312 Interesting. Thanks for giving it a go.
Which version of Terraform do you use?
I'm leaning to think this might be related to existing configuration that had been using previous version of TF vault provider and vault and which had been upgraded to a newer version of vault and vault provider hence the issue with state.
Weird that I cannot re-deploy my vault clusters from the scratch to see if it would fix the issue since these are under heavy use at the moment =(
@yermulnik that seems like a likely explanation for the problem that you and others have been seeing. I'm using Terraform 0.11.14, provider 2.7.1, and Vault 1.3.1, but I am using a completely fresh setup. What version did you upgrade from? I can try using the old version and then upgrading to see if it can be replicated.
@pcman312 We upgraded from vault provider 1.9.* to 2.7.1 and vault 1.1.3 to 1.3.1
@yermulnik I've managed to partially reproduce this issue.
Running Vault 1.1.3 (not in dev mode), TF 0.11.14, Provider 2.7.1, I performed a terraform apply, followed by another terraform apply and got an error similar to the one you mentioned previously:
Terraform will perform the following actions:
~ vault_approle_auth_backend_role.tcs
token_policies.#: "0" => "2"
token_policies.1971754988: "" => "default"
token_policies.2311870954: "" => "tcs_app"
Plan: 0 to add, 1 to change, 0 to destroy.
If I then shut down vault and start up v1.3.1 and run terraform apply it shows the same diff as above, however subsequent calls to terraform apply don't show a diff any longer.
I'm going to try the same procedure but comparing Vault 1.1.3 & Provider 1.9.0 to Vault 1.3.1 & Provider 2.7.1 to see how the provider plays a role in this.
@pcman312
I've managed to partially reproduce this issue.
Oh, I saw this behaviour as well. So basically once token_policies were planned and applied subsequent plan/apply would want to make changes to policies like kind of reverting previously applied changes — basically what you _partially_ reproduced was what we started this journey with, but at some point it started to produce changes I mentioned in the first message I posted to this thread (replace policies with token_policies — I didn't apply these so no idea what was _supposed_ to go next).
Thanks again for looking into this.
@yermulnik Ah, okay. I thought you had applied those changes and were still seeing the issue. Based on the diff, I'm reasonably confident it's going to remove policies and add token_policies which I believe is be expected behavior. Do you have a way of applying those changes into a non-prod environment to make sure they work as expected before going to prod?
@pcman312 I might had put myself not quite clear. Despite tf configuration having token_policies and having it applied TF wants to remove policies and put token_policies. Basically what the initial issue was about (the very 1st message from CarpathianUA in this issue). So once we've got our vault and tf vault provider upgraded to 2.7.1 and 1.3.1 respectively with a switch from policies to token_policies we have started to hit this issue — constant changes to plan nevertheless it was applied: removing policies + adding token_policies (while tf configuration has token_policies in there).
@yermulnik I think I've reproduced the perpetual diff problem but want to confirm that this is the same steps you took:
main.tf:resource "vault_approle_auth_backend_role" "tcs" {
backend = "${vault_auth_backend.approle.path}"
role_name = "tcs"
policies = ["default", "tcs_app"]
}
$ terraform initInitializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "vault" (1.9.0)...
Terraform has been successfully initialized!
$ terraform applyAn execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ vault_approle_auth_backend_role.tcs
id: <computed>
backend: "${vault_auth_backend.approle.path}"
bind_secret_id: "true"
policies.#: "2"
policies.1971754988: "default"
policies.2311870954: "tcs_app"
role_id: <computed>
role_name: "tcs"
+ vault_auth_backend.approle
id: <computed>
accessor: <computed>
default_lease_ttl_seconds: <computed>
max_lease_ttl_seconds: <computed>
path: <computed>
type: "approle"
+ vault_policy.tcs_app
id: <computed>
name: "tcs_app"
policy: "path \"auth/approle/*\" {\n capabilities = [\"create\", \"read\", \"update\", \"delete\", \"list\"]\n}\n"
Plan: 3 to add, 0 to change, 0 to destroy.
<completes successfully>
main.tf to change policies -> token_policies (no other changes aside from the provider version)resource "vault_approle_auth_backend_role" "tcs" {
backend = "${vault_auth_backend.approle.path}"
role_name = "tcs"
token_policies = ["default", "tcs_app"]
}
terraform apply, get the diff:Terraform will perform the following actions:
~ vault_approle_auth_backend_role.tcs
policies.#: "2" => "0"
policies.1971754988: "default" => ""
policies.2311870954: "tcs_app" => ""
token_policies.#: "0" => "2"
token_policies.1971754988: "" => "default"
token_policies.2311870954: "" => "tcs_app"
terraform apply and get the same diff every time it's run.Is this an accurate description of the steps you took?
@pcman312 Looks very similar to what I can recall. Apart from using backend attribute.
@yermulnik Sorry for the delayed update. I looked into the code for this but haven't come up with a solution to it yet. In the meantime you can look into using terraform state mv to move the policies values to token_policies. There is an rm command as well, but I'm a bit more hesitant to recommend it. It's the next thing I'm going to look into when I can loop back to this issue.
@pcman312 no problem. thanks for looking into this anyways. it's not very vital for us apart from having either back and forth with policies and token_policies or deprecation notices.
btw do you mean that terraform state mv should help to get rid of back and forth of policies and token_policies? having that terraform does the initial change from policies to token_policies itself but then it starts to move it back and forth. also I cannot see how terraform state mv would be used for a attribute of the resource.
@yermulnik That's my current thought. policies is transformed to token_policies, but until we figure out a code solution to this, terraform state mv or terraform state rm might work. I don't know for sure if it will work, and I'm not sure if it will cause any other problems to surface. I want to do more testing with it.
As some additional information which may help identify what's going on here...
We have some AppRoles which were created with an old version of Vault (I think around v0.9.6, but it's from before the change from policies to token_policies)
We're now on Vault v1.4.0, and provider v2.10.0.
What I have found is that AppRoles created in the older version of Vault actually do have both the old policies and period fields, and the new token_policies and token_period fields when you read them from Vault:
$ vault read auth/approle/role/test
Key Value
--- -----
bind_secret_id true
local_secret_ids false
period 24h
policies [default test]
secret_id_bound_cidrs <nil>
secret_id_num_uses 1
secret_id_ttl 5m
token_bound_cidrs []
token_explicit_max_ttl 0s
token_max_ttl 8h
token_no_default_policy false
token_num_uses 0
token_period 24h
token_policies [default test]
token_ttl 20m
token_type default
Removing the AppRole from the Terraform state with terraform state rm, then re-importing it, we still see the issue:
~ vault_approle_auth_backend_role.test
period: "86400" => "0"
policies.#: "2" => "0"
policies.1971754988: "default" => ""
policies.309839343: "test" => ""
token_period: "0" => "86400"
token_policies.#: "0" => "2"
token_policies.1971754988: "" => "default"
token_policies.309839343: "" => "test"
i.e. Terraform detects that the polices field exists still, and tries to update token_policies
Newly created AppRoles do not have this issue. When I read those from Vault, they do not have the policies or period fields, and Terraform is able to successfully detect that it does not need to make any changes.
As another interesting data point, we do NOT see this issue with the vault_aws_auth_backend_role or vault_kubernetes_auth_backend_role resources, even though Vault behaves the same for those:
$ vault read auth/aws/role/test
Key Value
--- -----
allow_instance_migration false
auth_type iam
bound_account_id []
bound_ami_id []
bound_ec2_instance_id <nil>
bound_iam_instance_profile_arn []
bound_iam_principal_arn [arn:aws:iam::REDACTED:role/va-demo-vault-client-role arn:aws:iam::REDACTED:role/vault-client-role]
bound_iam_principal_id [REDACTED REDACTED]
bound_iam_role_arn []
bound_region []
bound_subnet_id []
bound_vpc_id []
disallow_reauthentication false
inferred_aws_region n/a
inferred_entity_type n/a
policies [default test]
resolve_aws_unique_ids true
role_id a4062777-810a-eb1b-b8f0-375e5b9071d3
role_tag n/a
token_bound_cidrs []
token_explicit_max_ttl 0s
token_max_ttl 0s
token_no_default_policy false
token_num_uses 0
token_period 0s
token_policies [default test]
token_ttl 0s
token_type default
Note from above that the policies field exists when I read this from Vault, and yet Terraform is able to handle this gracefully.
As I look into this further, it appears that the vault_aws_auth_backend_role has some code to explicitly handle this type of issue:
https://github.com/terraform-providers/terraform-provider-vault/blob/master/vault/resource_aws_auth_backend_role.go#L437-L448
Whereas vault_approle_auth_backend_role does not:
https://github.com/terraform-providers/terraform-provider-vault/blob/master/vault/resource_approle_auth_backend_role.go#L260-L267
Hello - I opened https://github.com/terraform-providers/terraform-provider-vault/pull/744 to address this. Thanks to @lucymhdavies for pointing me in the right direction for the fix.
If you have the ability to checkout the repo, compile it, and give it a try, please let us know if it works out.
Most helpful comment
Hello - I opened https://github.com/terraform-providers/terraform-provider-vault/pull/744 to address this. Thanks to @lucymhdavies for pointing me in the right direction for the fix.
If you have the ability to checkout the repo, compile it, and give it a try, please let us know if it works out.