Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/aws_appautoscaling_target: Skip ListTags/UpdateTags for existing resources with no assigned ARN #31214

Merged
merged 7 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changelog/31214.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:bug
resource/aws_appautoscaling_target: Fix `InvalidParameter: 1 validation error(s) found.
minimum field size of 1, ListTagsForResourceInput.ResourceARN.` introduced in [v4.66.0](https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#4660-may--4-2023)
```
96 changes: 52 additions & 44 deletions internal/provider/fwprovider/intercept.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,28 +382,32 @@ func (r tagsInterceptor) read(ctx context.Context, request resource.ReadRequest,
return ctx, diags
}

// If the service package has a generic resource list tags methods, call it.
var err error

if v, ok := sp.(interface {
ListTags(context.Context, any, string) error
}); ok {
err = v.ListTags(ctx, meta, identifier) // Sets tags in Context
} else if v, ok := sp.(interface {
ListTags(context.Context, any, string, string) error
}); ok && r.tags.ResourceType != "" {
err = v.ListTags(ctx, meta, identifier, r.tags.ResourceType) // Sets tags in Context
}

// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.Partition, err) {
return ctx, diags
}

if err != nil {
diags.AddError(fmt.Sprintf("listing tags for %s %s (%s)", serviceName, resourceName, identifier), err.Error())

return ctx, diags
// Some old resources may not have the required attribute set after Read:
// https://github.com/hashicorp/terraform-provider-aws/issues/31180
if identifier != "" {
// If the service package has a generic resource list tags methods, call it.
var err error

if v, ok := sp.(interface {
ListTags(context.Context, any, string) error
}); ok {
err = v.ListTags(ctx, meta, identifier) // Sets tags in Context
} else if v, ok := sp.(interface {
ListTags(context.Context, any, string, string) error
}); ok && r.tags.ResourceType != "" {
err = v.ListTags(ctx, meta, identifier, r.tags.ResourceType) // Sets tags in Context
}

// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.Partition, err) {
return ctx, diags
}

if err != nil {
diags.AddError(fmt.Sprintf("listing tags for %s %s (%s)", serviceName, resourceName, identifier), err.Error())

return ctx, diags
}
}
}
}
Expand Down Expand Up @@ -505,28 +509,32 @@ func (r tagsInterceptor) update(ctx context.Context, request resource.UpdateRequ
return ctx, diags
}

// If the service package has a generic resource update tags methods, call it.
var err error

if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, any, any) error
}); ok {
err = v.UpdateTags(ctx, meta, identifier, oldTagsAll, newTagsAll)
} else if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, string, any, any) error
}); ok && r.tags.ResourceType != "" {
err = v.UpdateTags(ctx, meta, identifier, r.tags.ResourceType, oldTagsAll, newTagsAll)
}

// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.Partition, err) {
return ctx, diags
}

if err != nil {
diags.AddError(fmt.Sprintf("updating tags for %s %s (%s)", serviceName, resourceName, identifier), err.Error())

return ctx, diags
// Some old resources may not have the required attribute set after Read:
// https://github.com/hashicorp/terraform-provider-aws/issues/31180
if identifier != "" {
// If the service package has a generic resource update tags methods, call it.
var err error

if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, any, any) error
}); ok {
err = v.UpdateTags(ctx, meta, identifier, oldTagsAll, newTagsAll)
} else if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, string, any, any) error
}); ok && r.tags.ResourceType != "" {
err = v.UpdateTags(ctx, meta, identifier, r.tags.ResourceType, oldTagsAll, newTagsAll)
}

// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.Partition, err) {
return ctx, diags
}

if err != nil {
diags.AddError(fmt.Sprintf("updating tags for %s %s (%s)", serviceName, resourceName, identifier), err.Error())

return ctx, diags
}
}
}
// TODO If the only change was to tags it would be nice to not call the resource's U handler.
Expand Down
95 changes: 52 additions & 43 deletions internal/provider/intercept.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,28 +235,33 @@ func (r tagsInterceptor) run(ctx context.Context, d *schema.ResourceData, meta a
} else {
identifier = d.Get(identifierAttribute).(string)
}
o, n := d.GetChange(names.AttrTagsAll)

// If the service package has a generic resource update tags methods, call it.
var err error

if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, any, any) error
}); ok {
err = v.UpdateTags(ctx, meta, identifier, o, n)
} else if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, string, any, any) error
}); ok && r.tags.ResourceType != "" {
err = v.UpdateTags(ctx, meta, identifier, r.tags.ResourceType, o, n)
}

// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) {
return ctx, diags
}
// Some old resources may not have the required attribute set after Read:
// https://github.com/hashicorp/terraform-provider-aws/issues/31180
if identifier != "" {
o, n := d.GetChange(names.AttrTagsAll)

// If the service package has a generic resource update tags methods, call it.
var err error

if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, any, any) error
}); ok {
err = v.UpdateTags(ctx, meta, identifier, o, n)
} else if v, ok := sp.(interface {
UpdateTags(context.Context, any, string, string, any, any) error
}); ok && r.tags.ResourceType != "" {
err = v.UpdateTags(ctx, meta, identifier, r.tags.ResourceType, o, n)
}

if err != nil {
return ctx, sdkdiag.AppendErrorf(diags, "updating tags for %s %s (%s): %s", serviceName, resourceName, identifier, err)
// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) {
return ctx, diags
}

if err != nil {
return ctx, sdkdiag.AppendErrorf(diags, "updating tags for %s %s (%s): %s", serviceName, resourceName, identifier, err)
}
}
}
// TODO If the only change was to tags it would be nice to not call the resource's U handler.
Expand Down Expand Up @@ -284,33 +289,37 @@ func (r tagsInterceptor) run(ctx context.Context, d *schema.ResourceData, meta a
identifier = d.Get(identifierAttribute).(string)
}

// If the service package has a generic resource list tags methods, call it.
var err error

if v, ok := sp.(interface {
ListTags(context.Context, any, string) error
}); ok {
err = v.ListTags(ctx, meta, identifier) // Sets tags in Context
} else if v, ok := sp.(interface {
ListTags(context.Context, any, string, string) error
}); ok && r.tags.ResourceType != "" {
err = v.ListTags(ctx, meta, identifier, r.tags.ResourceType) // Sets tags in Context
}
// Some old resources may not have the required attribute set after Read:
// https://github.com/hashicorp/terraform-provider-aws/issues/31180
if identifier != "" {
// If the service package has a generic resource list tags methods, call it.
var err error

if v, ok := sp.(interface {
ListTags(context.Context, any, string) error
}); ok {
err = v.ListTags(ctx, meta, identifier) // Sets tags in Context
} else if v, ok := sp.(interface {
ListTags(context.Context, any, string, string) error
}); ok && r.tags.ResourceType != "" {
err = v.ListTags(ctx, meta, identifier, r.tags.ResourceType) // Sets tags in Context
}

// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) {
return ctx, diags
}
// ISO partitions may not support tagging, giving error.
if errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) {
return ctx, diags
}

if inContext.ServicePackageName == names.DynamoDB && err != nil {
// When a DynamoDB Table is `ARCHIVED`, ListTags returns `ResourceNotFoundException`.
if tfresource.NotFound(err) || tfawserr.ErrMessageContains(err, "UnknownOperationException", "Tagging is not currently supported in DynamoDB Local.") {
err = nil
if inContext.ServicePackageName == names.DynamoDB && err != nil {
// When a DynamoDB Table is `ARCHIVED`, ListTags returns `ResourceNotFoundException`.
if tfresource.NotFound(err) || tfawserr.ErrMessageContains(err, "UnknownOperationException", "Tagging is not currently supported in DynamoDB Local.") {
err = nil
}
}
}

if err != nil {
return ctx, sdkdiag.AppendErrorf(diags, "listing tags for %s %s (%s): %s", serviceName, resourceName, identifier, err)
if err != nil {
return ctx, sdkdiag.AppendErrorf(diags, "listing tags for %s %s (%s): %s", serviceName, resourceName, identifier, err)
}
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions website/docs/r/appautoscaling_target.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ description: |-

Provides an Application AutoScaling ScalableTarget resource. To manage policies which get attached to the target, see the [`aws_appautoscaling_policy` resource](/docs/providers/aws/r/appautoscaling_policy.html).

~> **NOTE:** Scalable targets created before 2023-03-20 may not have an assigned `arn`. These resource cannot use `tags` or participate in `default_tags`. To prevent `terraform plan` showing differences that can never be reconciled, use the [`lifecycle.ignore_changes`](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes) meta-argument. See the example below.

~> **NOTE:** The [Application Auto Scaling service automatically attempts to manage IAM Service-Linked Roles](https://docs.aws.amazon.com/autoscaling/application/userguide/security_iam_service-with-iam.html#security_iam_service-with-iam-roles) when registering certain service namespaces for the first time. To manually manage this role, see the [`aws_iam_service_linked_role` resource](/docs/providers/aws/r/iam_service_linked_role.html).

## Example Usage
Expand Down Expand Up @@ -62,6 +64,24 @@ resource "aws_appautoscaling_target" "replicas" {
}
```

### Suppressing `tags_all` Differences For Older Resources

```terraform
resource "aws_appautoscaling_target" "ecs_target" {
max_capacity = 4
min_capacity = 1
resource_id = "service/${aws_ecs_cluster.example.name}/${aws_ecs_service.example.name}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"

lifecycle {
ignore_changes = [
tags_all,
]
}
}
```

## Argument Reference

The following arguments are supported:
Expand Down