Skip to content

Commit

Permalink
Merge pull request #23283 from hashicorp/b-iso-tagging-iam-profile
Browse files Browse the repository at this point in the history
iam: Improve ISO tag handling
  • Loading branch information
YakDriver authored Feb 18, 2022
2 parents d4b6c38 + 7b1c89a commit b669c0d
Show file tree
Hide file tree
Showing 21 changed files with 372 additions and 149 deletions.
27 changes: 27 additions & 0 deletions .changelog/23283.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
```release-note:bug
resource/aws_iam_instance_profile: Improve tag handling in ISO regions
```

```release-note:bug
resource/aws_iam_openid_connect_provider: Improve tag handling in ISO regions
```

```release-note:bug
resource/aws_iam_policy: Improve tag handling in ISO regions
```

```release-note:bug
resource/aws_iam_saml_provider: Improve tag handling in ISO regions
```

```release-note:bug
resource/aws_iam_server_certificate: Improve tag handling in ISO regions
```

```release-note:bug
resource/aws_iam_service_linked_role: Improve tag handling in ISO regions
```

```release-note:bug
resource/aws_iam_virtual_mfa_device: Improve tag handling in ISO regions
```
4 changes: 2 additions & 2 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,7 @@ func Provider() *schema.Provider {
"aws_iam_role": iam.ResourceRole(),
"aws_iam_role_policy": iam.ResourceRolePolicy(),
"aws_iam_role_policy_attachment": iam.ResourceRolePolicyAttachment(),
"aws_iam_saml_provider": iam.ResourceSamlProvider(),
"aws_iam_saml_provider": iam.ResourceSAMLProvider(),
"aws_iam_server_certificate": iam.ResourceServerCertificate(),
"aws_iam_service_linked_role": iam.ResourceServiceLinkedRole(),
"aws_iam_service_specific_credential": iam.ResourceServiceSpecificCredential(),
Expand All @@ -1439,7 +1439,7 @@ func Provider() *schema.Provider {
"aws_iam_user_policy": iam.ResourceUserPolicy(),
"aws_iam_user_policy_attachment": iam.ResourceUserPolicyAttachment(),
"aws_iam_user_ssh_key": iam.ResourceUserSSHKey(),
"aws_iam_virtual_mfa_device": iam.ResourceVirtualMfaDevice(),
"aws_iam_virtual_mfa_device": iam.ResourceVirtualMFADevice(),

"aws_imagebuilder_component": imagebuilder.ResourceComponent(),
"aws_imagebuilder_container_recipe": imagebuilder.ResourceContainerRecipe(),
Expand Down
2 changes: 1 addition & 1 deletion internal/service/iam/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func FindRoleByName(conn *iam.IAM, name string) (*iam.Role, error) {
return output.Role, nil
}

func FindVirtualMfaDevice(conn *iam.IAM, serialNum string) (*iam.VirtualMFADevice, error) {
func FindVirtualMFADevice(conn *iam.IAM, serialNum string) (*iam.VirtualMFADevice, error) {
input := &iam.ListVirtualMFADevicesInput{}

output, err := conn.ListVirtualMFADevices(input)
Expand Down
44 changes: 40 additions & 4 deletions internal/service/iam/instance_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,27 @@ func resourceInstanceProfileCreate(d *schema.ResourceData, meta interface{}) err
request := &iam.CreateInstanceProfileInput{
InstanceProfileName: aws.String(name),
Path: aws.String(d.Get("path").(string)),
Tags: Tags(tags.IgnoreAWS()),
}

if len(tags) > 0 {
request.Tags = Tags(tags.IgnoreAWS())
}

var err error
response, err := conn.CreateInstanceProfile(request)

// Some partitions (i.e., ISO) may not support tag-on-create
if request.Tags != nil && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed creating IAM Instance Profile (%s) with tags: %s. Trying create without tags.", name, err)
request.Tags = nil

response, err = conn.CreateInstanceProfile(request)
}

if err == nil {
err = instanceProfileReadResult(d, response.InstanceProfile, meta)
err = instanceProfileReadResult(d, response.InstanceProfile, meta) // sets id
}

if err != nil {
return fmt.Errorf("creating IAM instance profile %s: %w", name, err)
}
Expand All @@ -117,6 +130,21 @@ func resourceInstanceProfileCreate(d *schema.ResourceData, meta interface{}) err
return fmt.Errorf("timed out while waiting for instance profile %s: %w", name, err)
}

// Some partitions (i.e., ISO) may not support tag-on-create, attempt tag after create
if request.Tags == nil && len(tags) > 0 {
err := instanceProfileUpdateTags(conn, d.Id(), nil, tags)

// If default tags only, log and continue. Otherwise, error.
if v, ok := d.GetOk("tags"); (!ok || len(v.(map[string]interface{})) == 0) && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed adding tags after create for IAM Instance Profile (%s): %s", d.Id(), err)
return resourceInstanceProfileUpdate(d, meta)
}

if err != nil {
return fmt.Errorf("failed adding tags after create for IAM Instance Profile (%s): %w", d.Id(), err)
}
}

return resourceInstanceProfileUpdate(d, meta)
}

Expand Down Expand Up @@ -197,8 +225,16 @@ func resourceInstanceProfileUpdate(d *schema.ResourceData, meta interface{}) err
if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := instanceProfileUpdateTags(conn, d.Id(), o, n); err != nil {
return fmt.Errorf("error updating tags for IAM Instance Profile (%s): %w", d.Id(), err)
err := instanceProfileUpdateTags(conn, d.Id(), o, n)

// Some partitions (i.e., ISO) may not support tagging, giving error
if verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed updating tags for IAM Instance Profile (%s): %s", d.Id(), err)
return nil
}

if err != nil {
return fmt.Errorf("failed updating tags for IAM Instance Profile (%s): %w", d.Id(), err)
}
}

Expand Down
41 changes: 38 additions & 3 deletions internal/service/iam/openid_connect_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,43 @@ func resourceOpenIDConnectProviderCreate(d *schema.ResourceData, meta interface{
Url: aws.String(d.Get("url").(string)),
ClientIDList: flex.ExpandStringList(d.Get("client_id_list").([]interface{})),
ThumbprintList: flex.ExpandStringList(d.Get("thumbprint_list").([]interface{})),
Tags: Tags(tags.IgnoreAWS()),
}

if len(tags) > 0 {
input.Tags = Tags(tags.IgnoreAWS())
}

out, err := conn.CreateOpenIDConnectProvider(input)

// Some partitions (i.e., ISO) may not support tag-on-create
if input.Tags != nil && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed creating IAM OIDC Provider with tags: %s. Trying create without tags.", err)
input.Tags = nil

out, err = conn.CreateOpenIDConnectProvider(input)
}

if err != nil {
return fmt.Errorf("error creating IAM OIDC Provider: %w", err)
}

d.SetId(aws.StringValue(out.OpenIDConnectProviderArn))

// Some partitions (i.e., ISO) may not support tag-on-create, attempt tag after create
if input.Tags == nil && len(tags) > 0 {
err := openIDConnectProviderUpdateTags(conn, d.Id(), nil, tags)

// If default tags only, log and continue. Otherwise, error.
if v, ok := d.GetOk("tags"); (!ok || len(v.(map[string]interface{})) == 0) && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed adding tags after create for IAM OIDC Provider (%s): %s", d.Id(), err)
return resourceOpenIDConnectProviderRead(d, meta)
}

if err != nil {
return fmt.Errorf("failed adding tags after create for IAM OIDC Provider (%s): %w", d.Id(), err)
}
}

return resourceOpenIDConnectProviderRead(d, meta)
}

Expand Down Expand Up @@ -139,8 +166,16 @@ func resourceOpenIDConnectProviderUpdate(d *schema.ResourceData, meta interface{
if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := openIDConnectProviderUpdateTags(conn, d.Id(), o, n); err != nil {
return fmt.Errorf("error updating tags for IAM OIDC Provider (%s): %w", d.Id(), err)
err := openIDConnectProviderUpdateTags(conn, d.Id(), o, n)

// Some partitions (i.e., ISO) may not support tagging, giving error
if verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed updating tags for IAM OIDC Provider (%s): %s", d.Id(), err)
return resourceOpenIDConnectProviderRead(d, meta)
}

if err != nil {
return fmt.Errorf("failed updating tags for IAM OIDC Provider (%s): %w", d.Id(), err)
}
}

Expand Down
6 changes: 3 additions & 3 deletions internal/service/iam/openid_connect_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
tfiam "github.com/hashicorp/terraform-provider-aws/internal/service/iam"
)

func TestAccIAMOpenidConnectProvider_basic(t *testing.T) {
func TestAccIAMOpenIDConnectProvider_basic(t *testing.T) {
rString := sdkacctest.RandString(5)
url := "accounts.testle.com/" + rString
resourceName := "aws_iam_openid_connect_provider.test"
Expand Down Expand Up @@ -62,7 +62,7 @@ func TestAccIAMOpenidConnectProvider_basic(t *testing.T) {
})
}

func TestAccIAMOpenidConnectProvider_tags(t *testing.T) {
func TestAccIAMOpenIDConnectProvider_tags(t *testing.T) {
rString := sdkacctest.RandString(5)
resourceName := "aws_iam_openid_connect_provider.test"

Expand Down Expand Up @@ -107,7 +107,7 @@ func TestAccIAMOpenidConnectProvider_tags(t *testing.T) {
})
}

func TestAccIAMOpenidConnectProvider_disappears(t *testing.T) {
func TestAccIAMOpenIDConnectProvider_disappears(t *testing.T) {
rString := sdkacctest.RandString(5)
resourceName := "aws_iam_openid_connect_provider.test"

Expand Down
43 changes: 39 additions & 4 deletions internal/service/iam/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,43 @@ func resourcePolicyCreate(d *schema.ResourceData, meta interface{}) error {
Path: aws.String(d.Get("path").(string)),
PolicyDocument: aws.String(policy),
PolicyName: aws.String(name),
Tags: Tags(tags.IgnoreAWS()),
}

if len(tags) > 0 {
request.Tags = Tags(tags.IgnoreAWS())
}

response, err := conn.CreatePolicy(request)

// Some partitions (i.e., ISO) may not support tag-on-create
if request.Tags != nil && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed creating IAM Policy (%s) with tags: %s. Trying create without tags.", name, err)
request.Tags = nil

response, err = conn.CreatePolicy(request)
}

if err != nil {
return fmt.Errorf("error creating IAM policy %s: %w", name, err)
return fmt.Errorf("error creating IAM Policy %s: %w", name, err)
}

d.SetId(aws.StringValue(response.Policy.Arn))

// Some partitions (i.e., ISO) may not support tag-on-create, attempt tag after create
if request.Tags == nil && len(tags) > 0 {
err := policyUpdateTags(conn, d.Id(), nil, tags)

// If default tags only, log and continue. Otherwise, error.
if v, ok := d.GetOk("tags"); (!ok || len(v.(map[string]interface{})) == 0) && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed adding tags after create for IAM Policy (%s): %s", d.Id(), err)
return resourcePolicyRead(d, meta)
}

if err != nil {
return fmt.Errorf("failed adding tags after create for IAM Policy (%s): %w", d.Id(), err)
}
}

return resourcePolicyRead(d, meta)
}

Expand Down Expand Up @@ -277,8 +304,16 @@ func resourcePolicyUpdate(d *schema.ResourceData, meta interface{}) error {
if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := policyUpdateTags(conn, d.Id(), o, n); err != nil {
return fmt.Errorf("error updating tags for IAM Policy (%s): %w", d.Id(), err)
err := policyUpdateTags(conn, d.Id(), o, n)

// Some partitions (i.e., ISO) may not support tagging, giving error
if verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed updating tags for IAM Policy (%s): %s", d.Id(), err)
return resourcePolicyRead(d, meta)
}

if err != nil {
return fmt.Errorf("failed updating tags for IAM Policy (%s): %w", d.Id(), err)
}
}

Expand Down
6 changes: 0 additions & 6 deletions internal/service/iam/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,6 @@ func resourceRoleRead(d *schema.ResourceData, meta interface{}) error {

tags := KeyValueTags(role.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

// Some partitions (i.e., ISO) may not support tagging, giving error
if meta.(*conns.AWSClient).Partition != endpoints.AwsPartitionID && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] failed listing tags for IAM Role (%s): %s", d.Id(), err)
return nil
}

//lintignore:AWSR002
if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %w", err)
Expand Down
9 changes: 0 additions & 9 deletions internal/service/iam/role_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@ package iam

import (
"fmt"
"log"
"net/url"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

func DataSourceRole() *schema.Resource {
Expand Down Expand Up @@ -100,12 +97,6 @@ func dataSourceRoleRead(d *schema.ResourceData, meta interface{}) error {

tags := KeyValueTags(output.Role.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

// Some partitions (i.e., ISO) may not support tagging, giving error
if meta.(*conns.AWSClient).Partition != endpoints.AwsPartitionID && verify.CheckISOErrorTagsUnsupported(err) {
log.Printf("[WARN] Unable to list tags for IAM Role %s: %s", d.Id(), err)
return nil
}

//lintignore:AWSR002
if err := d.Set("tags", tags.Map()); err != nil {
return fmt.Errorf("error setting tags: %w", err)
Expand Down
Loading

0 comments on commit b669c0d

Please sign in to comment.