CloudFormation安全组CidrIp用!GetAtt报错,求动态变量等解决方法
CloudFormation安全组CIDR引用问题解决方案
错误原因
你遇到的Invalid GetAtt报错,是因为AWS::EC2::Subnet资源不支持通过!GetAtt获取CidrBlock属性。CloudFormation中Subnet的!GetAtt仅开放了AvailabilityZone、Ipv6CidrBlocks等有限属性,CidrBlock不在可用列表内。
解决方案1:直接复用Sub表达式(最简方案)
既然子网的CIDR是通过!Sub "10.${ClusterId}.0.0/24"生成的,安全组规则里直接复用相同的表达式即可,确保两者完全一致:
SecurityGroup1: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security Group 1 VpcId: !Ref VPC SecurityGroupIngress: - CidrIp: !Sub "10.${ClusterId}.0.0/24" IpProtocol: -1
解决方案2:用Fn::Cidr统一生成CIDR块(适合多子网/动态计算场景)
如果需要创建多个子网,或CIDR需基于VPC网段动态划分,可通过Fn::Cidr函数预先生成CIDR列表,再在子网和安全组中统一引用:
Parameters: ClusterId: Type: String Description: Cluster ID Resources: VPC: Type: 'AWS::EC2::VPC' Properties: CidrBlock: !Sub "10.${ClusterId}.0.0/16" EnableDnsSupport: true EnableDnsHostnames: true InfrastructureSubnetPrivateA: Type: "AWS::EC2::Subnet" Properties: AvailabilityZone: !Select [0, !GetAZs ] # 从VPC网段中生成1个/24掩码的子网CIDR CidrBlock: !Select [0, !Cidr [!GetAtt VPC.CidrBlock, 1, 8]] MapPublicIpOnLaunch: false VpcId: !Ref VPC Tags: - Key: Name Value: infrastructure-subnet-private-a - Key: Group Value: infrastructure SecurityGroup1: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security Group 1 VpcId: !Ref VPC SecurityGroupIngress: # 复用同一个动态生成的CIDR - CidrIp: !Select [0, !Cidr [!GetAtt VPC.CidrBlock, 1, 8]] IpProtocol: -1
!Cidr [!GetAtt VPC.CidrBlock, 1, 8]的含义是:以VPC的CIDR为基础,生成1个子网网段,子网掩码长度为VPC掩码长度+8(即VPC是/16,子网就是/24)。
解决方案3:通过安全组引用替代CIDR(可选)
如果你的目标是允许子网内的资源访问,也可以给子网内的资源统一绑定一个安全组,然后在SecurityGroup1的Ingress规则中直接引用该安全组ID,无需使用CIDR:
# 先定义子网资源用的安全组 SubnetResourcesSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: SG for resources in private subnet A VpcId: !Ref VPC # 子网资源绑定这个SG(比如EC2、RDS等) # ... SecurityGroup1: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security Group 1 VpcId: !Ref VPC SecurityGroupIngress: - SourceSecurityGroupId: !Ref SubnetResourcesSG IpProtocol: -1
内容的提问来源于stack exchange,提问作者learner00
相关产品推荐
相关产品推荐

