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

CloudFormation模板中如何为ALB目标组导入并替换EC2实例ID

问题

我正在通过CloudFormation模板创建ALB,其中目标组资源需要导入之前任务导出的EC2实例ID,希望通过Sub函数替换导入名称以适配不同环境部署。用cfn-lint验证模板显示正确,但部署时收到错误:

No export named found

已确认所有预期导出名称符合命名规范且存在于对应栈中,查看CloudFormation转换后的模板,发现Fn::ImportValue后是空字符串,未读取Sub命令的结果。

原始模板内容:

AWSTemplateFormatVersion: "2010-09-09"
Description: Creates an application load balancer.
Parameters:
  pSystem:
    Type: String
    Default: your-system-name
    Description: 'Name of the system. Default: your-system-name'
  pApp:
    Type: String
    Description: 'Name of the application solution'
  pEnvironment:
    Type: String
    Default: sbx
    Description: 'Name of the deployment tier. Default: sbx'
  pVpcId:
    Type: AWS::SSM::Parameter::Value<String>

Resources:

  rLoadBalancerTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub '${pSystem}-${pApp}-${pEnvironment}-public-tg'
      HealthCheckEnabled: true
      HealthCheckIntervalSeconds: 60
      HealthCheckPath: 'REDACTED'
      HealthCheckPort: 1234
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 10
      HealthyThresholdCount: 2
      Matcher: 
        HttpCode: 200-299
      Port: 1234
      Protocol: HTTP
      ProtocolVersion: HTTP1
      TargetGroupAttributes: 
        - Key: 'deregistration_delay.timeout_seconds'
          Value: 300
        - Key: 'stickiness.enabled'
          Value: false
        - Key: 'load_balancing.algorithm.type'
          Value: round_robin
        - Key: 'slow_start.duration_seconds'
          Value: 0
      TargetType: instance
      UnhealthyThresholdCount: 2
      VpcId: !Ref pVpcId
      Targets: 
        - Id: !ImportValue 
          Fn::Sub: '${pSystem}-${pApp}-01-${pEnvironment}-ec2-id'
        - Id: !ImportValue
          Fn::Sub: "${pSystem}-${pApp}-02-${pEnvironment}-ec2-id"
        - Id: !ImportValue
          Fn::Sub: "${pSystem}-${pApp}-03-${pEnvironment}-ec2-id"

转换后的模板中Targets部分:

Targets:
- Id:
    Fn::ImportValue: ''
  Fn::Sub: ${pSystem}-${pApp}-01-${pEnvironment}-ec2-id
- Id:
    Fn::ImportValue: ''
  Fn::Sub: ${pSystem}-${pApp}-02-${pEnvironment}-ec2-id
- Id:
    Fn::ImportValue: ''
  Fn::Sub: ${pSystem}-${pApp}-03-${pEnvironment}-ec2-id
解决方案

问题出在YAML语法的嵌套写法错误:当前模板中!ImportValue和Fn::Sub被当作Id字段下的同级键,导致Fn::ImportValue没有接收任何参数,因此显示为空字符串。

正确的写法是将Fn::Sub的结果作为Fn::ImportValue的输入,需要把Sub嵌套在ImportValue内部,有两种写法:

写法1:使用短格式嵌套

Targets: 
  - Id: !ImportValue !Sub '${pSystem}-${pApp}-01-${pEnvironment}-ec2-id'
  - Id: !ImportValue !Sub '${pSystem}-${pApp}-02-${pEnvironment}-ec2-id'
  - Id: !ImportValue !Sub '${pSystem}-${pApp}-03-${pEnvironment}-ec2-id'

写法2:使用完整函数嵌套格式

Targets: 
  - Id:
      Fn::ImportValue:
        Fn::Sub: '${pSystem}-${pApp}-01-${pEnvironment}-ec2-id'
  - Id:
      Fn::ImportValue:
        Fn::Sub: '${pSystem}-${pApp}-02-${pEnvironment}-ec2-id'
  - Id:
      Fn::ImportValue:
        Fn::Sub: '${pSystem}-${pApp}-03-${pEnvironment}-ec2-id'

修正后的完整模板:

AWSTemplateFormatVersion: "2010-09-09"
Description: Creates an application load balancer.
Parameters:
  pSystem:
    Type: String
    Default: your-system-name
    Description: 'Name of the system. Default: your-system-name'
  pApp:
    Type: String
    Description: 'Name of the application solution'
  pEnvironment:
    Type: String
    Default: sbx
    Description: 'Name of the deployment tier. Default: sbx'
  pVpcId:
    Type: AWS::SSM::Parameter::Value<String>

Resources:

  rLoadBalancerTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub '${pSystem}-${pApp}-${pEnvironment}-public-tg'
      HealthCheckEnabled: true
      HealthCheckIntervalSeconds: 60
      HealthCheckPath: 'REDACTED'
      HealthCheckPort: 1234
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 10
      HealthyThresholdCount: 2
      Matcher: 
        HttpCode: 200-299
      Port: 1234
      Protocol: HTTP
      ProtocolVersion: HTTP1
      TargetGroupAttributes: 
        - Key: 'deregistration_delay.timeout_seconds'
          Value: 300
        - Key: 'stickiness.enabled'
          Value: false
        - Key: 'load_balancing.algorithm.type'
          Value: round_robin
        - Key: 'slow_start.duration_seconds'
          Value: 0
      TargetType: instance
      UnhealthyThresholdCount: 2
      VpcId: !Ref pVpcId
      Targets: 
        - Id: !ImportValue !Sub '${pSystem}-${pApp}-01-${pEnvironment}-ec2-id'
        - Id: !ImportValue !Sub '${pSystem}-${pApp}-02-${pEnvironment}-ec2-id'
        - Id: !ImportValue !Sub '${pSystem}-${pApp}-03-${pEnvironment}-ec2-id'

这样修改后,CloudFormation会先执行Sub生成正确的导出名称,再通过ImportValue获取对应的EC2实例ID,解决部署报错问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:50:54