CloudFormation栈创建失败:需指定两个不同可用区的子网
解决AWS CloudFormation中ELB等资源因跨可用区子网不足创建失败的问题
错误提示明确要求负载均衡器必须指定至少两个位于不同可用区的子网,当前你的模板存在两个关键问题:
- 所有子网未显式指定可用区,AWS默认会将它们放置在同一个可用区
- 负载均衡器
LoadBalance仅关联了一个子网Subnet1
1. 定义跨可用区的子网
在子网资源的Properties中添加AvailabilityZone属性,指定不同的可用区。推荐使用AWS内置伪参数动态获取当前区域的可用区,避免硬编码:
- 给
Subnet1添加:AvailabilityZone: !Select [0, !GetAZs ''] - 给
Subnet2添加:AvailabilityZone: !Select [1, !GetAZs '']
!GetAZs ''会返回当前部署区域的所有可用区列表,!Select选取列表中第0和第1个可用区,确保两个子网处于不同可用区。
2. 给负载均衡器关联多个跨可用区子网
修改LoadBalance的Subnets属性,添加至少两个子网:
Subnets: - !Ref Subnet1 - !Ref Subnet2
3. 修正模板中的其他错误
模板还有两处明显错误需要修正,否则即使解决子网问题,栈仍会创建失败:
- AppLBListnerS1的TargetGroupArn错误:当前指向
!Ref VPC,应该关联一个AWS::ElasticLoadBalancingV2::TargetGroup资源,需先定义目标组再引用其ARN。 - EC2Net2资源缺失:错误提示中提到
EC2Net2创建失败,但模板中仅存在EC2Net1,请确认是否遗漏了该资源定义。
修正后的完整模板示例
--- AWSTemplateFormatVersion: 2010-09-09 Parameters: DBName: Default: RBDB Description: 数据库名称 Type: String MinLength: '1' MaxLength: '64' AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' DBUsername: Type: String Description: 数据库主用户名 Default: admin DBPassword: Type: String NoEcho: true Description: 数据库主密码 Default: password DBInstanceClass: Default: db.m5.large Description: 数据库实例类型 Type: String DBAllocStore: Default: '500' Description: 数据库存储大小(GiB) Type: Number MinValue: '20' MaxValue: '65536' RBDBInstance: Default: RBDBInstance Description: 数据库实例标识符 Type: String MinLength: '1' MaxLength: '80' AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: VPC S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: 'aws--S3Bucket' IGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: VPC Internet Gateway Subnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.20.0/24 AvailabilityZone: !Select [0, !GetAZs ''] # 新增:指定第一个可用区 MapPublicIpOnLaunch: false Tags: - Key: Name Value: 'PrivateSubnet1' Subnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.30.0/24 AvailabilityZone: !Select [1, !GetAZs ''] # 新增:指定第二个可用区 MapPublicIpOnLaunch: true Tags: - Key: Name Value: 'PublicSubnet2' SSHSecGrp: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: Security group egress SecurityGroupEgress: - CidrIp: 127.0.0.111/32 IpProtocol: "-1" EC2SecGrp: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: EC2 Security Group GroupName: aws-security-grp SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 EC2Net1: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: 'ami-05c13eab67c5d8861' SecurityGroupIds: - !Ref EC2SecGrp SubnetId: !Ref Subnet1 KeyName: EC2Net1 UserData: Fn::Base64: !Sub | #!/bin/bash yum update -y yum install -y httpd systemctl start httpd systemctl enable httpd #echo "<h1>Hello from Region us-east-2b</h1>" > /var/www/html/index.html # 新增:定义目标组,供负载均衡器监听使用 TargetGroup1: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: VpcId: !Ref VPC Port: 80 Protocol: HTTP TargetType: instance Targets: - Id: !Ref EC2Net1 S3BuckPol: Type: 'AWS::S3::BucketPolicy' Properties: Bucket: !Ref S3Bucket PolicyDocument: Statement: - Effect: Allow Action: 's3:*' Resource: !Sub 'arn:aws:s3:::${S3Bucket}/*' Principal: AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:user/@matthew' LoadBalance: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: aws-elb-load-balance2 Scheme: internet-facing Subnets: - !Ref Subnet1 # 保留第一个子网 - !Ref Subnet2 # 新增:添加第二个跨可用区子网 AppLBListnerS1: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref TargetGroup1 # 修改为引用目标组ARN LoadBalancerArn: !Ref LoadBalance Port: 80 Protocol: HTTP MyRDS: Type: 'AWS::RDS::DBInstance' Properties: DBInstanceIdentifier: !Ref RBDBInstance DBName: !Ref DBName DBInstanceClass: !Ref DBInstanceClass AllocatedStorage: !Ref DBAllocStore Engine: MySQL MasterUsername: !Ref DBUsername MasterUserPassword: !Ref DBPassword Outputs: EC2InstanceNet1: Value: !Ref EC2Net1 S3BucketName: Value: !Ref S3Bucket DBInstanceId: Value: !Ref RBDBInstance LoadBalancerDNS: Value: !GetAtt LoadBalance.DNSName
内容的提问来源于stack exchange,提问作者Data Science Analytics Manager
相关产品推荐
相关产品推荐

