Reputation: 203
My CloudFormation stack creation fails with a very generic error and I can't seem to figure out why.
I'm creating a single-container ECS service task with ALB.
Here's my stack template:
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 stack creation fails on resource LoadBalancerListener
with status reason:
Invalid request provided: AWS::ElasticLoadBalancingV2::Listener Validation exception
I've found no similar issue so far and don't know where to get more details about what's wrong. Thank you.
Upvotes: 4
Views: 5862
Reputation: 1034
I had the same problem, but thanks to cloudformation, one error message can always mean multiple things.. In my case it was a permission error on the load balancer. Try to add this permission to your policy:
Statement:
- Effect: Allow
Action:
- elasticloadbalancing:*
- elasticloadbalancingv2:*
Resource: *
If this fixes your problem, you know for sure it is a permission issue on elastic load balancing. Try to narrow it down by reducing permissions step by step. Hint: some loadbalancing permissions are NOT resource specific, for those you'll need the Resource: *
to execute certain actions on it. From the 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.
Upvotes: 1
Reputation: 61
While the answer above is 100% correct, I just want to elaborate a bit more for those who are running into this same issue. @marcin states that the load balancer "type" is "application", but the "protocol" is TCP. He is referencing two separate CF template objects here.
When creating a load balancer, you actually need to define 3 different objects in the CF template. A "load balancer", a "load balancer listener" and a "target group" (the place the load balancer will be sending traffic).
So, if a load balancer's "type" is "application" the associated "TargetGroup" must have a protocol of either "HTTP", or "HTTPS". A type of "TCP" will give this error.
Upvotes: 6
Reputation: 238051
This happens probably because you are using application load balancer:
Type: application
However, you specify that your connection protocol is TCP
. This is obviously incorrect, as ALB only supports HTTP and HTTPS protocols. For TCP you need network load balancer (NLB).
Upvotes: 0