You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform引用现有Auto Scaling Group名称创建策略报错求助

Terraform模块:批量查询ASG并创建伸缩策略问题解决

需求与原代码

需要通过Terraform自动查询符合条件的现有Auto Scaling Group(ASG)名称,为每个ASG创建Auto Scaling Policy,并封装为Terraform模块。原代码如下:

data "external" "eks_cluster_asg" {
  program = ["bash", "-c", <<EOT
    AWS_OUTPUT=$(aws autoscaling describe-auto-scaling-groups \\
      --query "AutoScalingGroups[?contains(Tags[?Key=='k8s.io/cluster-autoscaler/enabled'], 'true') && contains(Tags[?Key=='k8s.io/cluster-autoscaler/cluster-name'], '${var.prefix}')].AutoScalingGroupName" \\
      --output json \\
      --region ${var.aws_region})
    echo "{\"autoscaling_group_name\": \"${AWS_OUTPUT}\"}"
EOT
  ]
}

resource "aws_autoscaling_policy" "example" {
  autoscaling_group_name = jsondecode(data.external.eks_cluster_asg.result)["autoscaling_group_name"]
  policy_type           = "TargetTrackingScaling"
  name                  = "my-policy"

  target_tracking_configuration {
    predefined_metric_specification {
      predefined_metric_type = "ASGAverageCPUUtilization"
    }

    target_value = 70
  }
}

错误信息

执行代码时报错:

无效引用 echo "{\"autoscaling_group_name\": \"${AWS_OUTPUT}\"}",提示资源类型的引用后必须至少跟一个属性访问,并指定资源名称

问题根源与修正方案

问题根源

Terraform会将bash脚本中的${...}语法识别为自身的插值引用,而非bash变量。原代码中${AWS_OUTPUT}被Terraform误判为资源引用,导致报错。此外,原代码返回的ASG名称是JSON数组,但单条aws_autoscaling_policy只能对应单个ASG,无法直接批量创建。

修正后的代码

variable "prefix" {
  type        = string
  description = "EKS集群名称前缀"
}

variable "aws_region" {
  type        = string
  description = "AWS区域"
}

data "external" "eks_cluster_asg" {
  program = [
    "bash",
    "-c",
    <<EOT
      aws autoscaling describe-auto-scaling-groups \\
        --query "AutoScalingGroups[?contains(Tags[?Key=='k8s.io/cluster-autoscaler/enabled'], 'true') && contains(Tags[?Key=='k8s.io/cluster-autoscaler/cluster-name'], '${var.prefix}')].AutoScalingGroupName" \\
        --output json \\
        --region ${var.aws_region}
EOT
  ]
}

locals {
  asg_names = jsondecode(data.external.eks_cluster_asg.result)
}

resource "aws_autoscaling_policy" "example" {
  for_each              = toset(local.asg_names)
  autoscaling_group_name = each.value
  policy_type           = "TargetTrackingScaling"
  name                  = "my-policy-${each.value}"

  target_tracking_configuration {
    predefined_metric_specification {
      predefined_metric_type = "ASGAverageCPUUtilization"
    }

    target_value = 70
  }
}

关键修正点

  1. 消除Terraform与bash插值冲突:移除bash变量AWS_OUTPUT,直接让AWS CLI命令输出JSON数组结果,避免Terraform误解析bash变量。
  2. 批量创建策略:通过jsondecode将查询结果转为列表,使用for_each遍历每个ASG名称,为每个ASG单独创建伸缩策略,同时为策略名称添加ASG后缀避免重复。
  3. 简化逻辑:去掉不必要的JSON包装步骤,直接使用AWS CLI的输出结果作为data源。

内容的提问来源于stack exchange,提问作者Mariana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:30:22