Сбой при создании прослушивателя AWS ELB из-за исключения проверки

Создание моего стека CloudFormation завершается неудачей из-за очень общей ошибки, и я не могу понять, почему.

Я создаю задачу обслуживания ECS с одним контейнером с помощью ALB.

Вот мой шаблон стека:

AWSTemplateFormatVersion: '2010-09-09'
Description: Services Containers

Parameters:
  VpcId:
    Type: String
    Default: vpc-4796bd23
  SubnetId:
    Type: String
    Default: subnet-f4701ff8
  ELBSecondarySubnetId:
    Type: String
    Default: subnet-8a453cef
  ECSCluster:
    Type: String
    Default: dev-ecs
  EcsSecurityGroup:
    Type: String
    Default: sg-74cb7b0c
  Color:
    Type: String
    AllowedValues: ['blue', 'green']
    Description: The deployment color
    Default: 'blue'
  BuildVersion:
    Type: String
    Description: The build version to deploy
  ComPublic:
    Type: String
    Description: Hosted Zone ID
    Default: Z00669325SSURKTK4ZPA
  MQPort:
    Type: Number
    Description: MQ Connectivity port
    Default: 5672

Resources:
  ApiLogsGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Join ['-', [ path-services-api, !Ref Color ]]
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      ContainerDefinitions:
        - Essential: True
          Image: ***.dkr.ecr.us-east-1.amazonaws.com/path-services/path-services-api
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref ApiLogsGroup
              awslogs-region: us-east-1
              awslogs-stream-prefix: !Ref BuildVersion
          Name: path-services-api
          PortMappings:
            - ContainerPort: !Ref MQPort
              Protocol: tcp
      ExecutionRoleArn: arn:aws:iam::***:role/ecs-task-execution-role
      Family: path-services-api
      NetworkMode: awsvpc
      Cpu: 4096
      Memory: 8192 # max
      RequiresCompatibilities: 
        - FARGATE
      TaskRoleArn: !Ref ServiceTaskRole
  ServiceTaskRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: ['ecs-tasks.amazonaws.com', 'ecs.amazonaws.com']
            Action: ['sts:AssumeRole']
      Path: /
      Policies:
        - PolicyName: !Join ['-', [path-services, !Ref Color, read-secrets]]
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - 'secretsmanager:ListSecrets'
                  - 'secretsmanager:DescribeSecret'
                  - 'secretsmanager:GetRandomPassword'
                  - 'secretsmanager:GetResourcePolicy'
                  - 'secretsmanager:GetSecretValue'
                  - 'secretsmanager:ListSecretVersionIds'
                Resource: [ 'arn:aws:secretsmanager:us-east-1:***:secret:prod/path-services*' ]
  PathService:
    Type: AWS::ECS::Service
    DependsOn: LoadBalancerListener
    Properties:
      Cluster: !Ref ECSCluster
      DesiredCount: 1
      LaunchType: FARGATE
      LoadBalancers:
        - ContainerName: path-services-api
          ContainerPort: !Ref MQPort
          TargetGroupArn: !Ref TargetGroup
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - !Ref EcsSecurityGroup
          Subnets:
            - !Ref SubnetId
      PropagateTags: SERVICE
      ServiceName: !Join ['-', [ path-services-api, !Ref Color ] ]
      TaskDefinition: !Ref TaskDefinition
  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckPort: !Ref MQPort
      HealthCheckProtocol: TCP
      Port: !Ref MQPort
      Protocol: TCP
      TargetType: ip
      VpcId: !Ref VpcId
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      IpAddressType: ipv4
      LoadBalancerAttributes:
        - Key: routing.http2.enabled
          Value: false
      Scheme: internet-facing
      SecurityGroups:
        - !Ref EcsSecurityGroup
      Subnets:
        - !Ref SubnetId
        - !Ref ELBSecondarySubnetId
      Type: application
  LoadBalancerListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref TargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: !Ref MQPort
      Protocol: TCP
  ServiceScalingPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    DependsOn: PathService
    Properties:
      PolicyName: !Join ['-', [ path-services-api, !Ref Color, scaling-policy ] ]
      PolicyType: TargetTrackingScaling
      ResourceId: !Join [ '/', [ service, !Ref ECSCluster, !Join ['-', [ path-services-api, !Ref Color ] ] ] ]
      ScalableDimension: ecs:service:DesiredCount
      ServiceNamespace: ecs
      TargetTrackingScalingPolicyConfiguration:
        PredefinedMetricSpecification:
          PredefinedMetricType: ECSServiceAverageCPUUtilization
        ScaleInCooldown: 30
        ScaleOutCooldown: 30
        TargetValue: 70.0
  # Route53Record:
  #   Type: AWS::Route53::RecordSet
  #   Properties:
  #     HostedZoneId: !Ref ComPublic
  #     Name: ***
  #     AliasTarget:
  #       DNSName: ApplicationLoadBalancer.DNSName
  #       HostedZoneId: !GetAtt ApplicationLoadBalancer.CanonicalHostedZoneI
  #     TTL: 600
  #     Type: A
  ServiceCpuAlarm:
    Type: AWS::CloudWatch::Alarm
    DependsOn: PathService
    Properties:
      AlarmActions:
        - !Ref ServiceAlarmTopic
      OKActions:
        - !Ref ServiceAlarmTopic
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 1
      Dimensions:
        - Name: Service
          Value: !GetAtt PathService.Name
      EvaluationPeriods: 1
      MetricName: CPUUtilization
      Namespace: AWS/ECS
      Period: 60
      Statistic: Maximum
      Threshold: 90
      TreatMissingData: notBreaching
  ServiceMemoryAlarm:
    Type: AWS::CloudWatch::Alarm
    DependsOn: PathService
    Properties:
      AlarmActions:
        - !Ref ServiceAlarmTopic
      OKActions:
        - !Ref ServiceAlarmTopic
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 1
      Dimensions:
        - Name: Service
          Value: !GetAtt PathService.Name
      EvaluationPeriods: 1
      MetricName: MemoryUtilization
      Namespace: AWS/ECS
      Period: 60
      Statistic: Maximum
      Threshold: 90
      TreatMissingData: notBreaching
  ServiceAlarmTopic:
    Type: AWS::SNS::Topic
    DependsOn: PathService
    Properties:
      TopicName: path-services-api-alarm-topic
      Subscription:
        - Endpoint: ***
          Protocol: email
        - Endpoint: ***
          Protocol: email

Ошибка создания стека CloudFormation на ресурсе LoadBalancerListener с причиной состояния:

Invalid request provided: AWS::ElasticLoadBalancingV2::Listener Validation exception

Я пока не обнаружил подобной проблемы и не знаю, где получить более подробную информацию о том, что не так. Спасибо.




Ответы (3)


Вероятно, это происходит из-за того, что вы используете балансировщик нагрузки приложения:

Type: application

Однако вы указываете, что ваш протокол подключения - TCP. Это явно неверно, поскольку ALB поддерживает только протоколы HTTP и HTTPS. Для TCP вам понадобится балансировщик сетевой нагрузки (NLB).

person Marcin    schedule 29.11.2020

Хотя приведенный выше ответ на 100% верен, я просто хочу уточнить немного больше для тех, кто сталкивается с этой же проблемой. @marcin утверждает, что тип балансировщика нагрузки - это приложение, но протокол - TCP. Здесь он ссылается на два отдельных объекта шаблона CF.

При создании балансировщика нагрузки вам действительно нужно определить 3 разных объекта в шаблоне CF. Балансировщик нагрузки, прослушиватель балансировщика нагрузки и целевая группа (место, куда балансировщик нагрузки будет отправлять трафик).

Итак, если типом балансировщика нагрузки является приложение, связанная TargetGroup должна иметь протокол HTTP или HTTPS. Тип TCP выдаст эту ошибку.

person Avery Pfeiffer    schedule 03.01.2021

У меня была та же проблема, но благодаря облачной информации одно сообщение об ошибке всегда может означать несколько вещей. В моем случае это была ошибка разрешения на балансировщике нагрузки. Попробуйте добавить это разрешение в свою политику:

Statement:
- Effect: Allow
  Action: 
    - elasticloadbalancing:*
    - elasticloadbalancingv2:*
  Resource: *

Если это решит вашу проблему, вы точно знаете, что это проблема с разрешением на эластичную балансировку нагрузки. Попробуйте сузить круг, постепенно уменьшая разрешения. Подсказка: некоторые разрешения для балансировки нагрузки НЕ зависят от ресурса, для них вам понадобится Resource: * для выполнения определенных действий с ним. Из документов AWS :

Столбец Типы ресурсов указывает, поддерживает ли каждое действие разрешения на уровне ресурсов. Если для этого столбца нет значения, вы должны указать все ресурсы (*) в элементе Resource вашего заявления политики. Если столбец включает тип ресурса, вы можете указать ARN этого типа в инструкции с этим действием.

person Robbert van den Bogerd    schedule 03.06.2021