From dd12f019d64760d0ec447b8f4e30dc4cd0751559 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Fri, 9 Apr 2021 15:24:48 -0400 Subject: [PATCH 1/4] provider: Support default tags (resources aws_i*) Reference: https://github.com/hashicorp/terraform-provider-aws/issues/7926 --- aws/resource_aws_iam_instance_profile.go | 13 ++++++--- ...esource_aws_iam_openid_connect_provider.go | 23 ++++++++++++---- aws/resource_aws_iam_policy.go | 25 ++++++++++++----- aws/resource_aws_iam_role.go | 27 ++++++++++++++----- aws/resource_aws_iam_saml_provider.go | 25 ++++++++++++----- aws/resource_aws_iam_server_certificate.go | 23 ++++++++++++---- aws/resource_aws_iam_user.go | 27 ++++++++++++++----- aws/resource_aws_imagebuilder_component.go | 25 ++++++++++++----- ...imagebuilder_distribution_configuration.go | 27 ++++++++++++++----- aws/resource_aws_imagebuilder_image.go | 15 +++++++---- ...esource_aws_imagebuilder_image_pipeline.go | 15 +++++++---- aws/resource_aws_imagebuilder_image_recipe.go | 27 ++++++++++++++----- ...agebuilder_infrastructure_configuration.go | 27 ++++++++++++++----- ...ource_aws_inspector_assessment_template.go | 27 ++++++++++++++----- aws/resource_aws_instance.go | 25 ++++++++++++----- aws/resource_aws_internet_gateway.go | 25 ++++++++++++----- aws/resource_aws_iot_topic_rule.go | 25 ++++++++++++----- 17 files changed, 302 insertions(+), 99 deletions(-) diff --git a/aws/resource_aws_iam_instance_profile.go b/aws/resource_aws_iam_instance_profile.go index 0dc6969d9532..7bd62f704c5a 100644 --- a/aws/resource_aws_iam_instance_profile.go +++ b/aws/resource_aws_iam_instance_profile.go @@ -69,13 +69,18 @@ func resourceAwsIamInstanceProfile() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsIamInstanceProfileCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) var name string if v, ok := d.GetOk("name"); ok { @@ -89,7 +94,7 @@ func resourceAwsIamInstanceProfileCreate(d *schema.ResourceData, meta interface{ request := &iam.CreateInstanceProfileInput{ InstanceProfileName: aws.String(name), Path: aws.String(d.Get("path").(string)), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().IamTags(), + Tags: tags.IgnoreAws().IamTags(), } var err error @@ -190,8 +195,8 @@ func resourceAwsIamInstanceProfileUpdate(d *schema.ResourceData, meta interface{ } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IamInstanceProfileUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for IAM Instance Profile (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_iam_openid_connect_provider.go b/aws/resource_aws_iam_openid_connect_provider.go index dadae698b747..577281b5745e 100644 --- a/aws/resource_aws_iam_openid_connect_provider.go +++ b/aws/resource_aws_iam_openid_connect_provider.go @@ -50,19 +50,24 @@ func resourceAwsIamOpenIDConnectProvider() *schema.Resource { Type: schema.TypeList, Required: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsIamOpenIDConnectProviderCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &iam.CreateOpenIDConnectProviderInput{ Url: aws.String(d.Get("url").(string)), ClientIDList: expandStringList(d.Get("client_id_list").([]interface{})), ThumbprintList: expandStringList(d.Get("thumbprint_list").([]interface{})), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().IamTags(), + Tags: tags.IgnoreAws().IamTags(), } out, err := conn.CreateOpenIDConnectProvider(input) @@ -77,6 +82,7 @@ func resourceAwsIamOpenIDConnectProviderCreate(d *schema.ResourceData, meta inte func resourceAwsIamOpenIDConnectProviderRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &iam.GetOpenIDConnectProviderInput{ @@ -97,10 +103,17 @@ func resourceAwsIamOpenIDConnectProviderRead(d *schema.ResourceData, meta interf d.Set("client_id_list", flattenStringList(out.ClientIDList)) d.Set("thumbprint_list", flattenStringList(out.ThumbprintList)) - if err := d.Set("tags", keyvaluetags.IamKeyValueTags(out.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + tags := keyvaluetags.IamKeyValueTags(out.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) } + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + return nil } @@ -119,8 +132,8 @@ func resourceAwsIamOpenIDConnectProviderUpdate(d *schema.ResourceData, meta inte } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IamOpenIDConnectProviderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for IAM OIDC Provider (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index ef7c52a25fff..16c8e2a6477e 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -72,13 +72,18 @@ func resourceAwsIamPolicy() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsIamPolicyCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) var name string if v, ok := d.GetOk("name"); ok { @@ -94,7 +99,7 @@ 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(), + Tags: tags.IgnoreAws().IamTags(), } response, err := conn.CreatePolicy(request) @@ -109,6 +114,7 @@ func resourceAwsIamPolicyCreate(d *schema.ResourceData, meta interface{}) error func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig getPolicyRequest := &iam.GetPolicyInput{ @@ -158,10 +164,17 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { 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 { + tags := keyvaluetags.IamKeyValueTags(policyRes.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) } + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + // Retrieve policy getPolicyVersionRequest := &iam.GetPolicyVersionInput{ @@ -216,7 +229,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { func resourceAwsIamPolicyUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn - if d.HasChangeExcept("tags") { + if d.HasChangesExcept("tags", "tags_all") { if err := iamPolicyPruneVersions(d.Id(), conn); err != nil { return err @@ -233,8 +246,8 @@ func resourceAwsIamPolicyUpdate(d *schema.ResourceData, meta interface{}) error } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IamPolicyUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for IAM Policy (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_iam_role.go b/aws/resource_aws_iam_role.go index 0df27bbe12ae..d19cd23568d6 100644 --- a/aws/resource_aws_iam_role.go +++ b/aws/resource_aws_iam_role.go @@ -110,7 +110,8 @@ func resourceAwsIamRole() *schema.Resource { ValidateFunc: validation.IntBetween(3600, 43200), }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "inline_policy": { Type: schema.TypeSet, @@ -144,6 +145,8 @@ func resourceAwsIamRole() *schema.Resource { Set: schema.HashString, }, }, + + CustomizeDiff: SetTagsDiff, } } @@ -155,6 +158,8 @@ func resourceAwsIamRoleImport( func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) var name string if v, ok := d.GetOk("name"); ok { @@ -183,8 +188,8 @@ func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error { request.PermissionsBoundary = aws.String(v.(string)) } - if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { - request.Tags = keyvaluetags.New(v).IgnoreAws().IamTags() + if len(tags) > 0 { + request.Tags = tags.IgnoreAws().IamTags() } var createResp *iam.CreateRoleOutput @@ -230,6 +235,7 @@ func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error { func resourceAwsIamRoleRead(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig request := &iam.GetRoleInput{ @@ -287,8 +293,15 @@ func resourceAwsIamRoleRead(d *schema.ResourceData, meta interface{}) error { } d.Set("unique_id", role.RoleId) - if err := d.Set("tags", keyvaluetags.IamKeyValueTags(role.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + tags := keyvaluetags.IamKeyValueTags(role.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) } assumeRolePolicy, err := url.QueryUnescape(*role.AssumeRolePolicyDocument) @@ -386,8 +399,8 @@ func resourceAwsIamRoleUpdate(d *schema.ResourceData, meta interface{}) error { } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IamRoleUpdateTags(iamconn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating IAM Role (%s) tags: %s", d.Id(), err) diff --git a/aws/resource_aws_iam_saml_provider.go b/aws/resource_aws_iam_saml_provider.go index dccb51c9d458..951eebbc785d 100644 --- a/aws/resource_aws_iam_saml_provider.go +++ b/aws/resource_aws_iam_saml_provider.go @@ -45,18 +45,23 @@ func resourceAwsIamSamlProvider() *schema.Resource { Required: true, ValidateFunc: validation.StringLenBetween(1000, 10000000), }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsIamSamlProviderCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &iam.CreateSAMLProviderInput{ Name: aws.String(d.Get("name").(string)), SAMLMetadataDocument: aws.String(d.Get("saml_metadata_document").(string)), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().IamTags(), + Tags: tags.IgnoreAws().IamTags(), } out, err := conn.CreateSAMLProvider(input) @@ -71,6 +76,7 @@ func resourceAwsIamSamlProviderCreate(d *schema.ResourceData, meta interface{}) func resourceAwsIamSamlProviderRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &iam.GetSAMLProviderInput{ @@ -95,17 +101,24 @@ func resourceAwsIamSamlProviderRead(d *schema.ResourceData, meta interface{}) er d.Set("valid_until", out.ValidUntil.Format(time.RFC1123)) d.Set("saml_metadata_document", out.SAMLMetadataDocument) - if err := d.Set("tags", keyvaluetags.IamKeyValueTags(out.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + tags := keyvaluetags.IamKeyValueTags(out.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) } + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + return nil } func resourceAwsIamSamlProviderUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn - if d.HasChangeExcept("tags") { + if d.HasChangesExcept("tags", "tags_all") { input := &iam.UpdateSAMLProviderInput{ SAMLProviderArn: aws.String(d.Id()), SAMLMetadataDocument: aws.String(d.Get("saml_metadata_document").(string)), @@ -116,8 +129,8 @@ func resourceAwsIamSamlProviderUpdate(d *schema.ResourceData, meta interface{}) } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IamSAMLProviderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for IAM SAML Provider (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_iam_server_certificate.go b/aws/resource_aws_iam_server_certificate.go index 3c95305659ff..14dbcf34f80d 100644 --- a/aws/resource_aws_iam_server_certificate.go +++ b/aws/resource_aws_iam_server_certificate.go @@ -91,13 +91,18 @@ func resourceAwsIAMServerCertificate() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) var sslCertName string if v, ok := d.GetOk("name"); ok { @@ -112,7 +117,7 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac CertificateBody: aws.String(d.Get("certificate_body").(string)), PrivateKey: aws.String(d.Get("private_key").(string)), ServerCertificateName: aws.String(sslCertName), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().IamTags(), + Tags: tags.IgnoreAws().IamTags(), } if v, ok := d.GetOk("certificate_chain"); ok { @@ -137,6 +142,7 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig resp, err := conn.GetServerCertificate(&iam.GetServerCertificateInput{ @@ -173,18 +179,25 @@ func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{ d.Set("upload_date", nil) } - if err := d.Set("tags", keyvaluetags.IamKeyValueTags(cert.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + tags := keyvaluetags.IamKeyValueTags(cert.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) } + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + return nil } func resourceAwsIAMServerCertificateUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IamServerCertificateUpdateTags(conn, d.Get("name").(string), o, n); err != nil { return fmt.Errorf("error updating tags for IAM Server Certificate (%s): %w", d.Get("name").(string), err) diff --git a/aws/resource_aws_iam_user.go b/aws/resource_aws_iam_user.go index 18de1a356a4f..91acdc2899fe 100644 --- a/aws/resource_aws_iam_user.go +++ b/aws/resource_aws_iam_user.go @@ -67,13 +67,18 @@ func resourceAwsIamUser() *schema.Resource { Default: false, Description: "Delete user even if it has non-Terraform-managed IAM access keys, login profile or MFA devices", }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) name := d.Get("name").(string) path := d.Get("path").(string) @@ -86,8 +91,8 @@ func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error { request.PermissionsBoundary = aws.String(v.(string)) } - if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { - request.Tags = keyvaluetags.New(v).IgnoreAws().IamTags() + if len(tags) > 0 { + request.Tags = tags.IgnoreAws().IamTags() } log.Println("[DEBUG] Create IAM User request:", request) @@ -103,6 +108,7 @@ func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error { func resourceAwsIamUserRead(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig request := &iam.GetUserInput{ @@ -153,8 +159,15 @@ func resourceAwsIamUserRead(d *schema.ResourceData, meta interface{}) error { } d.Set("unique_id", output.User.UserId) - if err := d.Set("tags", keyvaluetags.IamKeyValueTags(output.User.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + tags := keyvaluetags.IamKeyValueTags(output.User.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) } return nil @@ -209,8 +222,8 @@ func resourceAwsIamUserUpdate(d *schema.ResourceData, meta interface{}) error { } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IamUserUpdateTags(iamconn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating IAM User (%s) tags: %s", d.Id(), err) diff --git a/aws/resource_aws_imagebuilder_component.go b/aws/resource_aws_imagebuilder_component.go index 59fa135e2421..5cc867b7ac2e 100644 --- a/aws/resource_aws_imagebuilder_component.go +++ b/aws/resource_aws_imagebuilder_component.go @@ -89,7 +89,8 @@ func resourceAwsImageBuilderComponent() *schema.Resource { MinItems: 1, MaxItems: 25, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "type": { Type: schema.TypeString, Computed: true, @@ -107,11 +108,15 @@ func resourceAwsImageBuilderComponent() *schema.Resource { ValidateFunc: validation.StringLenBetween(1, 128), }, }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsImageBuilderComponentCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &imagebuilder.CreateComponentInput{ ClientToken: aws.String(resource.UniqueId()), @@ -145,8 +150,8 @@ func resourceAwsImageBuilderComponentCreate(d *schema.ResourceData, meta interfa input.SupportedOsVersions = expandStringSet(v.(*schema.Set)) } - if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 { - input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().ImagebuilderTags() + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().ImagebuilderTags() } if v, ok := d.GetOk("uri"); ok { @@ -174,6 +179,7 @@ func resourceAwsImageBuilderComponentCreate(d *schema.ResourceData, meta interfa func resourceAwsImageBuilderComponentRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &imagebuilder.GetComponentInput{ @@ -210,10 +216,17 @@ func resourceAwsImageBuilderComponentRead(d *schema.ResourceData, meta interface d.Set("platform", component.Platform) d.Set("supported_os_versions", aws.StringValueSlice(component.SupportedOsVersions)) - if err := d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(component.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + tags := keyvaluetags.ImagebuilderKeyValueTags(component.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) } + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + d.Set("type", component.Type) d.Set("version", component.Version) @@ -223,8 +236,8 @@ func resourceAwsImageBuilderComponentRead(d *schema.ResourceData, meta interface func resourceAwsImageBuilderComponentUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.ImagebuilderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for Image Builder Component (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_imagebuilder_distribution_configuration.go b/aws/resource_aws_imagebuilder_distribution_configuration.go index 05365f2baf84..335491ed9f8b 100644 --- a/aws/resource_aws_imagebuilder_distribution_configuration.go +++ b/aws/resource_aws_imagebuilder_distribution_configuration.go @@ -131,13 +131,18 @@ func resourceAwsImageBuilderDistributionConfiguration() *schema.Resource { ForceNew: true, ValidateFunc: validation.StringLenBetween(1, 126), }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsImageBuilderDistributionConfigurationCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &imagebuilder.CreateDistributionConfigurationInput{ ClientToken: aws.String(resource.UniqueId()), @@ -155,8 +160,8 @@ func resourceAwsImageBuilderDistributionConfigurationCreate(d *schema.ResourceDa input.Name = aws.String(v.(string)) } - if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 { - input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().ImagebuilderTags() + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().ImagebuilderTags() } output, err := conn.CreateDistributionConfiguration(input) @@ -176,6 +181,7 @@ func resourceAwsImageBuilderDistributionConfigurationCreate(d *schema.ResourceDa func resourceAwsImageBuilderDistributionConfigurationRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &imagebuilder.GetDistributionConfigurationInput{ @@ -206,7 +212,16 @@ func resourceAwsImageBuilderDistributionConfigurationRead(d *schema.ResourceData d.Set("description", distributionConfiguration.Description) d.Set("distribution", flattenImageBuilderDistributions(distributionConfiguration.Distributions)) d.Set("name", distributionConfiguration.Name) - d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(distributionConfiguration.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()) + tags := keyvaluetags.ImagebuilderKeyValueTags(distributionConfiguration.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } return nil } @@ -235,8 +250,8 @@ func resourceAwsImageBuilderDistributionConfigurationUpdate(d *schema.ResourceDa } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.ImagebuilderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for Image Builder Distribution Configuration (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_imagebuilder_image.go b/aws/resource_aws_imagebuilder_image.go index 99c3f3128d7a..18d5a564b180 100644 --- a/aws/resource_aws_imagebuilder_image.go +++ b/aws/resource_aws_imagebuilder_image.go @@ -134,17 +134,22 @@ func resourceAwsImageBuilderImage() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "version": { Type: schema.TypeString, Computed: true, }, }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsImageBuilderImageCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &imagebuilder.CreateImageInput{ ClientToken: aws.String(resource.UniqueId()), @@ -167,8 +172,8 @@ func resourceAwsImageBuilderImageCreate(d *schema.ResourceData, meta interface{} input.InfrastructureConfigurationArn = aws.String(v.(string)) } - if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 { - input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().ImagebuilderTags() + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().ImagebuilderTags() } output, err := conn.CreateImage(input) @@ -257,8 +262,8 @@ func resourceAwsImageBuilderImageRead(d *schema.ResourceData, meta interface{}) func resourceAwsImageBuilderImageUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.ImagebuilderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for Image Builder Image (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_imagebuilder_image_pipeline.go b/aws/resource_aws_imagebuilder_image_pipeline.go index d0e342e6a8fa..d40369883386 100644 --- a/aws/resource_aws_imagebuilder_image_pipeline.go +++ b/aws/resource_aws_imagebuilder_image_pipeline.go @@ -127,13 +127,18 @@ func resourceAwsImageBuilderImagePipeline() *schema.Resource { Default: imagebuilder.PipelineStatusEnabled, ValidateFunc: validation.StringInSlice(imagebuilder.PipelineStatus_Values(), false), }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsImageBuilderImagePipelineCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &imagebuilder.CreateImagePipelineInput{ ClientToken: aws.String(resource.UniqueId()), @@ -172,8 +177,8 @@ func resourceAwsImageBuilderImagePipelineCreate(d *schema.ResourceData, meta int input.Status = aws.String(v.(string)) } - if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 { - input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().ImagebuilderTags() + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().ImagebuilderTags() } output, err := conn.CreateImagePipeline(input) @@ -302,8 +307,8 @@ func resourceAwsImageBuilderImagePipelineUpdate(d *schema.ResourceData, meta int } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.ImagebuilderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for Image Builder Image Pipeline (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_imagebuilder_image_recipe.go b/aws/resource_aws_imagebuilder_image_recipe.go index 2f5687a4543a..9148ee4a4b0c 100644 --- a/aws/resource_aws_imagebuilder_image_recipe.go +++ b/aws/resource_aws_imagebuilder_image_recipe.go @@ -165,7 +165,8 @@ func resourceAwsImageBuilderImageRecipe() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "version": { Type: schema.TypeString, Required: true, @@ -179,11 +180,15 @@ func resourceAwsImageBuilderImageRecipe() *schema.Resource { ValidateFunc: validation.StringLenBetween(1, 1024), }, }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsImageBuilderImageRecipeCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &imagebuilder.CreateImageRecipeInput{ ClientToken: aws.String(resource.UniqueId()), @@ -209,8 +214,8 @@ func resourceAwsImageBuilderImageRecipeCreate(d *schema.ResourceData, meta inter input.ParentImage = aws.String(v.(string)) } - if v, ok := d.GetOk("tags"); ok { - input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().ImagebuilderTags() + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().ImagebuilderTags() } if v, ok := d.GetOk("version"); ok { @@ -237,6 +242,7 @@ func resourceAwsImageBuilderImageRecipeCreate(d *schema.ResourceData, meta inter func resourceAwsImageBuilderImageRecipeRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &imagebuilder.GetImageRecipeInput{ @@ -270,7 +276,16 @@ func resourceAwsImageBuilderImageRecipeRead(d *schema.ResourceData, meta interfa d.Set("owner", imageRecipe.Owner) d.Set("parent_image", imageRecipe.ParentImage) d.Set("platform", imageRecipe.Platform) - d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(imageRecipe.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()) + tags := keyvaluetags.ImagebuilderKeyValueTags(imageRecipe.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } d.Set("version", imageRecipe.Version) d.Set("working_directory", imageRecipe.WorkingDirectory) @@ -280,8 +295,8 @@ func resourceAwsImageBuilderImageRecipeRead(d *schema.ResourceData, meta interfa func resourceAwsImageBuilderImageRecipeUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.ImagebuilderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for Image Builder Image Recipe (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_imagebuilder_infrastructure_configuration.go b/aws/resource_aws_imagebuilder_infrastructure_configuration.go index e0b3148f4c09..b2d22e530765 100644 --- a/aws/resource_aws_imagebuilder_infrastructure_configuration.go +++ b/aws/resource_aws_imagebuilder_infrastructure_configuration.go @@ -110,18 +110,23 @@ func resourceAwsImageBuilderInfrastructureConfiguration() *schema.Resource { Optional: true, ValidateFunc: validation.StringLenBetween(1, 1024), }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "terminate_instance_on_failure": { Type: schema.TypeBool, Optional: true, Default: false, }, }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsImageBuilderInfrastructureConfigurationCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &imagebuilder.CreateInfrastructureConfigurationInput{ ClientToken: aws.String(resource.UniqueId()), @@ -167,8 +172,8 @@ func resourceAwsImageBuilderInfrastructureConfigurationCreate(d *schema.Resource input.SubnetId = aws.String(v.(string)) } - if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 { - input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().ImagebuilderTags() + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().ImagebuilderTags() } if v, ok := d.GetOk("terminate_instance_on_failure"); ok { @@ -211,6 +216,7 @@ func resourceAwsImageBuilderInfrastructureConfigurationCreate(d *schema.Resource func resourceAwsImageBuilderInfrastructureConfigurationRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &imagebuilder.GetInfrastructureConfigurationInput{ @@ -252,7 +258,16 @@ func resourceAwsImageBuilderInfrastructureConfigurationRead(d *schema.ResourceDa d.Set("security_group_ids", aws.StringValueSlice(infrastructureConfiguration.SecurityGroupIds)) d.Set("sns_topic_arn", infrastructureConfiguration.SnsTopicArn) d.Set("subnet_id", infrastructureConfiguration.SubnetId) - d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(infrastructureConfiguration.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()) + tags := keyvaluetags.ImagebuilderKeyValueTags(infrastructureConfiguration.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } d.Set("terminate_instance_on_failure", infrastructureConfiguration.TerminateInstanceOnFailure) return nil @@ -340,8 +355,8 @@ func resourceAwsImageBuilderInfrastructureConfigurationUpdate(d *schema.Resource } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.ImagebuilderUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags for Image Builder Infrastructure Configuration (%s): %w", d.Id(), err) diff --git a/aws/resource_aws_inspector_assessment_template.go b/aws/resource_aws_inspector_assessment_template.go index f83eaaed4e7f..b2a8158d5de6 100644 --- a/aws/resource_aws_inspector_assessment_template.go +++ b/aws/resource_aws_inspector_assessment_template.go @@ -48,13 +48,18 @@ func resourceAWSInspectorAssessmentTemplate() *schema.Resource { Required: true, ForceNew: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsInspectorAssessmentTemplateCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).inspectorconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) req := &inspector.CreateAssessmentTemplateInput{ AssessmentTargetArn: aws.String(d.Get("target_arn").(string)), @@ -71,8 +76,8 @@ func resourceAwsInspectorAssessmentTemplateCreate(d *schema.ResourceData, meta i d.SetId(aws.StringValue(resp.AssessmentTemplateArn)) - if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { - if err := keyvaluetags.InspectorUpdateTags(conn, d.Id(), nil, v); err != nil { + if len(tags) > 0 { + if err := keyvaluetags.InspectorUpdateTags(conn, d.Id(), nil, tags); err != nil { return fmt.Errorf("error adding Inspector assessment template (%s) tags: %s", d.Id(), err) } } @@ -82,6 +87,7 @@ func resourceAwsInspectorAssessmentTemplateCreate(d *schema.ResourceData, meta i func resourceAwsInspectorAssessmentTemplateRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).inspectorconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig resp, err := conn.DescribeAssessmentTemplates(&inspector.DescribeAssessmentTemplatesInput{ @@ -115,8 +121,15 @@ func resourceAwsInspectorAssessmentTemplateRead(d *schema.ResourceData, meta int return fmt.Errorf("error listing tags for Inspector assessment template (%s): %s", arn, err) } - if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + tags = tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) } return nil @@ -125,8 +138,8 @@ func resourceAwsInspectorAssessmentTemplateRead(d *schema.ResourceData, meta int func resourceAwsInspectorAssessmentTemplateUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).inspectorconn - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.InspectorUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating Inspector assessment template (%s) tags: %s", d.Id(), err) diff --git a/aws/resource_aws_instance.go b/aws/resource_aws_instance.go index 712e905e27d8..c070abb3c110 100644 --- a/aws/resource_aws_instance.go +++ b/aws/resource_aws_instance.go @@ -498,7 +498,8 @@ func resourceAwsInstance() *schema.Resource { Computed: true, ForceNew: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "tenancy": { Type: schema.TypeString, Optional: true, @@ -558,6 +559,8 @@ func resourceAwsInstance() *schema.Resource { Set: schema.HashString, }, }, + + CustomizeDiff: SetTagsDiff, } } @@ -579,13 +582,15 @@ func throughputDiffSuppressFunc(k, old, new string, d *schema.ResourceData) bool func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) instanceOpts, err := buildAwsInstanceOpts(d, meta) if err != nil { return err } - tagSpecifications := ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), ec2.ResourceTypeInstance) + tagSpecifications := ec2TagSpecificationsFromKeyValueTags(tags, ec2.ResourceTypeInstance) tagSpecifications = append(tagSpecifications, ec2TagSpecificationsFromMap(d.Get("volume_tags").(map[string]interface{}), ec2.ResourceTypeVolume)...) // Build the creation struct @@ -746,6 +751,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig instance, err := resourceAwsInstanceFindByID(conn, d.Id()) @@ -921,8 +927,15 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { d.Set("monitoring", monitoringState == ec2.MonitoringStateEnabled || monitoringState == ec2.MonitoringStatePending) } - if err := d.Set("tags", keyvaluetags.Ec2KeyValueTags(instance.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + tags := keyvaluetags.Ec2KeyValueTags(instance.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) } if _, ok := d.GetOk("volume_tags"); ok && !blockDeviceTagsDefined(d) { @@ -1024,8 +1037,8 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - if d.HasChange("tags") && !d.IsNewResource() { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") && !d.IsNewResource() { + o, n := d.GetChange("tags_all") if err := keyvaluetags.Ec2UpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating tags: %s", err) diff --git a/aws/resource_aws_internet_gateway.go b/aws/resource_aws_internet_gateway.go index 9961677f35ab..bf66ec21d8c4 100644 --- a/aws/resource_aws_internet_gateway.go +++ b/aws/resource_aws_internet_gateway.go @@ -29,7 +29,8 @@ func resourceAwsInternetGateway() *schema.Resource { Type: schema.TypeString, Optional: true, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "owner_id": { Type: schema.TypeString, Computed: true, @@ -39,17 +40,21 @@ func resourceAwsInternetGateway() *schema.Resource { Computed: true, }, }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsInternetGatewayCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) // Create the gateway log.Printf("[DEBUG] Creating internet gateway") var err error input := &ec2.CreateInternetGatewayInput{ - TagSpecifications: ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), ec2.ResourceTypeInternetGateway), + TagSpecifications: ec2TagSpecificationsFromKeyValueTags(tags, ec2.ResourceTypeInternetGateway), } resp, err := conn.CreateInternetGateway(input) if err != nil { @@ -93,6 +98,7 @@ func resourceAwsInternetGatewayCreate(d *schema.ResourceData, meta interface{}) func resourceAwsInternetGatewayRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig igRaw, _, err := IGStateRefreshFunc(conn, d.Id())() @@ -113,8 +119,15 @@ func resourceAwsInternetGatewayRead(d *schema.ResourceData, meta interface{}) er d.Set("vpc_id", ig.Attachments[0].VpcId) } - if err := d.Set("tags", keyvaluetags.Ec2KeyValueTags(ig.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + tags := keyvaluetags.Ec2KeyValueTags(ig.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) } d.Set("owner_id", ig.OwnerId) @@ -147,8 +160,8 @@ func resourceAwsInternetGatewayUpdate(d *schema.ResourceData, meta interface{}) conn := meta.(*AWSClient).ec2conn - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.Ec2UpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating EC2 Internet Gateway (%s) tags: %s", d.Id(), err) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index 315815c0f1e9..c7142f7f532d 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -421,7 +421,8 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), "error_action": { Type: schema.TypeList, Optional: true, @@ -1075,17 +1076,21 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsIotTopicRuleCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iotconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) ruleName := d.Get("name").(string) input := &iot.CreateTopicRuleInput{ RuleName: aws.String(ruleName), - Tags: aws.String(keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().UrlEncode()), + Tags: aws.String(tags.IgnoreAws().UrlEncode()), TopicRulePayload: expandIotTopicRulePayload(d), } @@ -1102,6 +1107,7 @@ func resourceAwsIotTopicRuleCreate(d *schema.ResourceData, meta interface{}) err func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iotconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &iot.GetTopicRuleInput{ @@ -1127,8 +1133,15 @@ func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error listing tags for IoT Topic Rule (%s): %w", aws.StringValue(out.RuleArn), err) } - if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + tags = tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) } if err := d.Set("cloudwatch_alarm", flattenIotCloudWatchAlarmActions(out.Rule.Actions)); err != nil { @@ -1234,8 +1247,8 @@ func resourceAwsIotTopicRuleUpdate(d *schema.ResourceData, meta interface{}) err } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.IotUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { return fmt.Errorf("error updating tags: %s", err) From 8fee77c805e8ba92793e17267530f3539b08b19f Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 12 Apr 2021 09:41:33 -0400 Subject: [PATCH 2/4] docs/provider: Update tagging documentation (resources aws_i*) --- website/docs/r/iam_instance_profile.html.markdown | 3 ++- website/docs/r/iam_openid_connect_provider.html.markdown | 3 ++- website/docs/r/iam_policy.html.markdown | 3 ++- website/docs/r/iam_role.html.markdown | 3 ++- website/docs/r/iam_saml_provider.html.markdown | 3 ++- website/docs/r/iam_server_certificate.html.markdown | 3 ++- website/docs/r/iam_user.html.markdown | 3 ++- website/docs/r/imagebuilder_component.html.markdown | 3 ++- .../r/imagebuilder_distribution_configuration.html.markdown | 3 ++- website/docs/r/imagebuilder_image.html.markdown | 3 ++- website/docs/r/imagebuilder_image_pipeline.html.markdown | 3 ++- website/docs/r/imagebuilder_image_recipe.html.markdown | 3 ++- .../r/imagebuilder_infrastructure_configuration.html.markdown | 3 ++- website/docs/r/inspector_assessment_template.html.markdown | 3 ++- website/docs/r/instance.html.markdown | 3 ++- website/docs/r/internet_gateway.html.markdown | 4 ++-- website/docs/r/iot_topic_rule.html.markdown | 3 ++- 17 files changed, 34 insertions(+), 18 deletions(-) diff --git a/website/docs/r/iam_instance_profile.html.markdown b/website/docs/r/iam_instance_profile.html.markdown index 064d859600f0..e93760da2d84 100644 --- a/website/docs/r/iam_instance_profile.html.markdown +++ b/website/docs/r/iam_instance_profile.html.markdown @@ -48,7 +48,7 @@ The following arguments are optional: * `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`. * `path` - (Optional, default "/") Path to the instance profile. For more information about paths, see [IAM Identifiers](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) in the IAM User Guide. Can be a string of characters consisting of either a forward slash (`/`) by itself or a string that must begin and end with forward slashes. Can include any ASCII character from the ! (\u0021) through the DEL character (\u007F), including most punctuation characters, digits, and upper and lowercase letters. * `role` - (Optional) Name of the role to add to the profile. -* `tags` - (Optional) Map of resource tags for the IAM Instance Profile. +* `tags` - (Optional) Map of resource tags for the IAM Instance Profile. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference @@ -57,6 +57,7 @@ In addition to all arguments above, the following attributes are exported: * `arn` - ARN assigned by AWS to the instance profile. * `create_date` - Creation timestamp of the instance profile. * `id` - Instance profile's ID. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `unique_id` - [Unique ID][1] assigned by AWS. [1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html#GUIDs diff --git a/website/docs/r/iam_openid_connect_provider.html.markdown b/website/docs/r/iam_openid_connect_provider.html.markdown index 720dd94a7931..bd5135cf03ff 100644 --- a/website/docs/r/iam_openid_connect_provider.html.markdown +++ b/website/docs/r/iam_openid_connect_provider.html.markdown @@ -31,13 +31,14 @@ The following arguments are supported: * `url` - (Required) The URL of the identity provider. Corresponds to the _iss_ claim. * `client_id_list` - (Required) A list of client IDs (also known as audiences). When a mobile or web app registers with an OpenID Connect provider, they establish a value that identifies the application. (This is the value that's sent as the client_id parameter on OAuth requests.) * `thumbprint_list` - (Required) A list of server certificate thumbprints for the OpenID Connect (OIDC) identity provider's server certificate(s). -* `tags` - (Optional) Map of resource tags for the IAM OIDC provider. +* `tags` - (Optional) Map of resource tags for the IAM OIDC provider. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference In addition to all arguments above, the following attributes are exported: * `arn` - The ARN assigned by AWS for this provider. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/iam_policy.html.markdown b/website/docs/r/iam_policy.html.markdown index c541ed680bfb..7529fce3d282 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` - (Optional) Map of resource tags for the IAM Policy +* `tags` - (Optional) Map of resource tags for the IAM Policy. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference @@ -58,6 +58,7 @@ In addition to all arguments above, the following attributes are exported: * `path` - The path of the policy in IAM. * `policy` - The policy document. * `policy_id` - The policy's ID. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/iam_role.html.markdown b/website/docs/r/iam_role.html.markdown index 98342b3e2d44..6a6305b30443 100644 --- a/website/docs/r/iam_role.html.markdown +++ b/website/docs/r/iam_role.html.markdown @@ -190,7 +190,7 @@ The following arguments are optional: * `name_prefix` - (Optional, Forces new resource) Creates a unique friendly name beginning with the specified prefix. Conflicts with `name`. * `path` - (Optional) Path to the role. See [IAM Identifiers](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) for more information. * `permissions_boundary` - (Optional) ARN of the policy that is used to set the permissions boundary for the role. -* `tags` - Key-value mapping of tags for the IAM role +* `tags` - Key-value mapping of tags for the IAM role. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ### inline_policy @@ -207,6 +207,7 @@ In addition to all arguments above, the following attributes are exported: * `create_date` - Creation date of the IAM role. * `id` - Name of the role. * `name` - Name of the role. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `unique_id` - Stable and unique string identifying the role. ## Import diff --git a/website/docs/r/iam_saml_provider.html.markdown b/website/docs/r/iam_saml_provider.html.markdown index 568f9276ba54..74433576f842 100644 --- a/website/docs/r/iam_saml_provider.html.markdown +++ b/website/docs/r/iam_saml_provider.html.markdown @@ -25,13 +25,14 @@ The following arguments are supported: * `name` - (Required) The name of the provider to create. * `saml_metadata_document` - (Required) An XML document generated by an identity provider that supports SAML 2.0. -* `tags` - (Optional) Map of resource tags for the IAM SAML provider. +* `tags` - (Optional) Map of resource tags for the IAM SAML provider. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference In addition to all arguments above, the following attributes are exported: * `arn` - The ARN assigned by AWS for this provider. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `valid_until` - The expiration date and time for the SAML provider in RFC1123 format, e.g. `Mon, 02 Jan 2006 15:04:05 MST`. ## Import diff --git a/website/docs/r/iam_server_certificate.html.markdown b/website/docs/r/iam_server_certificate.html.markdown index 15d6d9c9474b..d7e192933211 100644 --- a/website/docs/r/iam_server_certificate.html.markdown +++ b/website/docs/r/iam_server_certificate.html.markdown @@ -107,7 +107,7 @@ The following arguments are supported: included, it defaults to a slash (/). If this certificate is for use with AWS CloudFront, the path must be in format `/cloudfront/your_path_here`. See [IAM Identifiers][1] for more details on IAM Paths. -* `tags` - (Optional) Map of resource tags for the server certificate. +* `tags` - (Optional) Map of resource tags for the server certificate. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ~> **NOTE:** AWS performs behind-the-scenes modifications to some certificate files if they do not adhere to a specific format. These modifications will result in terraform forever believing that it needs to update the resources since the local and AWS file contents will not match after theses modifications occur. In order to prevent this from happening you must ensure that all your PEM-encoded files use UNIX line-breaks and that `certificate_body` contains only one certificate. All other certificates should go in `certificate_chain`. It is common for some Certificate Authorities to issue certificate files that have DOS line-breaks and that are actually multiple certificates concatenated together in order to form a full certificate chain. @@ -119,6 +119,7 @@ In addition to all arguments above, the following attributes are exported: * `expiration` - Date and time in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8) on which the certificate is set to expire. * `id` - The unique Server Certificate name * `name` - The name of the Server Certificate +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `upload_date` - Date and time in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8) when the server certificate was uploaded. ## Import diff --git a/website/docs/r/iam_user.html.markdown b/website/docs/r/iam_user.html.markdown index dbeeb5027ed8..067d619c05fb 100644 --- a/website/docs/r/iam_user.html.markdown +++ b/website/docs/r/iam_user.html.markdown @@ -59,7 +59,7 @@ The following arguments are supported: * `force_destroy` - (Optional, default false) When destroying this user, destroy even if it has non-Terraform-managed IAM access keys, login profile or MFA devices. Without `force_destroy` a user with non-Terraform-managed access keys and login profile will fail to be destroyed. -* `tags` - Key-value map of tags for the IAM user +* `tags` - Key-value map of tags for the IAM user. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference @@ -67,6 +67,7 @@ In addition to all arguments above, the following attributes are exported: * `arn` - The ARN assigned by AWS for this user. * `name` - The user's name. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `unique_id` - The [unique ID][1] assigned by AWS. [1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html#GUIDs diff --git a/website/docs/r/imagebuilder_component.html.markdown b/website/docs/r/imagebuilder_component.html.markdown index 6d64d61074e6..e5ba940c9195 100644 --- a/website/docs/r/imagebuilder_component.html.markdown +++ b/website/docs/r/imagebuilder_component.html.markdown @@ -62,7 +62,7 @@ The following attributes are optional: * `description` - (Optional) Description of the component. * `kms_key_id` - (Optional) Amazon Resource Name (ARN) of the Key Management Service (KMS) Key used to encrypt the component. * `supported_os_versions` - (Optional) Set of Operating Systems (OS) supported by the component. -* `tags` - (Optional) Key-value map of resource tags for the component. +* `tags` - (Optional) Key-value map of resource tags for the component. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `uri` - (Optional) S3 URI with data of the component. Exactly one of `data` and `uri` can be specified. ## Attributes Reference @@ -73,6 +73,7 @@ In addition to all arguments above, the following attributes are exported: * `date_created` - Date the component was created. * `encrypted` - Encryption status of the component. * `owner` - Owner of the component. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `type` - Type of the component. ## Import diff --git a/website/docs/r/imagebuilder_distribution_configuration.html.markdown b/website/docs/r/imagebuilder_distribution_configuration.html.markdown index b9b91eb45561..e985d05af993 100644 --- a/website/docs/r/imagebuilder_distribution_configuration.html.markdown +++ b/website/docs/r/imagebuilder_distribution_configuration.html.markdown @@ -45,7 +45,7 @@ The following arguments are optional: * `description` - (Optional) Description of the distribution configuration. * `kms_key_id` - (Optional) Amazon Resource Name (ARN) of the Key Management Service (KMS) Key used to encrypt the distribution configuration. -* `tags` - (Optional) Key-value map of resource tags for the distribution configuration. +* `tags` - (Optional) Key-value map of resource tags for the distribution configuration. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ### distribution @@ -83,6 +83,7 @@ In addition to all arguments above, the following attributes are exported: * `arn` - (Required) Amazon Resource Name (ARN) of the distribution configuration. * `date_created` - Date the distribution configuration was created. * `date_updated` - Date the distribution configuration was updated. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/imagebuilder_image.html.markdown b/website/docs/r/imagebuilder_image.html.markdown index 3c3ce2f51606..f38dce3e5904 100644 --- a/website/docs/r/imagebuilder_image.html.markdown +++ b/website/docs/r/imagebuilder_image.html.markdown @@ -32,7 +32,7 @@ The following arguments are optional: * `distribution_configuration_arn` - (Optional) Amazon Resource Name (ARN) of the Image Builder Distribution Configuration. * `enhanced_image_metadata_enabled` - (Optional) Whether additional information about the image being created is collected. Defaults to `true`. * `image_tests_configuration` - (Optional) Configuration block with image tests configuration. Detailed below. -* `tags` - (Optional) Key-value map of resource tags for the Image Builder Image. +* `tags` - (Optional) Key-value map of resource tags for the Image Builder Image. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ### image_tests_configuration @@ -56,6 +56,7 @@ In addition to all arguments above, the following attributes are exported: * `image` - Identifier of the AMI. * `name` - Name of the AMI. * `region` - Region of the AMI. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `version` - Version of the image. ## Timeouts diff --git a/website/docs/r/imagebuilder_image_pipeline.html.markdown b/website/docs/r/imagebuilder_image_pipeline.html.markdown index 28f914c541aa..a68e8938a2b9 100644 --- a/website/docs/r/imagebuilder_image_pipeline.html.markdown +++ b/website/docs/r/imagebuilder_image_pipeline.html.markdown @@ -40,7 +40,7 @@ The following arguments are optional: * `image_tests_configuration` - (Optional) Configuration block with image tests configuration. Detailed below. * `schedule` - (Optional) Configuration block with schedule settings. Detailed below. * `status` - (Optional) Status of the image pipeline. Valid values are `DISABLED` and `ENABLED`. Defaults to `ENABLED`. -* `tags` - (Optional) Key-value map of resource tags for the image pipeline. +* `tags` - (Optional) Key-value map of resource tags for the image pipeline. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ### image_tests_configuration @@ -69,6 +69,7 @@ In addition to all arguments above, the following attributes are exported: * `date_next_run` - Date the image pipeline will run next. * `date_updated` - Date the image pipeline was updated. * `platform` - Platform of the image pipeline. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/imagebuilder_image_recipe.html.markdown b/website/docs/r/imagebuilder_image_recipe.html.markdown index 7a380d72f400..850d0a4f9367 100644 --- a/website/docs/r/imagebuilder_image_recipe.html.markdown +++ b/website/docs/r/imagebuilder_image_recipe.html.markdown @@ -47,7 +47,7 @@ The following attributes are optional: * `block_device_mapping` - (Optional) Configuration block(s) with block device mappings for the the image recipe. Detailed below. * `description` - (Optional) Description of the image recipe. -* `tags` - (Optional) Key-value map of resource tags for the image recipe. +* `tags` - (Optional) Key-value map of resource tags for the image recipe. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `working_directory` - (Optional) The working directory to be used during build and test workflows. ### block_device_mapping @@ -85,6 +85,7 @@ In addition to all arguments above, the following attributes are exported: * `date_created` - Date the image recipe was created. * `owner` - Owner of the image recipe. * `platform` - Platform of the image recipe. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/imagebuilder_infrastructure_configuration.html.markdown b/website/docs/r/imagebuilder_infrastructure_configuration.html.markdown index 7929936ddff1..c61a1288868b 100644 --- a/website/docs/r/imagebuilder_infrastructure_configuration.html.markdown +++ b/website/docs/r/imagebuilder_infrastructure_configuration.html.markdown @@ -54,7 +54,7 @@ The following arguments are optional: * `security_group_ids` - (Optional) Set of EC2 Security Group identifiers. * `sns_topic_arn` - (Optional) Amazon Resource Name (ARN) of SNS Topic. * `subnet_id` - (Optional) EC2 Subnet identifier. Also requires `security_group_ids` argument. -* `tags` - (Optional) Key-value map of resource tags to assign to the configuration. +* `tags` - (Optional) Key-value map of resource tags to assign to the configuration. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `terminate_instance_on_failure` - (Optional) Enable if the instance should be terminated when the pipeline fails. Defaults to `false`. ### logging @@ -81,6 +81,7 @@ In addition to all arguments above, the following attributes are exported: * `arn` - Amazon Resource Name (ARN) of the configuration. * `date_created` - Date when the configuration was created. * `date_updated` - Date when the configuration was updated. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/inspector_assessment_template.html.markdown b/website/docs/r/inspector_assessment_template.html.markdown index 84e94dc39f35..c55fb11a013c 100644 --- a/website/docs/r/inspector_assessment_template.html.markdown +++ b/website/docs/r/inspector_assessment_template.html.markdown @@ -35,13 +35,14 @@ The following arguments are supported: * `target_arn` - (Required) The assessment target ARN to attach the template to. * `duration` - (Required) The duration of the inspector run. * `rules_package_arns` - (Required) The rules to be used during the run. -* `tags` - (Optional) Key-value map of tags for the Inspector assessment template. +* `tags` - (Optional) Key-value map of tags for the Inspector assessment template. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference In addition to all arguments above, the following attributes are exported: * `arn` - The template assessment ARN. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/instance.html.markdown b/website/docs/r/instance.html.markdown index debd8e97b5cd..3af6349eb104 100644 --- a/website/docs/r/instance.html.markdown +++ b/website/docs/r/instance.html.markdown @@ -126,7 +126,7 @@ The following arguments are supported: * `source_dest_check` - (Optional) Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs. Defaults true. * `subnet_id` - (Optional) VPC Subnet ID to launch in. -* `tags` - (Optional) A map of tags to assign to the resource. Note that these tags apply to the instance and not block storage devices. +* `tags` - (Optional) A map of tags to assign to the resource. Note that these tags apply to the instance and not block storage devices. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `tenancy` - (Optional) Tenancy of the instance (if the instance is running in a VPC). An instance with a tenancy of dedicated runs on single-tenant hardware. The host tenancy is not supported for the import-instance command. * `user_data` - (Optional) User data to provide when launching the instance. Do not pass gzip-compressed data via this argument; see `user_data_base64` instead. * `user_data_base64` - (Optional) Can be used instead of `user_data` to pass base64-encoded binary data directly. Use this instead of `user_data` whenever the value is not a valid UTF-8 string. For example, gzip-encoded user data must be base64-encoded and passed via this argument to avoid corruption. @@ -238,6 +238,7 @@ In addition to all arguments above, the following attributes are exported: * `private_dns` - The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC. * `public_dns` - The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC. * `public_ip` - The public IP address assigned to the instance, if applicable. **NOTE**: If you are using an [`aws_eip`](/docs/providers/aws/r/eip.html) with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). For `ebs_block_device`, in addition to the arguments above, the following attribute is exported: diff --git a/website/docs/r/internet_gateway.html.markdown b/website/docs/r/internet_gateway.html.markdown index aa8babb9e2b4..da20433f34a4 100644 --- a/website/docs/r/internet_gateway.html.markdown +++ b/website/docs/r/internet_gateway.html.markdown @@ -27,7 +27,7 @@ resource "aws_internet_gateway" "gw" { The following arguments are supported: * `vpc_id` - (Required) The VPC ID to create in. -* `tags` - (Optional) A map of tags to assign to the resource. +* `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. -> **Note:** It's recommended to denote that the AWS Instance or Elastic IP depends on the Internet Gateway. For example: @@ -50,7 +50,7 @@ In addition to all arguments above, the following attributes are exported: * `id` - The ID of the Internet Gateway. * `arn` - The ARN of the Internet Gateway. * `owner_id` - The ID of the AWS account that owns the internet gateway. - +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index d17e2e4584ec..d87acde28ebd 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -89,7 +89,7 @@ EOF * `sql` - (Required) The SQL statement used to query the topic. For more information, see AWS IoT SQL Reference (http://docs.aws.amazon.com/iot/latest/developerguide/iot-rules.html#aws-iot-sql-reference) in the AWS IoT Developer Guide. * `sql_version` - (Required) The version of the SQL rules engine to use when evaluating the rule. * `error_action` - (Optional) Configuration block with error action to be associated with the rule. See the documentation for `cloudwatch_alarm`, `cloudwatch_metric`, `dynamodb`, `dynamodbv2`, `elasticsearch`, `firehose`, `iot_analytics`, `iot_events`, `kinesis`, `lambda`, `republish`, `s3`, `step_functions`, `sns`, `sqs` configuration blocks for further configuration details. -* `tags` - (Optional) Key-value map of resource tags +* `tags` - (Optional) Key-value map of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. The `cloudwatch_alarm` object takes the following arguments: @@ -197,6 +197,7 @@ In addition to all arguments above, the following attributes are exported: * `id` - The name of the topic rule * `arn` - The ARN of the topic rule +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import From b59f227c688159fdfbc66fbe4c2cccfcc0804542 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 19 Apr 2021 13:10:04 -0400 Subject: [PATCH 3/4] Update aws/resource_aws_iam_policy.go --- aws/resource_aws_iam_policy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index 94b96fd94dc5..a4948ba29e36 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -168,7 +168,7 @@ func resourceAwsIamPolicyRead(d *schema.ResourceData, meta interface{}) error { d.Set("path", policy.Path) d.Set("policy_id", policy.PolicyId) - tags := keyvaluetags.IamKeyValueTags(policyRes.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + tags := keyvaluetags.IamKeyValueTags(policy.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) //lintignore:AWSR002 if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { From 7dc456f1093f7a695dbbb67fa8dcfff3f9712875 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 21 Apr 2021 12:45:13 -0400 Subject: [PATCH 4/4] provider: Add missing default tag Read functionality --- aws/resource_aws_iam_instance_profile.go | 10 +++++++++- aws/resource_aws_imagebuilder_image.go | 14 +++++++++++++- aws/resource_aws_imagebuilder_image_pipeline.go | 14 +++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_iam_instance_profile.go b/aws/resource_aws_iam_instance_profile.go index 7bd62f704c5a..5e9cc0446cba 100644 --- a/aws/resource_aws_iam_instance_profile.go +++ b/aws/resource_aws_iam_instance_profile.go @@ -267,6 +267,7 @@ func resourceAwsIamInstanceProfileDelete(d *schema.ResourceData, meta interface{ } func instanceProfileReadResult(d *schema.ResourceData, result *iam.InstanceProfile, meta interface{}) error { + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig d.SetId(aws.StringValue(result.InstanceProfileName)) @@ -288,9 +289,16 @@ func instanceProfileReadResult(d *schema.ResourceData, result *iam.InstanceProfi d.Set("role", result.Roles[0].RoleName) //there will only be 1 role returned } - if err := d.Set("tags", keyvaluetags.IamKeyValueTags(result.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + tags := keyvaluetags.IamKeyValueTags(result.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) } + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + return nil } diff --git a/aws/resource_aws_imagebuilder_image.go b/aws/resource_aws_imagebuilder_image.go index 18d5a564b180..75ded50e5574 100644 --- a/aws/resource_aws_imagebuilder_image.go +++ b/aws/resource_aws_imagebuilder_image.go @@ -197,6 +197,8 @@ func resourceAwsImageBuilderImageCreate(d *schema.ResourceData, meta interface{} func resourceAwsImageBuilderImageRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &imagebuilder.GetImageInput{ ImageBuildVersionArn: aws.String(d.Id()), @@ -253,7 +255,17 @@ func resourceAwsImageBuilderImageRead(d *schema.ResourceData, meta interface{}) d.Set("output_resources", nil) } - d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(image.Tags).IgnoreAws().IgnoreConfig(meta.(*AWSClient).IgnoreTagsConfig).Map()) + tags := keyvaluetags.ImagebuilderKeyValueTags(image.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + d.Set("version", image.Version) return nil diff --git a/aws/resource_aws_imagebuilder_image_pipeline.go b/aws/resource_aws_imagebuilder_image_pipeline.go index d40369883386..d252538097f1 100644 --- a/aws/resource_aws_imagebuilder_image_pipeline.go +++ b/aws/resource_aws_imagebuilder_image_pipeline.go @@ -198,6 +198,8 @@ func resourceAwsImageBuilderImagePipelineCreate(d *schema.ResourceData, meta int func resourceAwsImageBuilderImagePipelineRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).imagebuilderconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &imagebuilder.GetImagePipelineInput{ ImagePipelineArn: aws.String(d.Id()), @@ -248,7 +250,17 @@ func resourceAwsImageBuilderImagePipelineRead(d *schema.ResourceData, meta inter } d.Set("status", imagePipeline.Status) - d.Set("tags", keyvaluetags.ImagebuilderKeyValueTags(imagePipeline.Tags).IgnoreAws().IgnoreConfig(meta.(*AWSClient).IgnoreTagsConfig).Map()) + + tags := keyvaluetags.ImagebuilderKeyValueTags(imagePipeline.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } return nil }