From 882be1c6efce098b2d102e34f6573086e29042f6 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Thu, 11 Mar 2021 01:17:07 +0200 Subject: [PATCH 01/10] initial commit --- aws/internal/keyvaluetags/iam_tags.go | 35 ++++++++ aws/resource_aws_iam_policy.go | 95 +++++++++++++-------- aws/resource_aws_iam_policy_test.go | 116 ++++++++++++++++++++++---- 3 files changed, 197 insertions(+), 49 deletions(-) diff --git a/aws/internal/keyvaluetags/iam_tags.go b/aws/internal/keyvaluetags/iam_tags.go index 1059708d280..823ef646cd8 100644 --- a/aws/internal/keyvaluetags/iam_tags.go +++ b/aws/internal/keyvaluetags/iam_tags.go @@ -80,3 +80,38 @@ func IamUserUpdateTags(conn *iam.IAM, identifier string, oldTagsMap interface{}, return nil } + +// IamPolicyUpdateTags updates IAM Policy tags. +// The identifier is the Policy ARN. +func IamPolicyUpdateTags(conn *iam.IAM, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { + oldTags := New(oldTagsMap) + newTags := New(newTagsMap) + + if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { + input := &iam.UntagPolicyInput{ + PolicyArn: aws.String(identifier), + TagKeys: aws.StringSlice(removedTags.Keys()), + } + + _, err := conn.UntagPolicy(input) + + if err != nil { + return fmt.Errorf("error untagging resource (%s): %w", identifier, err) + } + } + + if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { + input := &iam.TagPolicyInput{ + PolicyArn: aws.String(identifier), + Tags: updatedTags.IgnoreAws().IamTags(), + } + + _, err := conn.TagPolicy(input) + + if err != nil { + return fmt.Errorf("error tagging resource (%s): %w", identifier, err) + } + } + + return nil +} diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index 0a44f36cabc..a78bc29a637 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) func resourceAwsIamPolicy() *schema.Resource { @@ -67,12 +68,17 @@ func resourceAwsIamPolicy() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "policy_id": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tagsSchema(), }, } } func resourceAwsIamPolicyCreate(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn var name string if v, ok := d.GetOk("name"); ok { @@ -88,9 +94,10 @@ func resourceAwsIamPolicyCreate(d *schema.ResourceData, meta interface{}) error Path: aws.String(d.Get("path").(string)), PolicyDocument: aws.String(d.Get("policy").(string)), PolicyName: aws.String(name), + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().IamTags(), } - response, err := iamconn.CreatePolicy(request) + response, err := conn.CreatePolicy(request) if err != nil { return fmt.Errorf("Error creating IAM policy %s: %s", name, err) } @@ -101,7 +108,8 @@ func resourceAwsIamPolicyCreate(d *schema.ResourceData, meta interface{}) error } func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig getPolicyRequest := &iam.GetPolicyInput{ PolicyArn: aws.String(d.Id()), @@ -112,7 +120,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { var getPolicyResponse *iam.GetPolicyOutput err := resource.Retry(1*time.Minute, func() *resource.RetryError { var err error - getPolicyResponse, err = iamconn.GetPolicy(getPolicyRequest) + getPolicyResponse, err = conn.GetPolicy(getPolicyRequest) if d.IsNewResource() && isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { return resource.RetryableError(err) @@ -125,7 +133,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { return nil }) if isResourceTimeoutError(err) { - getPolicyResponse, err = iamconn.GetPolicy(getPolicyRequest) + getPolicyResponse, err = conn.GetPolicy(getPolicyRequest) } if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { log.Printf("[WARN] IAM Policy (%s) not found, removing from state", d.Id()) @@ -143,16 +151,22 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { return nil } - d.Set("arn", getPolicyResponse.Policy.Arn) - d.Set("description", getPolicyResponse.Policy.Description) - d.Set("name", getPolicyResponse.Policy.PolicyName) - d.Set("path", getPolicyResponse.Policy.Path) + policyRes := getPolicyResponse.Policy + d.Set("arn", policyRes.Arn) + d.Set("description", policyRes.Description) + d.Set("name", policyRes.PolicyName) + d.Set("path", policyRes.Path) + d.Set("policy_id", policyRes.PolicyId) + + if err := d.Set("tags", keyvaluetags.IamKeyValueTags(policyRes.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } // Retrieve policy getPolicyVersionRequest := &iam.GetPolicyVersionInput{ PolicyArn: aws.String(d.Id()), - VersionId: getPolicyResponse.Policy.DefaultVersionId, + VersionId: policyRes.DefaultVersionId, } log.Printf("[DEBUG] Getting IAM Policy Version: %s", getPolicyVersionRequest) @@ -160,7 +174,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { var getPolicyVersionResponse *iam.GetPolicyVersionOutput err = resource.Retry(1*time.Minute, func() *resource.RetryError { var err error - getPolicyVersionResponse, err = iamconn.GetPolicyVersion(getPolicyVersionRequest) + getPolicyVersionResponse, err = conn.GetPolicyVersion(getPolicyVersionRequest) if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { return resource.RetryableError(err) @@ -173,7 +187,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { return nil }) if isResourceTimeoutError(err) { - getPolicyVersionResponse, err = iamconn.GetPolicyVersion(getPolicyVersionRequest) + getPolicyVersionResponse, err = conn.GetPolicyVersion(getPolicyVersionRequest) } if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { log.Printf("[WARN] IAM Policy (%s) not found, removing from state", d.Id()) @@ -200,29 +214,40 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { } func resourceAwsIamPolicyUpdate(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn - if err := iamPolicyPruneVersions(d.Id(), iamconn); err != nil { - return err - } + if d.HasChangeExcept("tags") { - request := &iam.CreatePolicyVersionInput{ - PolicyArn: aws.String(d.Id()), - PolicyDocument: aws.String(d.Get("policy").(string)), - SetAsDefault: aws.Bool(true), + if err := iamPolicyPruneVersions(d.Id(), conn); err != nil { + return err + } + + request := &iam.CreatePolicyVersionInput{ + PolicyArn: aws.String(d.Id()), + PolicyDocument: aws.String(d.Get("policy").(string)), + SetAsDefault: aws.Bool(true), + } + + if _, err := conn.CreatePolicyVersion(request); err != nil { + return fmt.Errorf("Error updating IAM policy %s: %s", d.Id(), err) + } } - if _, err := iamconn.CreatePolicyVersion(request); err != nil { - return fmt.Errorf("Error updating IAM policy %s: %s", d.Id(), err) + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.IamPolicyUpdateTags(conn, d.Id(), o, n); err != nil { + return fmt.Errorf("error updating tags for IAM Server Certificate (%s): %w", d.Id(), err) + } } return resourceAwsIamPolicyRead(d, meta) } func resourceAwsIamPolicyDelete(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn - if err := iamPolicyDeleteNondefaultVersions(d.Id(), iamconn); err != nil { + if err := iamPolicyDeleteNondefaultVersions(d.Id(), conn); err != nil { return err } @@ -230,7 +255,7 @@ func resourceAwsIamPolicyDelete(d *schema.ResourceData, meta interface{}) error PolicyArn: aws.String(d.Id()), } - if _, err := iamconn.DeletePolicy(request); err != nil { + if _, err := conn.DeletePolicy(request); err != nil { if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { return nil } @@ -247,8 +272,8 @@ func resourceAwsIamPolicyDelete(d *schema.ResourceData, meta interface{}) error // // The default version is never deleted. -func iamPolicyPruneVersions(arn string, iamconn *iam.IAM) error { - versions, err := iamPolicyListVersions(arn, iamconn) +func iamPolicyPruneVersions(arn string, conn *iam.IAM) error { + versions, err := iamPolicyListVersions(arn, conn) if err != nil { return err } @@ -268,12 +293,12 @@ func iamPolicyPruneVersions(arn string, iamconn *iam.IAM) error { } } - err1 := iamPolicyDeleteVersion(arn, *oldestVersion.VersionId, iamconn) + err1 := iamPolicyDeleteVersion(arn, *oldestVersion.VersionId, conn) return err1 } -func iamPolicyDeleteNondefaultVersions(arn string, iamconn *iam.IAM) error { - versions, err := iamPolicyListVersions(arn, iamconn) +func iamPolicyDeleteNondefaultVersions(arn string, conn *iam.IAM) error { + versions, err := iamPolicyListVersions(arn, conn) if err != nil { return err } @@ -282,7 +307,7 @@ func iamPolicyDeleteNondefaultVersions(arn string, iamconn *iam.IAM) error { if *version.IsDefaultVersion { continue } - if err := iamPolicyDeleteVersion(arn, *version.VersionId, iamconn); err != nil { + if err := iamPolicyDeleteVersion(arn, *version.VersionId, conn); err != nil { return err } } @@ -290,25 +315,25 @@ func iamPolicyDeleteNondefaultVersions(arn string, iamconn *iam.IAM) error { return nil } -func iamPolicyDeleteVersion(arn, versionID string, iamconn *iam.IAM) error { +func iamPolicyDeleteVersion(arn, versionID string, conn *iam.IAM) error { request := &iam.DeletePolicyVersionInput{ PolicyArn: aws.String(arn), VersionId: aws.String(versionID), } - _, err := iamconn.DeletePolicyVersion(request) + _, err := conn.DeletePolicyVersion(request) if err != nil { return fmt.Errorf("Error deleting version %s from IAM policy %s: %s", versionID, arn, err) } return nil } -func iamPolicyListVersions(arn string, iamconn *iam.IAM) ([]*iam.PolicyVersion, error) { +func iamPolicyListVersions(arn string, conn *iam.IAM) ([]*iam.PolicyVersion, error) { request := &iam.ListPolicyVersionsInput{ PolicyArn: aws.String(arn), } - response, err := iamconn.ListPolicyVersions(request) + response, err := conn.ListPolicyVersions(request) if err != nil { return nil, fmt.Errorf("Error listing versions for IAM policy %s: %s", arn, err) } diff --git a/aws/resource_aws_iam_policy_test.go b/aws/resource_aws_iam_policy_test.go index 8335b961744..7dd19fe8230 100644 --- a/aws/resource_aws_iam_policy_test.go +++ b/aws/resource_aws_iam_policy_test.go @@ -126,6 +126,8 @@ func TestAccAWSIAMPolicy_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "path", "/"), resource.TestCheckResourceAttr(resourceName, "policy", expectedPolicyText), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "policy_id"), ), }, { @@ -164,6 +166,50 @@ func TestAccAWSIAMPolicy_description(t *testing.T) { }) } +func TestAccAWSIAMPolicy_tags(t *testing.T) { + var out iam.GetPolicyOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_iam_policy.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSIAMPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIAMPolicyConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIAMPolicyExists(resourceName, &out), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSIAMPolicyConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIAMPolicyExists(resourceName, &out), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAWSIAMPolicyConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIAMPolicyExists(resourceName, &out), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + func TestAccAWSIAMPolicy_disappears(t *testing.T) { var out iam.GetPolicyOutput rName := acctest.RandomWithPrefix("tf-acc-test") @@ -179,7 +225,7 @@ func TestAccAWSIAMPolicy_disappears(t *testing.T) { Config: testAccAWSIAMPolicyConfigName(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSIAMPolicyExists(resourceName, &out), - testAccCheckAWSIAMPolicyDisappears(&out), + testAccCheckResourceDisappears(testAccProvider, resourceAwsIamPolicy(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -334,19 +380,6 @@ func testAccCheckAWSIAMPolicyDestroy(s *terraform.State) error { return nil } -func testAccCheckAWSIAMPolicyDisappears(out *iam.GetPolicyOutput) resource.TestCheckFunc { - return func(s *terraform.State) error { - iamconn := testAccProvider.Meta().(*AWSClient).iamconn - - params := &iam.DeletePolicyInput{ - PolicyArn: out.Policy.Arn, - } - - _, err := iamconn.DeletePolicy(params) - return err - } -} - func testAccAWSIAMPolicyConfigDescription(rName, description string) string { return fmt.Sprintf(` resource "aws_iam_policy" "test" { @@ -449,3 +482,58 @@ resource "aws_iam_policy" "test" { } `, rName, policy) } + +func testAccAWSIAMPolicyConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_iam_policy" "test" { + name = %q + + policy = < Date: Fri, 19 Mar 2021 09:50:21 +0200 Subject: [PATCH 02/10] changelog --- .changelog/18276.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/18276.txt diff --git a/.changelog/18276.txt b/.changelog/18276.txt new file mode 100644 index 00000000000..eff02141b8b --- /dev/null +++ b/.changelog/18276.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/iam_policy: Add tagging support +``` \ No newline at end of file From 8446a93763b754b72aff1785c33f22002d16fea3 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Fri, 19 Mar 2021 09:51:09 +0200 Subject: [PATCH 03/10] changelog --- .changelog/18276.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.changelog/18276.txt b/.changelog/18276.txt index eff02141b8b..5fe2f60db60 100644 --- a/.changelog/18276.txt +++ b/.changelog/18276.txt @@ -1,3 +1,7 @@ ```release-note:enhancement resource/iam_policy: Add tagging support +``` + +```release-note:enhancement +resource/iam_policy: Add `policy_id` attribute ``` \ No newline at end of file From 2e8105acd15b9c47f50d0812796e903d36394caa Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Fri, 19 Mar 2021 09:55:13 +0200 Subject: [PATCH 04/10] minor error changes --- aws/resource_aws_iam_policy.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index a78bc29a637..c769d2b60c0 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -99,7 +99,7 @@ func resourceAwsIamPolicyCreate(d *schema.ResourceData, meta interface{}) error response, err := conn.CreatePolicy(request) if err != nil { - return fmt.Errorf("Error creating IAM policy %s: %s", name, err) + return fmt.Errorf("Error creating IAM policy %s: %w", name, err) } d.SetId(aws.StringValue(response.Policy.Arn)) @@ -142,7 +142,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { } if err != nil { - return fmt.Errorf("Error reading IAM policy %s: %s", d.Id(), err) + return fmt.Errorf("Error reading IAM policy %s: %w", d.Id(), err) } if getPolicyResponse == nil || getPolicyResponse.Policy == nil { @@ -196,7 +196,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { } if err != nil { - return fmt.Errorf("Error reading IAM policy version %s: %s", d.Id(), err) + return fmt.Errorf("Error reading IAM policy version %s: %w", d.Id(), err) } policy := "" @@ -204,7 +204,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { var err error policy, err = url.QueryUnescape(aws.StringValue(getPolicyVersionResponse.PolicyVersion.Document)) if err != nil { - return fmt.Errorf("error parsing policy: %s", err) + return fmt.Errorf("error parsing policy: %w", err) } } @@ -229,7 +229,7 @@ func resourceAwsIamPolicyUpdate(d *schema.ResourceData, meta interface{}) error } if _, err := conn.CreatePolicyVersion(request); err != nil { - return fmt.Errorf("Error updating IAM policy %s: %s", d.Id(), err) + return fmt.Errorf("Error updating IAM policy %s: %w", d.Id(), err) } } @@ -237,7 +237,7 @@ func resourceAwsIamPolicyUpdate(d *schema.ResourceData, meta interface{}) error o, n := d.GetChange("tags") if err := keyvaluetags.IamPolicyUpdateTags(conn, d.Id(), o, n); err != nil { - return fmt.Errorf("error updating tags for IAM Server Certificate (%s): %w", d.Id(), err) + return fmt.Errorf("error updating tags for IAM Policy (%s): %w", d.Id(), err) } } @@ -259,7 +259,7 @@ func resourceAwsIamPolicyDelete(d *schema.ResourceData, meta interface{}) error if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { return nil } - return fmt.Errorf("Error deleting IAM policy %s: %s", d.Id(), err) + return fmt.Errorf("Error deleting IAM policy %s: %w", d.Id(), err) } return nil @@ -323,7 +323,7 @@ func iamPolicyDeleteVersion(arn, versionID string, conn *iam.IAM) error { _, err := conn.DeletePolicyVersion(request) if err != nil { - return fmt.Errorf("Error deleting version %s from IAM policy %s: %s", versionID, arn, err) + return fmt.Errorf("Error deleting version %s from IAM policy %s: %w", versionID, arn, err) } return nil } @@ -335,7 +335,7 @@ func iamPolicyListVersions(arn string, conn *iam.IAM) ([]*iam.PolicyVersion, err response, err := conn.ListPolicyVersions(request) if err != nil { - return nil, fmt.Errorf("Error listing versions for IAM policy %s: %s", arn, err) + return nil, fmt.Errorf("Error listing versions for IAM policy %s: %w", arn, err) } return response.Versions, nil } From 92e0394c56f80ea9d0abf6c2d68397820cdb6186 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Fri, 19 Mar 2021 10:00:06 +0200 Subject: [PATCH 05/10] iam policy data source --- .changelog/18276.txt | 4 ++++ aws/data_source_aws_iam_policy.go | 5 +++++ aws/data_source_aws_iam_policy_test.go | 15 +++++++++------ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.changelog/18276.txt b/.changelog/18276.txt index 5fe2f60db60..e96608c85e1 100644 --- a/.changelog/18276.txt +++ b/.changelog/18276.txt @@ -4,4 +4,8 @@ resource/iam_policy: Add tagging support ```release-note:enhancement resource/iam_policy: Add `policy_id` attribute +``` + +```release-note:enhancement +data-source/iam_policy: Add `policy_id` and `tags` attributes ``` \ No newline at end of file diff --git a/aws/data_source_aws_iam_policy.go b/aws/data_source_aws_iam_policy.go index 8e2d3fdd161..a4d6637cb50 100644 --- a/aws/data_source_aws_iam_policy.go +++ b/aws/data_source_aws_iam_policy.go @@ -30,6 +30,11 @@ func dataSourceAwsIAMPolicy() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "policy_id": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tagsSchema(), }, } } diff --git a/aws/data_source_aws_iam_policy_test.go b/aws/data_source_aws_iam_policy_test.go index c78712bb513..7bff6fdbe0e 100644 --- a/aws/data_source_aws_iam_policy_test.go +++ b/aws/data_source_aws_iam_policy_test.go @@ -9,7 +9,8 @@ import ( ) func TestAccAWSDataSourceIAMPolicy_basic(t *testing.T) { - resourceName := "data.aws_iam_policy.test" + datasourceName := "data.aws_iam_policy.test" + resourceName := "aws_iam_policy.test_policy" policyName := fmt.Sprintf("test-policy-%s", acctest.RandString(10)) resource.ParallelTest(t, resource.TestCase{ @@ -19,11 +20,13 @@ func TestAccAWSDataSourceIAMPolicy_basic(t *testing.T) { { Config: testAccAwsDataSourceIamPolicyConfig(policyName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", policyName), - resource.TestCheckResourceAttr(resourceName, "description", "My test policy"), - resource.TestCheckResourceAttr(resourceName, "path", "/"), - resource.TestCheckResourceAttrSet(resourceName, "policy"), - resource.TestCheckResourceAttrPair(resourceName, "arn", "aws_iam_policy.test_policy", "arn"), + resource.TestCheckResourceAttr(datasourceName, "name", policyName), + resource.TestCheckResourceAttr(datasourceName, "description", "My test policy"), + resource.TestCheckResourceAttr(datasourceName, "path", "/"), + resource.TestCheckResourceAttrSet(datasourceName, "policy"), + resource.TestCheckResourceAttrSet(datasourceName, "policy_id"), + resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(datasourceName, "tags", resourceName, "tags"), ), }, }, From b397de0d45360af3bfcc3eaf291599e9b68582e0 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Fri, 19 Mar 2021 10:04:47 +0200 Subject: [PATCH 06/10] iam policy data source --- aws/data_source_aws_iam_policy_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/aws/data_source_aws_iam_policy_test.go b/aws/data_source_aws_iam_policy_test.go index 7bff6fdbe0e..d08dcb35c91 100644 --- a/aws/data_source_aws_iam_policy_test.go +++ b/aws/data_source_aws_iam_policy_test.go @@ -10,7 +10,7 @@ import ( func TestAccAWSDataSourceIAMPolicy_basic(t *testing.T) { datasourceName := "data.aws_iam_policy.test" - resourceName := "aws_iam_policy.test_policy" + resourceName := "aws_iam_policy.test" policyName := fmt.Sprintf("test-policy-%s", acctest.RandString(10)) resource.ParallelTest(t, resource.TestCase{ @@ -20,11 +20,11 @@ func TestAccAWSDataSourceIAMPolicy_basic(t *testing.T) { { Config: testAccAwsDataSourceIamPolicyConfig(policyName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(datasourceName, "name", policyName), - resource.TestCheckResourceAttr(datasourceName, "description", "My test policy"), - resource.TestCheckResourceAttr(datasourceName, "path", "/"), - resource.TestCheckResourceAttrSet(datasourceName, "policy"), - resource.TestCheckResourceAttrSet(datasourceName, "policy_id"), + resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(datasourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(datasourceName, "path", resourceName, "path"), + resource.TestCheckResourceAttrPair(datasourceName, "policy", resourceName, "policy"), + resource.TestCheckResourceAttrPair(datasourceName, "policy_id", resourceName, "policy_id"), resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), resource.TestCheckResourceAttrPair(datasourceName, "tags", resourceName, "tags"), ), @@ -36,7 +36,7 @@ func TestAccAWSDataSourceIAMPolicy_basic(t *testing.T) { func testAccAwsDataSourceIamPolicyConfig(policyName string) string { return fmt.Sprintf(` -resource "aws_iam_policy" "test_policy" { +resource "aws_iam_policy" "test" { name = "%s" path = "/" description = "My test policy" @@ -58,7 +58,7 @@ EOF } data "aws_iam_policy" "test" { - arn = aws_iam_policy.test_policy.arn + arn = aws_iam_policy.test.arn } `, policyName) } From 881083c1f300a3c141ec64314615f9b58cba6ae8 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Fri, 19 Mar 2021 13:09:04 +0200 Subject: [PATCH 07/10] docs --- website/docs/d/iam_policy.html.markdown | 2 ++ website/docs/r/iam_policy.html.markdown | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/website/docs/d/iam_policy.html.markdown b/website/docs/d/iam_policy.html.markdown index 8014258bb36..7ff5c976992 100644 --- a/website/docs/d/iam_policy.html.markdown +++ b/website/docs/d/iam_policy.html.markdown @@ -30,4 +30,6 @@ data "aws_iam_policy" "example" { * `path` - The path to the policy. * `description` - The description of the policy. * `policy` - The policy document of the policy. +* `policy_id` - The policy's ID. +* `tags` - Key-value mapping of tags for the IAM Policy diff --git a/website/docs/r/iam_policy.html.markdown b/website/docs/r/iam_policy.html.markdown index 4a0d2450716..7cc5f00903a 100644 --- a/website/docs/r/iam_policy.html.markdown +++ b/website/docs/r/iam_policy.html.markdown @@ -45,17 +45,19 @@ The following arguments are supported: * `path` - (Optional, default "/") Path in which to create the policy. See [IAM Identifiers](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) for more information. * `policy` - (Required) The policy document. This is a JSON formatted string. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](https://learn.hashicorp.com/terraform/aws/iam-policy) +* `tags` - Key-value mapping of tags for the IAM Policy ## Attributes Reference In addition to all arguments above, the following attributes are exported: -* `id` - The policy's ID. +* `id` - The ARN assigned by AWS to this policy. * `arn` - The ARN assigned by AWS to this policy. * `description` - The description of the policy. * `name` - The name of the policy. * `path` - The path of the policy in IAM. * `policy` - The policy document. +* `policy_id` - The policy's ID. ## Import From 46a3be7bc2a6245d337277a35d1577945ad02f39 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Fri, 26 Mar 2021 12:01:23 +0300 Subject: [PATCH 08/10] Apply suggestions from code review Co-authored-by: Kit Ewbank --- aws/data_source_aws_iam_policy.go | 2 +- aws/resource_aws_iam_policy.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/data_source_aws_iam_policy.go b/aws/data_source_aws_iam_policy.go index a4d6637cb50..3a2233aac96 100644 --- a/aws/data_source_aws_iam_policy.go +++ b/aws/data_source_aws_iam_policy.go @@ -34,7 +34,7 @@ func dataSourceAwsIAMPolicy() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "tags": tagsSchemaComputed(), }, } } diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index c769d2b60c0..c200060727b 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -293,7 +293,7 @@ func iamPolicyPruneVersions(arn string, conn *iam.IAM) error { } } - err1 := iamPolicyDeleteVersion(arn, *oldestVersion.VersionId, conn) + err1 := iamPolicyDeleteVersion(arn, aws.StringValue(oldestVersion.VersionId), conn) return err1 } @@ -307,7 +307,7 @@ func iamPolicyDeleteNondefaultVersions(arn string, conn *iam.IAM) error { if *version.IsDefaultVersion { continue } - if err := iamPolicyDeleteVersion(arn, *version.VersionId, conn); err != nil { + if err := iamPolicyDeleteVersion(arn, aws.StringValue(version.VersionId), conn); err != nil { return err } } From c2640d064dd73c1e766b29c89a8ec0f1075944f5 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Fri, 26 Mar 2021 13:07:21 -0400 Subject: [PATCH 09/10] Apply suggestions from code review --- .changelog/18276.txt | 8 ++++---- website/docs/r/iam_policy.html.markdown | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.changelog/18276.txt b/.changelog/18276.txt index e96608c85e1..b94e07e663c 100644 --- a/.changelog/18276.txt +++ b/.changelog/18276.txt @@ -1,11 +1,11 @@ ```release-note:enhancement -resource/iam_policy: Add tagging support +resource/aws_iam_policy: Add tagging support ``` ```release-note:enhancement -resource/iam_policy: Add `policy_id` attribute +resource/aws_iam_policy: Add `policy_id` attribute ``` ```release-note:enhancement -data-source/iam_policy: Add `policy_id` and `tags` attributes -``` \ No newline at end of file +data-source/aws_iam_policy: Add `policy_id` and `tags` attributes +``` diff --git a/website/docs/r/iam_policy.html.markdown b/website/docs/r/iam_policy.html.markdown index 7cc5f00903a..c541ed680bf 100644 --- a/website/docs/r/iam_policy.html.markdown +++ b/website/docs/r/iam_policy.html.markdown @@ -45,7 +45,7 @@ The following arguments are supported: * `path` - (Optional, default "/") Path in which to create the policy. See [IAM Identifiers](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) for more information. * `policy` - (Required) The policy document. This is a JSON formatted string. For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](https://learn.hashicorp.com/terraform/aws/iam-policy) -* `tags` - Key-value mapping of tags for the IAM Policy +* `tags` - (Optional) Map of resource tags for the IAM Policy ## Attributes Reference From 736c4e13c1b4bc73c8a9c00398f7a74fe1be71e4 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Fri, 26 Mar 2021 13:22:47 -0400 Subject: [PATCH 10/10] Update aws/resource_aws_iam_policy_test.go --- aws/resource_aws_iam_policy_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/resource_aws_iam_policy_test.go b/aws/resource_aws_iam_policy_test.go index 7dd19fe8230..584c617ee84 100644 --- a/aws/resource_aws_iam_policy_test.go +++ b/aws/resource_aws_iam_policy_test.go @@ -173,6 +173,7 @@ func TestAccAWSIAMPolicy_tags(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, iam.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSIAMPolicyDestroy, Steps: []resource.TestStep{