YAML: 'null' values are not allowed in templates - amazon-web-services

The YAML template below is giving this error message:
[/Resources/ecsTemplate/Properties] 'null' values are not allowed in templates
AWSTemplateFormatVersion: "2010-09-09"
Resources:
ecsTemplate:
Type: AWS::ECS::Service
Properties:
CapacityProviderStrategy:
Base: Integer
CapacityProvider: String
Weight: Integer
Cluster: String
DeploymentConfiguration:
Alarms:
AlarmNames: AWS/ECS
Enable: true
Rollback: true
DeploymentCircuitBreaker:
Enable: true
Rollback: true
MaximumPercent: Integer
MinimumHealthyPercent: Integer
DeploymentController:
Type: String
DesiredCount: 4
EnableECSManagedTags: Boolean
EnableExecuteCommand: Boolean
HealthCheckGracePeriodSeconds: Integer
LaunchType: String
LoadBalancers:
ContainerName: String
ContainerPort: Integer
LoadBalancerName: String
TargetGroupArn: String
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: String
SecurityGroups:
- String
Subnets:
- String
PlacementConstraints:
Expression: String
Type: memberOf
PlacementStrategies:
Field: String
Type: random
PlatformVersion: String
PropagateTags: String
Role: String
SchedulingStrategy: String
ServiceConnectConfiguration:
Enabled: Boolean
LogConfiguration:
LogDriver: String
Options:
Key : Value
SecretOptions:
- Secret
Namespace: String
Services:
ClientAliases:
DnsName: String
Port: 80
DiscoveryName: String
IngressPortOverride: Integer
PortName: 80
ServiceName: String
ServiceRegistries:
- ServiceRegistry
Tags:
- Tag
TaskDefinition: String
Would you know what is causing this error?

Related

AWS Network LoadBalancer listener and the following target groups have incompatible protocols

I have run into an issue trying to setup rtmp on AWS EC2 using CloudFormation. I have two stack's aws.yaml and web.yaml. CF responds with the following error on execution: Internal error reported from downstream service during operation 'The listener and the following target groups have incompatible protocols: [arn:...]. I've tried to specify a protocol directly in the listener but this just results in the error, You cannot specify the protocol version for a target group with the 'TCP_UDP' protocol. Thanks in advance for help!
nlb.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Deploys a single network load balancer
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: ID of the VPC
PublicSubnets:
Type: List<AWS::EC2::Subnet::Id>
Description: List of Public subnets to use for the Load Balancer
CertificateArn:
Type: String
Description: Arn of the ACM certificate to be used by the load balancer listener.
Resources:
PublicNlb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: publicNlb
Scheme: internet-facing
Subnets: !Ref PublicSubnets
Tags:
- Key: Name
Value: wordpress-nlb
Type: network
PublicNlbTargetGroupHttp:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Port: 80
Protocol: TCP
Targets:
- Id: !ImportValue WordPressPublicAlbArn
TargetType: alb
VpcId: !Ref VpcId
PublicNlbTargetGroupHttps:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Port: 443
Protocol: TCP
Targets:
- Id: !ImportValue WordPressPublicAlbArn
TargetType: alb
VpcId: !Ref VpcId
PublicNlbHttpListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref PublicNlbTargetGroupHttp
LoadBalancerArn: !Ref PublicNlb
Port: 80
Protocol: TCP
PublicNlbHttpsListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref PublicNlbTargetGroupHttps
LoadBalancerArn: !Ref PublicNlb
Port: 443
Protocol: TCP
Outputs:
PublicNlbTargetGroupHttpArn:
Value: !Ref PublicNlbTargetGroupHttp
Export:
Name: WordPressPublicNlbTargetGroupHttpArn
PublicNlbTargetGroupHttpsArn:
Value: !Ref PublicNlbTargetGroupHttps
Export:
Name: WordPressPublicNlbTargetGroupHttpsArn
PublicNlbCanonicalHostedZoneId:
Value: !GetAtt PublicNlb.CanonicalHostedZoneID
PublicNlbDnsName:
Value: !GetAtt PublicNlb.DNSName
PublicNlbFullName:
Value: !GetAtt PublicNlb.LoadBalancerFullName
PublicNlbHostname:
Value:
!Sub https://${PublicNlb.DNSName}
# !If [ NoSslCertificate, !Join [ '', [ 'http://', !GetAtt PublicAlb.DNSName ] ], !Join [ '', [ 'https://', !GetAtt PublicAlb.DNSName ] ] ]
PublicNlbHttpsListenerArn:
Value: !Ref PublicNlbHttpsListener
Export:
Name: WordPressPublicNlbHttpsListenerArn
PublicNlbHttpListenerArn:
Value: !Ref PublicNlbHttpListener
Export:
Name: WordPressPublicNlbHttpListenerArn
web.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: Deploys highly available wordpress application
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: ID of the VPC
RecipeVersion:
Type: String
Description: The semantic version number you want to give to the recipe (in Major.Minor.Patch format).
AllowedPattern: ^[0-9]+\.[0-9]+\.[0-9]+$
PrivateSubnets:
Type: List<AWS::EC2::Subnet::Id>
Description: List of Private subnets to use for the application
PrivateSubnetsString:
Type: String
Description: List of Private subnets to use for the application as string
Account:
Type: String
Default: non-prod
AllowedValues:
- prod
- non-prod
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- preprod
- prod
InstanceProfileName:
Type: String
Default: EC2RoleForSSM
Description: The name of the InstanceProfile to be used with the instances.
AmazonLinuxAMI:
Type: AWS::EC2::Image::Id
MinSize:
Type: Number
Description: The minimum limit of allowed instances to be deployed.
Default: 1
MaxSize:
Type: Number
Description: The maximum limit of allowed instances to be deployed.
Default: 8
DesiredCapacity:
Type: Number
Description: The average amount of instances to be deployed.
Default: 1
OnDemandBaseCapacity:
Type: Number
Description: The minimum amount of the Auto Scaling group's capacity that must be fulfilled by On-Demand Instances. For production you should always have at least 1 On-Demand instance (set to 1).
Default: 1
OnDemandPercentageAboveBaseCapacity:
Type: Number
Description: Controls the percentages of On-Demand Instances and Spot Instances for your additional capacity beyond OnDemandBaseCapacity. Expressed as a number (for example, 20 specifies 20% On-Demand Instances, 80% Spot Instances). Defaults to 0 if not specified. If set to 100, only On-Demand Instances are provisioned.
Default: 0
Mappings:
LoadBalancerRulePriority:
dev:
"rule": "3"
preprod:
"rule": "2"
prod:
"rule": "1"
LoadBalancerHosts:
dev:
hostOne: "*.example.*"
preprod:
hostOne: "preprod.example.*"
prod:
hostOne: "*.example.*"
SalingServerProperties:
# #link https://aws.amazon.com/ec2/instance-types/
# #link https://instaguide.io/#sortField=vcpu&sortDir=-1&platform=rhel&tenancyCode=dedicated&priceCalc=abs&period=mo
dev:
instanceTypeOne: "c6gd.xlarge"
preprod:
instanceTypeOne: "c6gd.xlarge"
prod:
instanceTypeOne: "c6gd.xlarge"
Conditions:
IsProd: !Equals [!Ref Environment, prod]
IsPreProd: !Equals [!Ref Environment, preprod]
IsDev: !Equals [!Ref Environment, dev]
Resources:
AlbTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${Environment}-wordpress"
HealthCheckEnabled: true
HealthCheckIntervalSeconds: 10
HealthCheckPath: /
HealthCheckPort: "80"
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 4
UnhealthyThresholdCount: 2
Port: 80
Protocol: HTTP
ProtocolVersion: HTTP1
Tags:
- Key: Name
Value: !Sub "${Environment}-${RecipeVersion}-wordpress"
TargetGroupAttributes:
- Key: stickiness.enabled
Value: "false"
- Key: stickiness.type
Value: lb_cookie # or app_cookie
TargetType: instance
VpcId: !Ref VpcId
AlbListenerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref AlbTargetGroup
Conditions:
- Field: host-header
HostHeaderConfig:
Values:
- dropingaming.*
- !FindInMap [ LoadBalancerHosts, !Ref Environment, hostOne ]
ListenerArn: !ImportValue WordPressPublicAlbHttpsListenerArn
Priority: !FindInMap [ LoadBalancerRulePriority, !Ref Environment, rule ]
NlbTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${Environment}-wordpress-rtmp"
HealthCheckEnabled: true
HealthCheckIntervalSeconds: 30
HealthCheckPort: "4444"
HealthCheckProtocol: HTTP
Port: 1935
Protocol: TCP_UDP
Tags:
- Key: Name
Value: !Sub "${Environment}-${RecipeVersion}-wordpress"
TargetGroupAttributes:
- Key: stickiness.enabled
Value: "true"
TargetType: instance
VpcId: !Ref VpcId
NlbListenerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref NlbTargetGroup
Conditions:
# Configures the rule to apply when the host header matches the domain we want to send to the target group
# https://stackoverflow.com/questions/45664638/how-to-make-a-list-item-conditional-in-cloud-formation-template
- Field: host-header
HostHeaderConfig:
Values:
- dropingaming.*
- !FindInMap [ LoadBalancerHosts, !Ref Environment, hostOne ]
ListenerArn: !ImportValue WordPressPublicAlbHttpsListenerArn
Priority: !FindInMap [ LoadBalancerRulePriority, !Ref Environment, rule ]
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: !Sub "${Environment}-wordpress"
LaunchTemplateData:
ImageId: !Ref AmazonLinuxAMI
EbsOptimized: 'true'
IamInstanceProfile:
Name: EC2RoleForSSM
SecurityGroupIds:
- !ImportValue WordPressEc2SecurityGroupId
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html
# The user data to make available to the instance. You must provide base64-encoded text.
# User data is limited to 16 KB. For more information, see Running Commands on Your Linux Instance at Launch (Linux) or Adding User Data (Windows).
# logging is sent to :: /var/log/cloud-init-output.log
# this script is stored to :: /var/lib/cloud/instance/scripts/part-001
UserData:
Fn::Base64: !Sub
- |
#!/bin/bash -ex
EC2_INSTANCE_ID="`wget -q -O - http://instance-data/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"
test -n "$EC2_INSTANCE_ID" || die 'cannot obtain instance-id'
EC2_AVAIL_ZONE="`wget -q -O - http://instance-data/latest/meta-data/placement/availability-zone || die \"wget availability-zone has failed: $?\"`"
test -n "$EC2_AVAIL_ZONE" || die 'cannot obtain availability-zone'
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9][0-9]*\)[a-z]*\$:\\1:'`"
EC2_PUBLIC_IPV4="`curl http://checkip.amazonaws.com`"
EC2_PRIVATE_IPV4="`curl http://169.254.169.254/latest/meta-data/local-ipv4`"
# https://tldp.org/LDP/abs/html/here-docs.html
sudo cat > '/var/ebs-www-copy/aws.json' <<End-of-message
{
"AmazonLinuxAMI": "${AmazonLinuxAMI}",
"RecipeVersion": "${RecipeVersion}",
"EfsId": "${EfsId}",
"VpcId": "${VpcId}",
"PrivateSubnets": "${PrivateSubnetsString}",
"Account": "${Account}",
"Environment": "${Environment}",
"InstanceProfileName": "${InstanceProfileName}",
"MinSize": "${MinSize}",
"MaxSize": "${MaxSize}",
"DesiredCapacity": "${DesiredCapacity}",
"OnDemandBaseCapacity": "${OnDemandBaseCapacity}",
"OnDemandPercentageAboveBaseCapacity": "${OnDemandPercentageAboveBaseCapacity}",
"EC2_PUBLIC_IPV4": "$EC2_PUBLIC_IPV4",
"EC2_PRIVATE_IPV4": "$EC2_PRIVATE_IPV4",
"EC2_INSTANCE_ID": "$EC2_INSTANCE_ID",
"EC2_AVAIL_ZONE": "$EC2_AVAIL_ZONE",
"EC2_REGION": "$EC2_REGION"
}
End-of-message
cat /var/ebs-www-copy/aws.json
# redacting the overly specific :)
systemctl start httpd
- EfsId: !ImportValue "WordPressEfsId"
# https://github.com/aws-samples/session-manager-without-igw/blob/main/session-manager-without-igw.yml
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub "${Environment}-wordpress"
TargetGroupARNs:
- !Ref AlbTargetGroup
- !Ref NlbTargetGroup
MinSize: !Ref MinSize
MaxSize: !Ref MaxSize
DesiredCapacity: !Ref DesiredCapacity
VPCZoneIdentifier: !Ref PrivateSubnets
MixedInstancesPolicy:
LaunchTemplate:
LaunchTemplateSpecification:
# Version: !Ref LaunchTemplateVersionNumber
Version: !GetAtt
- LaunchTemplate
- LatestVersionNumber
LaunchTemplateId: !Ref LaunchTemplate
# https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-mixed-instances-groups-launch-template-overrides.html
# #link https://aws.amazon.com/ec2/instance-types/
# #link https://instaguide.io/#sortField=vcpu&sortDir=-1&platform=rhel&tenancyCode=dedicated&priceCalc=abs&period=mo
Overrides:
# I want to know if predictive load b is bs or nah
- InstanceType: !FindInMap [SalingServerProperties, !Ref Environment, instanceTypeOne]
InstancesDistribution:
OnDemandBaseCapacity: !Ref OnDemandBaseCapacity
OnDemandPercentageAboveBaseCapacity: !Ref OnDemandPercentageAboveBaseCapacity
# https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-mixed-instances-groups.html#allocation-strategies
SpotAllocationStrategy: lowest-price
OnDemandAllocationStrategy: lowest-price
Tags:
- Key: "Name"
PropagateAtLaunch: true
Value: !Sub "${Environment}-wordpress"
- Key: "Version"
PropagateAtLaunch: true
Value: !Sub "${RecipeVersion}"
AutoScalingPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AutoScalingGroupName: !Ref AutoScalingGroup
PolicyType: PredictiveScaling
PredictiveScalingConfiguration:
MetricSpecifications:
- TargetValue: 70
PredefinedMetricPairSpecification:
PredefinedMetricType: ASGCPUUtilization
So based on the error the NlbListenerRule seems to be what is failing; though, the downstream service bit has me confused. Google return near nothing, so I'm hopeful you may know!?
So AWS support along with the comment above lead me straight to the problem. The NlbListenerRule was using an incorrect ListenerArn: !ImportValue WordPressPublicAlbHttpsListenerArn. Also, another issues which is catchable in the provided templates above was caught by the support team "NLB work on Layer-4 of OSI Model , and we cannot create NLB Listener rule based on Host-Header Condition." Thus ListenerRule's may only be applied to HTTP based hosts.
changed in web.yaml
NlbListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref NlbTargetGroup
LoadBalancerArn: !ImportValue PublicNlbLoadBalancerArn
Port: 1935
Protocol: TCP_UDP
added in alb.yaml
Outputs:
PublicNlb:
Value: !Ref PublicNlb
Export:
Name: PublicNlbLoadBalancerArn
PublicNlbTargetGroupHttpArn:

How can I create aurora cluster db instance in different available zone?

I created a Aurora cluster (postgresql 11) with 3 instances in ap-southeast-2 region (1 writer, 2 reader). I noticed that the writer is in the AZ 2b but two readers are in the same AZ which is 2a. How can I make them evenly spread to 3 AZ?
The cloudformation for this cluster:
AuroraDBFirstInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: ${self:custom.postgresqlInstanceClass}
Engine: aurora-postgresql
EngineVersion: ${self:custom.postgresqlEngineVersion}
DBClusterIdentifier: !Ref AuroraDBCluster
PubliclyAccessible: ${self:custom.publiclyAccessible}
AuroraDBSecondInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: ${self:custom.postgresqlInstanceClass}
Engine: aurora-postgresql
EngineVersion: ${self:custom.postgresqlEngineVersion}
DBClusterIdentifier: !Ref AuroraDBCluster
PubliclyAccessible: ${self:custom.publiclyAccessible}
AuroraDBThirdInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: ${self:custom.postgresqlInstanceClass}
Engine: aurora-postgresql
EngineVersion: ${self:custom.postgresqlEngineVersion}
DBClusterIdentifier: !Ref AuroraDBCluster
PubliclyAccessible: ${self:custom.publiclyAccessible}
You can specify the AZ in cloudformation it self. If you do not specify subnet then Aurora will pick random AZ from subnet group you provide.
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: String
AllowMajorVersionUpgrade: Boolean
AssociatedRoles:
- DBInstanceRole
AutoMinorVersionUpgrade: Boolean
AvailabilityZone: String
BackupRetentionPeriod: Integer
CACertificateIdentifier: String
CharacterSetName: String
CopyTagsToSnapshot: Boolean
DBClusterIdentifier: String
DBInstanceClass: String
DBInstanceIdentifier: String
DBName: String
DBParameterGroupName: String
DBSecurityGroups:
- String
DBSnapshotIdentifier: String
DBSubnetGroupName: String
DeleteAutomatedBackups: Boolean
DeletionProtection: Boolean
Domain: String
DomainIAMRoleName: String
EnableCloudwatchLogsExports:
- String
EnableIAMDatabaseAuthentication: Boolean
EnablePerformanceInsights: Boolean
Engine: String
EngineVersion: String
Iops: Integer
KmsKeyId: String
LicenseModel: String
MasterUsername: String
MasterUserPassword: String
MaxAllocatedStorage: Integer
MonitoringInterval: Integer
MonitoringRoleArn: String
MultiAZ: Boolean
OptionGroupName: String
PerformanceInsightsKMSKeyId: String
PerformanceInsightsRetentionPeriod: Integer
Port: String
PreferredBackupWindow: String
PreferredMaintenanceWindow: String
ProcessorFeatures:
- ProcessorFeature
PromotionTier: Integer
PubliclyAccessible: Boolean
SourceDBInstanceIdentifier: String
SourceRegion: String
StorageEncrypted: Boolean
StorageType: String
Tags:
- Tag
Timezone: String
UseDefaultProcessorFeatures: Boolean
VPCSecurityGroups:
- String
for better info for each properties you can refer to cloudformation template documention. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html
You can control placement of your db instances through DBSubnetGroup and AvailabilityZone.
Below is working example for creating DBSubnetGroup consisting of 3 subnets in 3 different AZs in us-east-1. The only thing you need to do to run this example is to change subnet-ids to your own from us-east-1a, us-east-1b,us-east-1c AZs in MyDBSubnetGroup:
Resources:
MyDBSubnetGroup:
Properties:
DBSubnetGroupDescription: Subent Group in 3 AZs
SubnetIds:
- subnet-82c876e5
- subnet-21ef547d
- subnet-a9e16487
Type: "AWS::RDS::DBSubnetGroup"
RDSCluster:
Properties:
DBSubnetGroupName: !Ref MyDBSubnetGroup
Engine: aurora-postgresql
MasterUserPassword: postgresql22332
MasterUsername: postgresql
Type: "AWS::RDS::DBCluster"
RDSDBInstance1:
Properties:
AvailabilityZone: us-east-1a
DBClusterIdentifier:
Ref: RDSCluster
DBInstanceClass: db.t3.medium
Engine: aurora-postgresql
PubliclyAccessible: "true"
DeleteAutomatedBackups: true
Type: "AWS::RDS::DBInstance"
RDSDBInstance2:
Properties:
AvailabilityZone: us-east-1b
DBClusterIdentifier:
Ref: RDSCluster
DBInstanceClass: db.t3.medium
Engine: aurora-postgresql
PubliclyAccessible: "true"
DeleteAutomatedBackups: true
Type: "AWS::RDS::DBInstance"
RDSDBInstance3:
Properties:
AvailabilityZone: us-east-1c
DBClusterIdentifier:
Ref: RDSCluster
DBInstanceClass: db.t3.medium
Engine: aurora-postgresql
PubliclyAccessible: "true"
DeleteAutomatedBackups: true
Type: "AWS::RDS::DBInstance"

AWS ELB Listener creation fails with Validation exception

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.
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.
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).
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.

Health checks failed with these codes: [502] - Cloudformation

Hi I am using cloudforamtion to create ecs cluster, service and task. In task I am simply pulling wordpress image and connecting it to rds database. The problem here is the instance in the target group goes to draining state and then turn unhealthy. Wordpress shows up in the dns of alb but when you refresh it sometime gives error 502 bad gateway. I am only attaching the template where the error can exist most probably I might be giving the port wrong. I have good connection to the database (I have checked it as I did ssh into the instance and then used mysql -umysqldb -pmysql123a -h rds.endpoint command). The targets in targetgroup shoes an error Health checks failed with these codes: [502]
Task:
---
AWSTemplateFormatVersion: 2010-09-09
Parameters:
ExRole:
Type: String
RDS:
Type: String
Resources:
Task:
Type: AWS::ECS::TaskDefinition
Properties:
Family: wordpress
Cpu: 1 vCPU
ExecutionRoleArn: !Ref ExRole
Memory: 1 GB
NetworkMode: bridge
RequiresCompatibilities:
- EC2
TaskRoleArn: !Ref ExRole
ContainerDefinitions:
- Essential: true
Image: wordpress:latest
Name: wordpress
PortMappings:
- ContainerPort: 80
HostPort: 0
Protocol: tcp
Environment:
- Name: WORDPRESS_DB_HOST
Value: !Ref RDS
- Name: WORDPRESS_DB_USER
Value: mysqldb
- Name: WORDPRESS_DB_PASSWORD
Value: mysql123a
- Name: WORDPRESS_DB_NAME
Value: mysqldb
Outputs:
Task:
Description: Contains all the task specifications
Value: !Ref Task
Export:
Name: "Task"
alb:
---
AWSTemplateFormatVersion: 2010-09-09
Parameters:
SubnetA:
Type: String
SubnetB:
Type: String
VpcID:
Type: String
Resources:
Albsg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: alb-sg
VpcId: !Ref VpcID
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: For traffic from Internet
GroupDescription: Security Group for demo server
Alb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: Alb
Scheme: internet-facing
SecurityGroups:
- !Ref Albsg
Subnets:
- Ref: "SubnetA"
- Ref: "SubnetB"
Type: application
DefaultTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn: Alb
Properties:
Name: alb-tg
VpcId: !Ref VpcID
Port: 80
Protocol: HTTP
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref Alb
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref DefaultTargetGroup
Outputs:
Albsg:
Description: security group for application load balancer
Value: !Ref Albsg
Export:
Name: "Albsg"
Alb:
Description: application load balancer
Value: !Ref Alb
Export:
Name: "Alb"
DefaultTargetGroup:
Description: Default Target Group
Value: !Ref DefaultTargetGroup
Export:
Name: "DefaultTargetGroup"
Cluster and service
---
AWSTemplateFormatVersion: 2010-09-09
Parameters:
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: webserver
DesiredCapacity:
Type: Number
Default: 2
MinSize:
Type: Number
Default: 1
MaxSize:
Type: Number
Default: 4
InstanceProfile:
Type: String
DefaultTargetGroup:
Type: String
Task:
Type: String
Albsg:
Type: String
VpcID:
Type: String
SubnetA:
Type: String
SubnetB:
Type: String
webserver:
Type: String
Resources:
MyCluster:
Type: AWS::ECS::Cluster
Properties: {}
Myservice:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref MyCluster
DeploymentController:
Type: ECS
DesiredCount: 2
LaunchType: EC2
LoadBalancers:
- ContainerName: wordpress
ContainerPort: 80
TargetGroupArn: !Ref DefaultTargetGroup
#Role: !Ref InstanceProfile
SchedulingStrategy: REPLICA
ServiceName: wordpress
TaskDefinition: !Ref Task
ec2instance:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
yum update -y && yum install -y aws-cfn-bootstrap
echo ECS_CLUSTER=${MyCluster} >> /etc/ecs/ecs.config
echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config
/opt/aws/bin/cfn-signal -e $? \
--stack ${AWS::StackName} \
--resource myASG \
--region ${AWS::Region}
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
DeleteOnTermination: "true"
VolumeSize: 30
VolumeType: gp2
ImageId: ami-06e05a843071324d1
InstanceType: t2.small
IamInstanceProfile: !Ref InstanceProfile
KeyName: !Ref KeyName
SecurityGroups:
- Ref: webserver
myASG:
Type: AWS::AutoScaling::AutoScalingGroup
CreationPolicy:
ResourceSignal:
Timeout: PT5M
Count: !Ref DesiredCapacity
Properties:
#AutoScalingGroupName: myASG
MinSize: !Ref MinSize
MaxSize: !Ref MaxSize
DesiredCapacity: !Ref DesiredCapacity
HealthCheckGracePeriod: 300
LaunchConfigurationName:
Ref: ec2instance
VPCZoneIdentifier:
- !Ref SubnetA
- !Ref SubnetB
TargetGroupARNs:
- !Ref DefaultTargetGroup
most probably I might be giving the port wrong
In your Type: AWS::ECS::TaskDefinition you have defined port 80 for the wordpress.
But your target group is using port 8080:
Properties:
Name: alb-tg
VpcId: !Ref VpcID
Port: 8080 # <--- should be 80
Protocol: HTTP
To use 302 code for health checks:
DefaultTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn: Alb
Properties:
Name: alb-tg
VpcId: !Ref VpcID
Port: 80
Protocol: HTTP
Matcher:
HttpCode: 302

Error: Value of property LoadBalancerAttributes must be of type List

Error: Value of property LoadBalancerAttributes must be of type List
I followed cloud formation documentation and set the Attributes but still I am getting error
Can anyone know the issue and where I went wrong?
how can fix the template
Resources:
IAPILoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref IAPIBlueTargetGroup
Type: forward
LoadBalancerArn: !Ref IAPILoadBalancer
Port: !Ref LoadBalancerPort
Protocol: TCP
IAPILoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
LoadBalancerAttributes:
access_logs.s3.bucket: xxxxxxxx
access_logs.s3.prefix: xxxxxxxx
access_logs.s3.enabled: false
deletion_protection.enabled: fasle
Name: NLB
Scheme: internal
Subnets:
- !Ref PrivateRailA
- !Ref PrivateRailB
Type: network
Tags:
- Key: "platform_name"
Value: "nx"```
LoadBalancerAttributes should have different form.
Please have a look at the following:
LoadBalancerAttributes:
- Key: access_logs.s3.bucket
Value: xxxxxxxx
- Key: access_logs.s3.prefix
Value: xxxx
- Key: access_logs.s3.enabled
Value: false
- Key: deletion_protection.enabled
Value: false