From 17a80e25f121a3171a04cced082de095ba5e334c Mon Sep 17 00:00:00 2001 From: Yong Wen Chua Date: Thu, 20 Aug 2020 06:43:00 +0800 Subject: [PATCH] Add `iam_groups` to `vault_aws_secret_backend_role` (#826) --- vault/resource_aws_secret_backend_role.go | 16 ++++++++ .../resource_aws_secret_backend_role_test.go | 32 +++++++++++++++ .../docs/r/aws_secret_backend_role.html.md | 39 +++++++++++-------- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/vault/resource_aws_secret_backend_role.go b/vault/resource_aws_secret_backend_role.go index c2c018e0f..cb132c5a0 100644 --- a/vault/resource_aws_secret_backend_role.go +++ b/vault/resource_aws_secret_backend_role.go @@ -81,6 +81,14 @@ func awsSecretBackendRoleResource() *schema.Resource { ConflictsWith: []string{"policy", "policy_arn"}, Description: "ARNs of AWS roles allowed to be assumed. Only valid when credential_type is 'assumed_role'", }, + "iam_groups": { + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + Description: "A list of IAM group names. IAM users generated against this vault role will be added to these IAM Groups. For a credential type of assumed_role or federation_token, the policies sent to the corresponding AWS call (sts:AssumeRole or sts:GetFederation) will be the policies from each group in iam_groups combined with the policy_document and policy_arns parameters.", + }, "default_sts_ttl": { Type: schema.TypeInt, Optional: true, @@ -127,6 +135,8 @@ func awsSecretBackendRoleWrite(d *schema.ResourceData, meta interface{}) error { credentialType := d.Get("credential_type").(string) + iamGroups := d.Get("iam_groups").(*schema.Set).List() + data := map[string]interface{}{ "credential_type": credentialType, } @@ -139,6 +149,9 @@ func awsSecretBackendRoleWrite(d *schema.ResourceData, meta interface{}) error { if len(roleARNs) != 0 { data["role_arns"] = roleARNs } + if len(iamGroups) != 0 || !d.IsNewResource() { + data["iam_groups"] = iamGroups + } defaultStsTTL, defaultStsTTLOk := d.GetOk("default_sts_ttl") maxStsTTL, maxStsTTLOk := d.GetOk("max_sts_ttl") @@ -214,6 +227,9 @@ func awsSecretBackendRoleRead(d *schema.ResourceData, meta interface{}) error { if v, ok := secret.Data["max_sts_ttl"]; ok { d.Set("max_sts_ttl", v) } + if v, ok := secret.Data["iam_groups"]; ok { + d.Set("iam_groups", v) + } d.Set("backend", strings.Join(pathPieces[:len(pathPieces)-2], "/")) d.Set("name", pathPieces[len(pathPieces)-1]) return nil diff --git a/vault/resource_aws_secret_backend_role_test.go b/vault/resource_aws_secret_backend_role_test.go index a22986b95..28f501d8f 100644 --- a/vault/resource_aws_secret_backend_role_test.go +++ b/vault/resource_aws_secret_backend_role_test.go @@ -33,6 +33,7 @@ func TestAccAWSSecretBackendRole_basic(t *testing.T) { resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "name", fmt.Sprintf("%s-policy-inline", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "backend", backend), util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "iam_groups.#", "0"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic), @@ -53,16 +54,39 @@ func TestAccAWSSecretBackendRole_basic(t *testing.T) { resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "max_sts_ttl", "21600"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "backend", backend), util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "iam_groups.#", "2"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "iam_groups.#", "2"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend), util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "iam_groups.#", "2"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.2518714066", testAccAWSSecretBackendRoleRoleArn_updated), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "iam_groups.#", "2"), + ), + }, + { + Config: testAccAWSSecretBackendRoleConfig_basic(name, backend, accessKey, secretKey), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "name", fmt.Sprintf("%s-policy-inline", name)), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "backend", backend), + util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "iam_groups.#", "0"), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend), + util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.3970977939", testAccAWSSecretBackendRoleRoleArn_basic), ), }, }, @@ -154,17 +178,21 @@ func TestAccAWSSecretBackendRole_nested(t *testing.T) { resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "backend", backend), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "default_sts_ttl", "3600"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "max_sts_ttl", "21600"), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "iam_groups.#", "2"), util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "iam_groups.#", "2"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend), util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "iam_groups.#", "2"), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend), resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.2518714066", testAccAWSSecretBackendRoleRoleArn_updated), + resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "iam_groups.#", "2"), ), }, }, @@ -243,12 +271,14 @@ resource "vault_aws_secret_backend_role" "test_policy_inline" { backend = "${vault_aws_secret_backend.test.path}" default_sts_ttl = 3600 max_sts_ttl = 21600 + iam_groups = ["group1", "group2"] } resource "vault_aws_secret_backend_role" "test_policy_arns" { name = "%s-policy-arn" policy_arns = ["%s"] credential_type = "iam_user" + iam_groups = ["group1", "group2"] backend = "${vault_aws_secret_backend.test.path}" } @@ -257,6 +287,7 @@ resource "vault_aws_secret_backend_role" "test_policy_inline_and_arns" { policy_document = %q policy_arns = ["%s"] credential_type = "iam_user" + iam_groups = ["group1", "group2"] backend = "${vault_aws_secret_backend.test.path}" } @@ -264,6 +295,7 @@ resource "vault_aws_secret_backend_role" "test_role_arns" { name = "%s-role-arns" role_arns = ["%s"] credential_type = "assumed_role" + iam_groups = ["group1", "group2"] backend = "${vault_aws_secret_backend.test.path}" } `, path, accessKey, secretKey, name, testAccAWSSecretBackendRolePolicyInline_updated, name, testAccAWSSecretBackendRolePolicyArn_updated, name, testAccAWSSecretBackendRolePolicyInline_updated, testAccAWSSecretBackendRolePolicyArn_updated, name, testAccAWSSecretBackendRoleRoleArn_updated) diff --git a/website/docs/r/aws_secret_backend_role.html.md b/website/docs/r/aws_secret_backend_role.html.md index 44c8838db..c6120d078 100644 --- a/website/docs/r/aws_secret_backend_role.html.md +++ b/website/docs/r/aws_secret_backend_role.html.md @@ -51,32 +51,39 @@ EOT The following arguments are supported: * `backend` - (Required) The path the AWS secret backend is mounted at, -with no leading or trailing `/`s. + with no leading or trailing `/`s. * `name` - (Required) The name to identify this role within the backend. -Must be unique within the backend. + Must be unique within the backend. * `credential_type` - (Required) Specifies the type of credential to be used when -retrieving credentials from the role. Must be one of `iam_user`, `assumed_role`, or -`federation_token`. + retrieving credentials from the role. Must be one of `iam_user`, `assumed_role`, or + `federation_token`. * `role_arns` - (Optional) Specifies the ARNs of the AWS roles this Vault role -is allowed to assume. Required when `credential_type` is `assumed_role` and -prohibited otherwise. + is allowed to assume. Required when `credential_type` is `assumed_role` and + prohibited otherwise. * `policy_arns` - (Optional) Specifies a list of AWS managed policy ARNs. The -behavior depends on the credential type. With `iam_user`, the policies will be -attached to IAM users when they are requested. With `assumed_role` and -`federation_token`, the policy ARNs will act as a filter on what the credentials -can do, similar to `policy_document`. When `credential_type` is `iam_user` or -`federation_token`, at least one of `policy_document` or `policy_arns` must -be specified. + behavior depends on the credential type. With `iam_user`, the policies will be + attached to IAM users when they are requested. With `assumed_role` and + `federation_token`, the policy ARNs will act as a filter on what the credentials + can do, similar to `policy_document`. When `credential_type` is `iam_user` or + `federation_token`, at least one of `policy_document` or `policy_arns` must + be specified. * `policy_document` - (Optional) The IAM policy document for the role. The -behavior depends on the credential type. With `iam_user`, the policy document -will be attached to the IAM user generated and augment the permissions the IAM -user has. With `assumed_role` and `federation_token`, the policy document will -act as a filter on what the credentials can do, similar to `policy_arns`. + behavior depends on the credential type. With `iam_user`, the policy document + will be attached to the IAM user generated and augment the permissions the IAM + user has. With `assumed_role` and `federation_token`, the policy document will + act as a filter on what the credentials can do, similar to `policy_arns`. + +* `iam_groups` (Optional) - A list of IAM group names. IAM users generated + against this vault role will be added to these IAM Groups. For a credential + type of `assumed_role` or `federation_token`, the policies sent to the + corresponding AWS call (sts:AssumeRole or sts:GetFederation) will be the + policies from each group in `iam_groups` combined with the `policy_document` + and `policy_arns` parameters. * `default_sts_ttl` - (Optional) The default TTL in seconds for STS credentials. When a TTL is not specified when STS credentials are requested,