Ec2 和弹性负载均衡器

时间:2021-02-23 21:37:10

标签: amazon-web-services amazon-ec2 amazon-elb

请考虑这种情况:

我想部署一个 CloudFormation 堆栈,其中包含弹性负载均衡器将流量路由到 EC2 所需的基本资源。

我从一个附加了 VPC、InternetGateway、VPCGatewayAttachment、RouteTable、Route、SubnetRouteTableAssociation 的模板中剥离了波纹管模板。

我这样做是因为我认为 AWS 会为我配置一个默认 VPC。

Mappings:
  NetworkToSubnet:
    "10.0.0.0":
        PubSubnetZoneA: "10.0.10.0/24"
        PrivSubnetZoneA: "10.0.20.0/24"
        PubSubnetZoneB: "10.0.30.0/24"
        PrivSubnetZoneB: "10.0.40.0/24"


Resources: 
  # Internet accessable subnet in the first availability zone
  PubSubnetZoneA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      AvailabilityZone:
        Fn::Select:
        - '0'
        - Fn::GetAZs:
            Ref: 'AWS::Region'
      CidrBlock:
        Fn::FindInMap:
        - NetworkToSubnet
        - '10.0.0.0'
        - PubSubnetZoneA
      MapPublicIpOnLaunch: 'True'
      Tags:
        - Key: 'Name'
          Value:
              'Fn::Join': [ ':', [ 'Public', 'Zone A', !Ref 'AWS::StackName' ] ]

  # Non-internet accessable subnet in the first availability zone
  PrivSubnetZoneA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      AvailabilityZone:
        Fn::Select:
        - '0'
        - Fn::GetAZs:
            Ref: 'AWS::Region'
      CidrBlock:
        Fn::FindInMap:
        - NetworkToSubnet
        - '10.0.0.0'
        - PrivSubnetZoneA
      MapPublicIpOnLaunch: 'False'
      Tags:
        - Key: 'Name'
          Value:
              'Fn::Join': [ ':', [ 'Private', 'Zone A', !Ref 'AWS::StackName' ] ]

  # Internet accessable subnet in the second availability zone
  PubSubnetZoneB:
    Type: 'AWS::EC2::Subnet'
    Properties:
      AvailabilityZone:
        Fn::Select:
        - '1'
        - Fn::GetAZs:
            Ref: 'AWS::Region'
      CidrBlock:
        Fn::FindInMap:
        - NetworkToSubnet
        - '10.0.0.0'
        - PubSubnetZoneB
      MapPublicIpOnLaunch: 'True'
      Tags:
        - Key: 'Name'
          Value:
              'Fn::Join': [ ':', [ 'Public', 'Zone B', !Ref 'AWS::StackName' ] ]

  # Non-internet accessable subnet in the second availability zone
  PrivSubnetZoneB:
    Type: 'AWS::EC2::Subnet'
    Properties:
      AvailabilityZone:
        Fn::Select:
        - '1'
        - Fn::GetAZs:
            Ref: 'AWS::Region'
      CidrBlock:
        Fn::FindInMap:
        - NetworkToSubnet
        - '10.0.0.0'
        - PrivSubnetZoneB
      MapPublicIpOnLaunch: 'False'
      Tags:
        - Key: 'Name'
          Value:
              'Fn::Join': [ ':', [ 'Private', 'Zone B', !Ref 'AWS::StackName' ] ]




  # EC2 Security Group Allowing Port 22 and 80 from anywhere
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'SSH and Port 80'
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId:
              Ref: ELBSecurityGroup

  # ELB Security Group allowing Port 80 from anywhere
  ELBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'SSH and Port 80'
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  # Linux Instance with Apache running on Port 80
  AmazonLinuxInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0ffd774e02309201f
      InstanceInitiatedShutdownBehavior: stop
      InstanceType: t2.nano
      Monitoring: 'true'
      NetworkInterfaces:
      - AssociatePublicIpAddress: 'true'
        DeviceIndex: '0'
        GroupSet:
        - !Ref EC2SecurityGroup
      Tenancy: default
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          cd /tmp
          yum update -y
          yum install -y httpd24
          echo "Healthy" > /var/www/html/index.html
          service httpd start
          /opt/aws/bin/cfn-signal \
            -e $? \
            --stack ${AWS::StackName} \
            --resource AmazonLinuxInstance \
            --region ${AWS::Region}

  # Target Group
  EC2TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 15
      HealthyThresholdCount: 5
      Matcher:
        HttpCode: '200'
      Name: EC2TargetGroup
      Port: 80
      Protocol: HTTP
      TargetGroupAttributes:
      - Key: deregistration_delay.timeout_seconds
        Value: '20'
      Targets:
      - Id:
          Ref: AmazonLinuxInstance
        Port: 80
      UnhealthyThresholdCount: 3
      Tags:
      - Key: Name
        Value: EC2TargetGroup
      - Key: Port
        Value: 80

  #ELB (ALB)
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn:
            Ref: EC2TargetGroup
      LoadBalancerArn:
          Ref: ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP

  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing # or internal

Outputs:
  ALBHostName:
      Description: 'Application Load Balancer Hostname'
      Value:
        !GetAtt ApplicationLoadBalancer.DNSName
  EC2Instance:
      Description: 'EC2 Instance'
      Value:
        Ref: AmazonLinuxInstance
  EC2TargetGroup:
      Description: 'EC2 Target Group'
      Value:
        Ref: EC2TargetGroup
  ApplicationLoadBalancer:
      Description: 'Application Load Balancer'
      Value:
        Ref: ApplicationLoadBalancer

在提供堆栈时,出现以下错误:

 The following resource(s) failed to create: [PubSubnetZoneB, PrivSubnetZoneA, 
 PrivSubnetZoneB, ApplicationLoadBalancer, ELBSecurityGroup, PubSubnetZoneA]. Rollback 
 requested by user.

 At least two subnets in two different Availability Zones must be specified (Service: 
 AmazonElasticLoadBalancing; Status Code: 400; Error Code: ValidationError; Request ID: 000- 
 0000-0000-0000-0000; Proxy: null)

ELB 所需的最少资源是什么,才能将流量定向到 EC2?

1 个答案:

答案 0 :(得分:0)

错误是说 At least two subnets in two different Availability Zones must be specified

来自AWS::ElasticLoadBalancingV2::LoadBalancer - AWS CloudFormation

<块引用>

子网

子网的 ID。每个可用区只能指定一个子网。您必须指定子网或子网映射。

[应用程序负载均衡器] 您必须指定来自至少两个可用区的子网。当您为现有应用程序负载均衡器指定子网时,它们会替换之前启用的子网。

因此,您需要将 Subnets 添加到您的负载均衡器定义中。它必须至少有两个子网,每个子网位于不同的可用区。