terraform-provider-vault: Bug with vault_approle_auth_backend_role token_policies

Terraform Version

Terraform v0.11.14

  • provider.vault v2.3.0

Affected Resource(s)

Please list the resources as a list, for example:

  • vault_approle_auth_backend_role

Terraform Configuration Files

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

Expected Behavior

token_policies argument is assigned with policies after apply and reflected in state.

Actual Behavior

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.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply vault_approle_auth_backend_role resource with token_policies argument defined.
  2. terraform apply again
  3. See the differnce as above.

Important Factoids

Everything works perfect with provider version 2.0.0 and policies argument instead of token_policies

Thanks in advance!

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 8
  • Comments: 32 (25 by maintainers)

Commits related to this issue

Most upvoted comments

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.

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

+1

Also, as @StephenWithPH noted, using the deprecated policies field throws a warning, but works, where the recommended token_policies field does not.

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.