Search code examples
amazon-web-servicesaws-cloudformationtargetamazon-elb

No associated load balancer when creating TargetGroup in AWS CloudFormation


The creation of the target group fails because it is not associated with a LoadBalancer. But I'm passing it explicitly using parameters... Could it be a policy issue?

AWSTemplateFormatVersion: 2010-09-09
Description: CF template for Service.

Parameters:
    ClusterArn:
        Type: String
        Description: The Cluster ARN in which to launch the service.
    VPCId:
        Type: AWS::EC2::VPC::Id
        Description: The VPC Id in which the service will be launched.
    FrontEndALBHTTPListenerArn:
        Type: String
        Description: The listener Arn for the back-end service type.
    ALBHostedZoneId:
        Type: String
        Description: The HZ to add the DNS Record.
    LoadBalancerDNSName:
        Type: String
        Description: Load balancer DNS Name.

Resources:
    CustomerHTTPListerRule:
        Type: AWS::ElasticLoadBalancingV2::ListenerRule
        Properties:
            Actions:
                - Type: forward
                  TargetGroupArn:
                    !Ref FrontEndBackEndHTTPTargetGroup
            Conditions:
                - Field: host-header
                  Values:
                      - customer.services.company.com
            Priority: 5
            ListenerArn: !Ref FrontEndALBHTTPListenerArn
# Task Definition
    FrontEndTaskDefinition:
        Type: AWS::ECS::TaskDefinition
        Properties:
            NetworkMode: bridge
            Family: front-end
            ContainerDefinitions:
                -
                  Name: front-end
                  Image: 'xxx.xxx.ecr.xxx.amazonaws.com/frontend'
                  Memory: 128
                  PortMappings:
                    -
                      ContainerPort: 80
                      HostPort: 0
                  Essential: true
                  Environment:
                    - Name: ENVIRONMENT
                      Value: test
# Service Definition
    FrontEndServiceDefinition:
        Type: AWS::ECS::Service
        Properties:
            Cluster: !Ref ClusterArn
            DeploymentConfiguration:
                MinimumHealthyPercent: 50
                MaximumPercent: 200
            DesiredCount: 1
            HealthCheckGracePeriodSeconds: 30
            LaunchType: EC2
            TaskDefinition: !Ref FrontEndTaskDefinition
            ServiceName: Customer
            PlacementStrategies:
                - Type: spread
                  Field: instanceId
            LoadBalancers:
                -
                  ContainerName: front-end
                  ContainerPort: 80
                  TargetGroupArn: !Ref FrontendHTTPTargetGroup
        DependsOn: FrontendHTTPTargetGroup

# front-end Target Group
    FrontendBackEndHTTPTargetGroup:
        Type: AWS::ElasticLoadBalancingV2::TargetGroup
        Properties:
            HealthCheckIntervalSeconds: 5
            HealthCheckPath: '/health'
            HealthCheckProtocol: HTTP
            HealthCheckTimeoutSeconds: 3
            HealthyThresholdCount: 3
            UnhealthyThresholdCount: 2
            Matcher:
                HttpCode: 200
            Name: front-end
            Port: 80
            Protocol: HTTP
            Tags:
                - Key: Name
                  Value: front-end
            TargetGroupAttributes:
                - Key: deregistration_delay.timeout_seconds
                  Value: 10
            TargetType: instance
            VpcId: !Ref VPCId

Here is the policy attached to the Stack:

 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": 
                "ec2:DescribeInstances",
                "ec2:DescribeAddresses",
                "ec2:DescribeRegions",
                "ec2:DescribeSnapshots",
                "ecs:DescribeTaskDefinition",
                "ecs:DeregisterTaskDefinition",
                "ecs:CreateService",
                "ec2:DescribeVolumeStatus",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeNetworkInterfaceAttribute",
                "ecs:RegisterTaskDefinition",
                "ec2:DescribeVolumes",
                "ecs:DescribeServices",
                "ec2:DescribeNetworkInterfacePermissions",
                "ec2:DescribeKeyPairs",
                "ec2:DescribeNetworkAcls",
                "ec2:DescribeRouteTables",
                "ec2:DescribeCustomerGateways",
                "ec2:DescribeVpcEndpointConnectionNotifications",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeVpcs",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpc*",
                "route53:ListHostedZones",
                "route53:ChangeResourceRecordSets",
                "route53:ListResourceRecordSets",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:CreateListener",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:CreateRule",
                "elasticloadbalancing:DeleteRule",
                "elasticloadbalancing:ModifyTargetGroupAttributes",
                "elasticloadbalancing:CreateTargetGroup",
                "elasticloadbalancing:ModifyTargetGroup",
                "elasticloadbalancing:ModifyRule",
                "elasticloadbalancing:AddTags",
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeRules",
                "elasticloadbalancing:DescribeLoadBalancerAttributes",
                "elasticloadbalancing:DeleteTargetGroup",
                "elasticloadbalancing:DescribeTargetGroupAttributes"
                "elasticloadbalancing:DeregisterTargets",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:ModifyListener"
            ],
            "Resource": "*"
        }
    ]
}

With full admin rights, it creates the stack without any problem.

Am I missing a policy, dependsOn?

This can be related Creating an ALB Target Group in CloudFormation but I do not define the ALB in this stack.


Solution

  • The issue was a race condition between Listener and Service creation: the Service was created while the Listener was still in progress or has just been created. Adding a dependson instruction on the Service resolved the issue.