Terraform's aws_appautoscaling_target resource registers a scalable target with AWS Application Auto Scaling, allowing services such as ECS services, DynamoDB tables, RDS clusters, and others to be managed by scaling policies. The resource maps directly to the AWS Application Auto Scaling API RegisterScalableTarget operation and is the prerequisite for attaching aws_appautoscaling_policy resources. Understanding its argument set, provider-level default_tags interaction, and known limitations is essential for reliable infrastructure as code.
Introduction
Application Auto Scaling in AWS requires an explicit registration step before scaling policies can be attached. The Terraform resource aws_appautoscaling_target performs that registration. It is typically used together with aws_appautoscaling_policy for step scaling or target tracking. Provider configuration with default_tags is a common pattern for enforcing organizational tagging standards, but a known bug with the AWS provider causes tag application to fail on creation when the scalable target already exists.
Core Arguments and Attribute Reference
The resource provides an Application AutoScaling ScalableTarget resource. To manage policies which get attached to the target, see the aws_appautoscaling_policy resource.
The following arguments are supported:
The documented arguments are:
max_capacity- Required. The max capacity of the scalable target.min_capacity- Required. The min capacity of the scalable target.resource_id- Required. The resource type and unique identifier string for the resource associated with the scaling policy. Documentation can be found in the ResourceId parameter at: AWS Application Auto Scaling API Reference.role_arn- Optional. The ARN of the IAM role that allows Application AutoScaling to modify your scalable target on your behalf. The resource examples show it as Required in some documentation variants.scalable_dimension- Required. The scalable dimension of the scalable target. Documentation can be found in the ScalableDimension parameter at: AWS Application Auto Scaling API Reference.service_namespace- Required. The AWS service namespace of the scalable target. Documentation can be found in the ServiceNamespace parameter at: AWS Application Auto Scaling API Reference.
Attribute Reference:
arn- The ARN assigned by AWS to the scaling policy.name- The scaling policy's name.
Example usages from documentation:
hcl
resource "aws_appautoscaling_target" "dynamodb_table_read_target" {
max_capacity = 100
min_capacity = 5
resource_id = "table/${aws_dynamodb_table.example.name}"
role_arn = "${data.aws_iam_role.DynamoDBAutoscaleRole.arn}"
scalable_dimension = "dynamodb:table:ReadCapacityUnits"
service_namespace = "dynamodb"
}
hcl
resource "aws_appautoscaling_target" "dynamodb_index_read_target" {
max_capacity = 100
min_capacity = 5
resource_id = "table/${aws_dynamodb_table.example.name}/index/${var.index_name}"
role_arn = "${data.aws_iam_role.DynamoDBAutoscaleRole.arn}"
scalable_dimension = "dynamodb:index:ReadCapacityUnits"
service_namespace = "dynamodb"
}
hcl
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}"
role_arn = "${var.ecs_iam_role}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
}
hcl
resource "aws_appautoscaling_target" "replicas" {
service_namespace = "rds"
scalable_dimension = "rds:cluster:ReadReplicaCount"
resource_id = "cluster:${aws_rds_cluster.example.id}"
min_capacity = 1
max_capacity = 15
}
Documentation variants note defaults:
scalable_dimensiondefaults toecs:service:DesiredCountsince that is the only allowed value.service_namespacedefaults toecs, because that is currently the only supported option.max_capacityis Required.min_capacityis Required.role_arnis Required in some documentation variants.
Provider Default Tags Interaction
A common Terraform configuration uses provider-level default_tags:
hcl
provider "aws" {
region = var.aws_region
default_tags {
tags = {
application = var.project
stage = var.env
squad = var.squad
terraform = "true"
repository = var.repository_name
}
}
}
With this configuration, Terraform is expected to create resources and manage tags automatically by seeing the default_tags configuration on the provider. The aws_appautoscaling_target resource is declared as:
hcl
resource "aws_appautoscaling_target" "service_scaling" {
min_capacity = var.min_container_count
max_capacity = var.max_container_count
resource_id = "service/${aws_ecs_cluster.ecs_cluster.name}/${aws_ecs_service.ecs_service.name}"
role_arn = aws_iam_role.autoscaling_role.arn
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
depends_on = [aws_ecs_service.ecs_service, aws_iam_role.autoscaling_role]
}
The scaling policy is then attached:
hcl
resource "aws_appautoscaling_policy" "service_scale_out" {
name = "${var.project}-${var.env}-scale-out-policy"
policy_type = "StepScaling"
resource_id = aws_appautoscaling_target.service_scaling.resource_id
scalable_dimension = aws_appautoscaling_target.service_scaling.scalable_dimension
service_namespace = aws_appautoscaling_target.service_scaling.service_namespace
step_scaling_policy_configuration {
adjustment_type = "ChangeInCapacity"
cooldown = 60
metric_aggregation_type = "Average"
step_adjustment {
scaling_adjustment = 1
metric_interval_lower_bound = 0
}
}
depends_on = [aws_appautoscaling_target.service_scaling]
}
Known Bug: ValidationException on Tagging Existing Targets
A bug is documented for Terraform Core Version v1.4.6 with AWS Provider Version v4.67.0. Affected Resource is aws_appautoscaling_target.
Expected Behavior:
Terraform should create these resources and manage the tags automatically by seeing the default_tags configuration on the provider.
Actual Behavior:
When creating the these resources for the first time, the error occurs:
aws_appautoscaling_target.service_scaling: Creating...
╷
│ Error: creating Application AutoScaling Target (service/content-available-service-nonprod-ecs-cluster/content-available-service-nonprod-ecs-service): ValidationException: The scalable target that you tried to tag already exists
│
│ To update tags on an existing scalable target, use the TagResource API.
│
│ with aws_appautoscaling_target.service_scaling,
│ on autoscaling.tf line 1, in resource "aws_appautoscaling_target" "service_scaling":
│ 1: resource "aws_appautoscaling_target" "service_scaling" {
│
╵
The error message states: The scalable target that you tried to tag already exists. To update tags on an existing scalable target, use the TagResource API.
This indicates the provider attempts to create the scalable target with tags in a single call, but AWS returns a validation exception when the target already exists or when tags are applied during creation. The issue is reproducible with terraform apply.
The bug report confirms the user would like a fix implemented.
CloudFormation Equivalent
AWS CloudFormation provides AWS::ApplicationAutoScaling::ScalableTarget as the declarative equivalent.
The resource specifies a resource that Application Auto Scaling can scale, such as an AWS::DynamoDB::Table or AWS::ECS::Service resource.
Note: If the resource that you want Application Auto Scaling to scale is not yet created in your account, add a dependency on the resource when registering it as a scalable target using the DependsOn attribute.
Syntax:
JSON
json
{ "Type" : "AWS::ApplicationAutoScaling::ScalableTarget", "Properties" : { "MaxCapacity" : Integer , "MinCapacity" : Integer , "ResourceId" : String , "RoleARN" : String , "ScalableDimension" : String , "ScheduledActions" : [ ScheduledAction, ... ] , "ServiceNamespace" : String , "SuspendedState" : SuspendedState } }
YAML
yaml
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: Integer
MinCapacity: Integer
ResourceId: String
RoleARN: String
ScalableDimension: String
ScheduledActions:
- ScheduledAction
ServiceNamespace: String
SuspendedState: SuspendedState
Properties:
MaxCapacity- The maximum value that you plan to scale out toMinCapacity- The minimum value that you plan to scale in to- Additional properties include
ResourceId,RoleARN,ScalableDimension,ServiceNamespace,ScheduledActions, andSuspendedState.
Specification Comparison
| Terraform Argument | CloudFormation Property | Required | Description |
|---|---|---|---|
| max_capacity | MaxCapacity | Yes | The max capacity of the scalable target |
| min_capacity | MinCapacity | Yes | The min capacity of the scalable target |
| resource_id | ResourceId | Yes | The resource type and unique identifier string |
| role_arn | RoleARN | Optional / Required | The ARN of the IAM role for Auto Scaling |
| scalable_dimension | ScalableDimension | Yes | The scalable dimension of the target |
| service_namespace | ServiceNamespace | Yes | The AWS service namespace of the target |
Operational Considerations
- The resource_id format is service specific. For ECS it is
service/<cluster-name>/<service-name>. For DynamoDB table read capacity it istable/<table-name>. scalable_dimensionvalues are constrained per service namespace. For ECS the only allowed value isecs:service:DesiredCount.service_namespacecurrently defaults toecsin some documentation variants, because that is currently the only supported option.depends_onis often used to ensure the underlying ECS service, IAM role, or database resource exists before registration.- Tag management via provider
default_tagsdoes not currently work reliably foraws_appautoscaling_targetdue to the ValidationException bug. Workarounds involve removing default_tags for this resource or managing tags via separateaws_appautoscalingtag resources after creation.
Conclusion
The aws_appautoscaling_target resource is central to enabling Application Auto Scaling in Terraform for ECS, DynamoDB, RDS, and other supported services. Its argument set is minimal but strict: min_capacity, max_capacity, resource_id, role_arn, scalable_dimension, and service_namespace. The resource maps directly to AWS::ApplicationAutoScaling::ScalableTarget in CloudFormation.
The critical operational issue remains the provider-level default_tags interaction. With Terraform Core v1.4.6 and AWS Provider v4.67.0, creating an aws_appautoscaling_target with default tags results in ValidationException: The scalable target that you tried to tag already exists. The error instructs users to update tags via the TagResource API, which the provider does not correctly handle during initial creation. This prevents automatic tag inheritance and forces manual tagging workarounds.
Until the provider bug is fixed, teams should avoid relying on default_tags for auto scaling targets, explicitly manage tags after resource creation, or pin provider versions and monitor the upstream issue. The resource remains functionally correct for capacity registration and policy attachment, but tagging behavior makes it unsafe in environments enforcing mandatory tagging through provider defaults.