Terraform aws_appautoscaling_policy Complete Reference for Application Auto Scaling

Application Auto Scaling in AWS provides a unified way to scale resources across services such as ECS, SageMaker, DynamoDB, and Aurora. Terraform exposes this capability through the aws_appautoscaling_policy resource, which maps directly to the AWS Application Auto Scaling ScalingPolicy construct. Understanding both the CloudFormation definition and the Terraform implementation is essential to build reliable, drift-resistant scaling configurations.

CloudFormation ScalingPolicy Foundation

The CloudFormation resource AWS::ApplicationAutoScaling::ScalingPolicy defines a scaling policy that Application Auto Scaling uses to adjust the capacity of a scalable target. The resource supports multiple policy types and is the canonical model that Terraform implements.

The syntax declaration for CloudFormation is:

Type: AWS::ApplicationAutoScaling::ScalingPolicy Properties: PolicyName: String PolicyType: String PredictiveScalingPolicyConfiguration: PredictiveScalingPolicyConfiguration ResourceId: String ScalableDimension: String ScalingTargetId: String ServiceNamespace: String StepScalingPolicyConfiguration: StepScalingPolicyConfiguration TargetTrackingScalingPolicyConfiguration: TargetTrackingScalingPolicyConfiguration

Key properties from the reference include:

  • PolicyName
    The name of the scaling policy. Updates to the name of a target tracking scaling policy are not supported, unless you also update the metric used for scaling
  • PolicyType
  • PredictiveScalingPolicyConfiguration
  • ResourceId
  • ScalableDimension
  • ScalingTargetId
  • ServiceNamespace
  • StepScalingPolicyConfiguration
  • TargetTrackingScalingPolicyConfiguration

This property set forms the basis for both Step Scaling and Target Tracking Scaling in Terraform.

Terraform Resource Model and Arguments

The Terraform provider resource aws_appautoscaling_policy provides an Application Auto Scaling Policy resource.

Example usage from the provider documentation:

resource "aws_appautoscaling_policy" "down" { name = "scale-down" service_namespace = "ecs" resource_id = "service/ecsclustername/servicename" scalable_dimension = "ecs:service:DesiredCount" adjustment_type = "ChangeInCapacity" cooldown = 60 metric_aggregation_type = "Maximum" step_adjustment { metric_interval_lower_bound = 0 scaling_adjustment = -1 } depends_on = ["aws_appautoscaling_target.target"] }

Argument reference:

  • name
    Required. The name of the policy.
  • policy_type
    Optional. Defaults to “StepScaling” because it is the only option available.
  • resource_id
    Required. The Resource ID on which you want the Application Auto Scaling policy to apply to. For Amazon ECS services, this value is the resource type, followed by the cluster name and service name, such as service/default/sample-webapp
  • scalable_dimension
    Optional. The scalable dimension of the scalable target that this scaling policy applies to. The scalable dimension contains the service names-pace, resource type, and scaling property, such as ecs:service:DesiredCount for the desired task count of an Amazon ECS service. Defaults to ecs:service:DesiredCount since that is the only allowed value.
  • service_namespace
    Optional. The AWS service namespace of the scalable target

The resource requires a preceding aws_appautoscaling_target to register the scalable resource before attaching policy logic.

Target Tracking Scaling Configuration

Target tracking is the best default for most workloads. Set a CPU or request count target and let AWS handle the math.

In Terraform the configuration is expressed with target_tracking_scaling_policy_configuration. A SageMaker example shows the need for customized metrics and dimensions:

resource "aws_appautoscaling_policy" "sagemaker_policy" { name = "somepolicy" policy_type = "TargetTrackingScaling" resource_id = aws_appautoscaling_target.sagemaker_target.resource_id scalable_dimension = aws_appautoscaling_target.sagemaker_target.scalable_dimension service_namespace = aws_appautoscaling_target.sagemaker_target.service_namespace target_tracking_scaling_policy_configuration { customized_metric_specification{ metric_name = "ApproximateBacklogSizePerInstance" namespace = "AWS/SageMaker" Dimensions = ....????? statistic = "Average" } target_value = 3 scale_in_cooldown =300 scale_out_cooldown = 600 } }

The Dimensions refer to the CloudWatch dimensions of metric ApproximateBacklogSizePerInstance. For SageMaker variant metrics the dimension is EndpointName with the value set to the endpoint name.

The target definition for that example is:

resource "aws_appautoscaling_target" "sagemaker_target" { max_capacity = 3 min_capacity = 1 resource_id = "myendpoint" scalable_dimension = "sagemaker:variant:DesiredInstanceCount" service_namespace = "sagemaker" }

Target tracking configuration properties include TargetValue, CustomizedMetricSpecification with MetricName, Namespace, Dimensions, Statistic, and cooldown settings for scale in and scale out.

Step Scaling Configuration

It is useful when you need non-linear scaling behavior. Step scaling allows different adjustments based on metric intervals.

A scale out example:

resource "aws_appautoscaling_policy" "scale_out" { name = "myapp-scale-out" policy_type = "StepScaling" resource_id = aws_appautoscaling_target.ecs.resource_id scalable_dimension = aws_appautoscaling_target.ecs.scalable_dimension service_namespace = aws_appautoscaling_target.ecs.service_namespace step_scaling_policy_configuration { adjustment_type = "ChangeInCapacity" cooldown = 60 metric_aggregation_type = "Average" step_adjustment { metric_interval_lower_bound = 0 metric_interval_upper_bound = 15 scaling_adjustment = 2 } step_adjustment { metric_interval_lower_bound = 15 metric_interval_upper_bound = 25 scaling_adjustment = 4 } step_adjustment { metric_interval_lower_bound = 25 scaling_adjustment = 6 } } }

A scale in counterpart uses a longer cooldown to prevent premature reductions:

resource "aws_appautoscaling_policy" "scale_in" { name = "myapp-scale-in" policy_type = "StepScaling" resource_id = aws_appautoscaling_target.ecs.resource_id scalable_dimension = aws_appautoscaling_target.ecs.scalable_dimension service_namespace = aws_appautoscaling_target.ecs.service_namespace step_scaling_policy_configuration { adjustment_type = "ChangeInCapacity" cooldown = 300 metric_aggregation_type = "Average" step_adjustment { metric_interval_upper_bound = 0 scaling_adjustment = -1 } } }

Step scaling works in conjunction with CloudWatch alarms that trigger the policy via alarm_actions.

Module Parameters for Reusable Policies

A reusable Terraform module for app autoscaling exposes parameters to control policy creation.

Module variables include:

  • app
    the name of the application expressed as an acronym
    string
    n/a
    yes
  • env
    the target tier ('dev', 'qa', 'stage', or 'prod'.)
    string
    n/a
    yes
  • policy_type
    scaling policy - either 'StepScaling' or 'TargetTrackingScaling'
    string
    "TargetTrackingScaling"
    no
  • predefinedmetrictype
    the name of the pre-defined aws cloudwatch metric type to base autoscaling activities on
    string
    "ECSServiceAverageCPUUtilization"
    no
  • program
    the program associated with the application
    string
    n/a
    yes
  • resource_id
    resource type and unique identifier string for the resource associated with the scaling policy - use outputs from appautoscaling target resource
    string
    n/a
    yes
  • resourcenamesuffix
    resource name suffix that follows the stack name
    string
    n/a
    yes
  • scalable_dimension
    calable dimension of the scalable target - use outputs from appautoscaling target resource
    string
    n/a
    yes
  • service_namespace
    aws service namespace of the scalable target - use outputs from the appautoscaling target resource
    string
    n/a
    yes
  • target_value
    target value of the metric to invoke autoscaling activity
    number
    80
    no

The module defaults to TargetTrackingScaling with a predefined metric of ECSServiceAverageCPUUtilization and a target value of 80.

ECS Auto Scaling Patterns and Drift Prevention

ECS auto scaling in Terraform starts with awsappautoscalingtarget to register the service, then awsappautoscalingpolicy for the scaling logic.

To prevent Terraform from overriding auto scaler adjustments, a lifecycle block is used:

lifecycle { ignore_changes = [desired_count] }

Without this, every terraform apply would reset the task count to whatever is in your Terraform config, overriding the auto scaler's adjustments.

Choosing Scaling Thresholds

The right thresholds depend on your application, but here are guidelines:

  • CPU target tracking at 70% leaves headroom for traffic spikes while still using resources efficiently
  • Scale-out cooldown of 60 seconds lets you respond quickly to growing demand
  • Scale-in cooldown of 300 seconds prevents premature scale-in during temporary dips
  • Always keep minimum tasks >= 2 for availability across AZs
  • Use ALBRequestCountPerTarget for web services - it responds to load before CPU saturates

Outputs from an ECS autoscaling setup typically include:

output "scaling_target_resource_id" { value = aws_appautoscaling_target.ecs.resource_id } output "min_capacity" { value = aws_appautoscaling_target.ecs.min_capacity } output "max_capacity" { value = aws_appautoscaling_target.ecs.max_capacity }

A complete ECS pattern combines target tracking, step scaling, and scheduled scaling for the most responsive setup.

CloudWatch Alarm Integration

Step scaling policies are often triggered by CloudWatch metric alarms.

Scale out alarm example:

resource "aws_cloudwatch_metric_alarm" "cpu_high" { alarm_name = "myapp-cpu-high" comparison_operator = "GreaterThanThreshold" evaluation_periods = 2 metric_name = "CPUUtilization" namespace = "AWS/ECS" period = 60 statistic = "Average" threshold = 70 dimensions = { ClusterName = var.ecs_cluster_name ServiceName = aws_ecs_service.app.name } alarm_actions = [aws_appautoscaling_policy.scale_out.arn] }

Scale in alarm example:

resource "aws_cloudwatch_metric_alarm" "cpu_low" { alarm_name = "myapp-cpu-low" comparison_operator = "LessThanThreshold" evaluation_periods = 5 metric_name = "CPUUtilization" namespace = "AWS/ECS" period = 60 statistic = "Average" threshold = 30 dimensions = { ClusterName = var.ecs_cluster_name ServiceName = aws_ecs_service.app.name } alarm_actions = [aws_appautoscaling_policy.scale_in.arn] }

Scheduled Scaling for Predictable Traffic

If your traffic patterns are predictable like business hours, schedule scaling changes:

resource "aws_appautoscaling_scheduled_action" "scale_up" { name = "myapp-scale-up-business-hours" service_namespace = aws_appautoscaling_target.ecs.service_namespace resource_id =

Scheduled actions complement reactive policies by pre-warming capacity.

Policy Type Comparison

| Feature | StepScaling | TargetTrackingScaling |
| PolicyType value | StepScaling | TargetTrackingScaling |
| Control | Manual steps with metric intervals | Automatic target value maintenance |
| Cooldown | Per policy | ScaleInCooldown, ScaleOutCooldown |
| Metric | CloudWatch alarm driven | Predefined or customized metric |
| Use case | Non-linear scaling, fine grained control | Default stable load handling |

Conclusion

Terraform awsappautoscalingpolicy provides a direct mapping to AWS Application Auto Scaling scaling policies with support for StepScaling, TargetTrackingScaling, and PredictiveScaling via CloudFormation properties. The resource requires a matching awsappautoscalingtarget to define resourceid, scalabledimension, and servicenamespace. Target tracking is the best default for most workloads, with a CPU target around 70% and a scale-out cooldown of 60 seconds and scale-in cooldown of 300 seconds. Step scaling enables non-linear adjustments with multiple stepadjustment blocks keyed to metric intervals. Customized metrics such as SageMaker ApproximateBacklogSizePerInstance require explicit Dimensions mapping to CloudWatch dimensions. Drift prevention via lifecycle ignorechanges on desiredcount is essential for ECS services to allow the auto scaler to manage capacity without Terraform resets. Combining target tracking, step scaling, scheduled actions, and proper cooldowns yields a responsive and stable auto scaling system across ECS, SageMaker, and other AWS services.

Sources

  1. AWS CloudFormation Documentation
  2. NCI-CRDC terraform-aws-appautoscaling-policy
  3. OneUptime ECS Auto Scaling Terraform Guide
  4. Repost AWS SageMaker Auto Scaling Question
  5. Koding AWS App Autoscaling Policy Docs

Related Posts