AWS ELB 侦听器创建失败并出现验证异常
AWS ELB Listener creation fails with Validation exception
我的 CloudFormation 堆栈创建失败并出现一个非常普遍的错误,我似乎无法弄清楚原因。
我正在使用 ALB 创建单容器 ECS 服务任务。
这是我的堆栈模板:
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
资源 LoadBalancerListener
上的 CloudFormation 堆栈创建失败,状态原因:
Invalid request provided: AWS::ElasticLoadBalancingV2::Listener Validation exception
到目前为止我还没有发现类似的问题,也不知道从哪里可以获得有关问题的更多详细信息。谢谢。
发生这种情况可能是因为您正在使用应用程序负载均衡器:
Type: application
但是,您指定连接协议是 TCP
。这显然是不正确的,因为 ALB 只支持 HTTP 和 HTTPS 协议。对于 TCP,您需要 网络负载平衡器 (NLB)。
虽然上面的答案是 100% 正确的,但我只想为那些 运行 遇到同样问题的人详细说明一下。 @marcin 声明负载平衡器“类型”是“应用程序”,但“协议”是 TCP。他在这里引用了两个单独的 CF 模板对象。
创建负载均衡器时,实际上需要在CF模板中定义3个不同的对象。 “负载均衡器”、“负载均衡器侦听器”和“目标组”(负载均衡器将发送流量的位置)。
因此,如果负载均衡器的“类型”是“应用程序”,则关联的“TargetGroup”必须具有“HTTP”或“HTTPS”协议。一种类型的“TCP”会报这个错。
我遇到了同样的问题,但多亏了 cloudformation,一条错误消息总是意味着多件事。在我的情况下,这是负载均衡器上的权限错误。尝试将此权限添加到您的策略中:
Statement:
- Effect: Allow
Action:
- elasticloadbalancing:*
- elasticloadbalancingv2:*
Resource: *
如果这解决了您的问题,您肯定知道这是弹性负载平衡的权限问题。尝试通过逐步降低权限来缩小范围。提示:一些负载平衡权限不是特定于资源的,对于那些你需要 Resource: *
才能对其执行某些操作。来自 AWS docs:
The Resource types column indicates whether each action supports resource-level permissions. If there is no value for this column, you must specify all resources ("*") in the Resource element of your policy statement. If the column includes a resource type, then you can specify an ARN of that type in a statement with that action.
我的 CloudFormation 堆栈创建失败并出现一个非常普遍的错误,我似乎无法弄清楚原因。
我正在使用 ALB 创建单容器 ECS 服务任务。
这是我的堆栈模板:
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
资源 LoadBalancerListener
上的 CloudFormation 堆栈创建失败,状态原因:
Invalid request provided: AWS::ElasticLoadBalancingV2::Listener Validation exception
到目前为止我还没有发现类似的问题,也不知道从哪里可以获得有关问题的更多详细信息。谢谢。
发生这种情况可能是因为您正在使用应用程序负载均衡器:
Type: application
但是,您指定连接协议是 TCP
。这显然是不正确的,因为 ALB 只支持 HTTP 和 HTTPS 协议。对于 TCP,您需要 网络负载平衡器 (NLB)。
虽然上面的答案是 100% 正确的,但我只想为那些 运行 遇到同样问题的人详细说明一下。 @marcin 声明负载平衡器“类型”是“应用程序”,但“协议”是 TCP。他在这里引用了两个单独的 CF 模板对象。
创建负载均衡器时,实际上需要在CF模板中定义3个不同的对象。 “负载均衡器”、“负载均衡器侦听器”和“目标组”(负载均衡器将发送流量的位置)。
因此,如果负载均衡器的“类型”是“应用程序”,则关联的“TargetGroup”必须具有“HTTP”或“HTTPS”协议。一种类型的“TCP”会报这个错。
我遇到了同样的问题,但多亏了 cloudformation,一条错误消息总是意味着多件事。在我的情况下,这是负载均衡器上的权限错误。尝试将此权限添加到您的策略中:
Statement:
- Effect: Allow
Action:
- elasticloadbalancing:*
- elasticloadbalancingv2:*
Resource: *
如果这解决了您的问题,您肯定知道这是弹性负载平衡的权限问题。尝试通过逐步降低权限来缩小范围。提示:一些负载平衡权限不是特定于资源的,对于那些你需要 Resource: *
才能对其执行某些操作。来自 AWS docs:
The Resource types column indicates whether each action supports resource-level permissions. If there is no value for this column, you must specify all resources ("*") in the Resource element of your policy statement. If the column includes a resource type, then you can specify an ARN of that type in a statement with that action.