Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The target group does not have an associated load balancer

I want to create ECS service from Cloud Formation Script. The service needs to be exposed to outside with Application Load Balancer

I have created Elastic Load Balancer, a Listener and ListnerRule

 Resources:
  Vpc:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 0e3933ae-23c2-44e1-a0d9-82fcfba93511
  PubSubnetAz1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: 'ap-southeast-1a'
      MapPublicIpOnLaunch: true
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 6c7ca021-4114-4ec8-acf8-4f103ff7011f
  PubSubnetAz2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: 'ap-southeast-1b'
      MapPublicIpOnLaunch: true
    Metadata:
      'AWS::CloudFormation::Designer':
        id: cfe07e5c-e00f-4918-b877-f567fa08c802
  InternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 46bddd21-3027-4ccb-9e5d-ebf887429453
  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref Vpc
      InternetGatewayId: !Ref InternetGateway
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 11b7e802-d5ba-437a-8695-4bd5406d4db7
  RouteViaIgw:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref Vpc
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 1a2f2b53-09d3-4c2c-8286-295870b8c602
  PublicRouteViaIgw:
    Type: 'AWS::EC2::Route'
    DependsOn:
      - AttachGateway
    Properties:
      RouteTableId: !Ref RouteViaIgw
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 4b7c941a-8498-4e70-886b-9339018cc18a
  PubSubnet1RouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PubSubnetAz1
      RouteTableId: !Ref RouteViaIgw
    Metadata:
      'AWS::CloudFormation::Designer':
        id: cea0d60a-6d91-4922-90ea-f6db9f4378a9


  PubSubnet2RouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PubSubnetAz2
      RouteTableId: !Ref RouteViaIgw
    Metadata:
      'AWS::CloudFormation::Designer':
        id: c3b3c8e1-a9c8-47c6-8d26-b6f272bcd9e1

  EcsSecurityGroup:
    Condition: CreateNewSecurityGroup
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: ECS Allowed Ports
      SecurityGroupIngress:
        IpProtocol: tcp
        FromPort: 30
        ToPort: 150
        CidrIp: 0.0.0.0/0
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 493fdb30-54ce-4e4e-9cd6-c9faa6e3f93b

  LoadBalancerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref Vpc
      GroupDescription: Access to the load balancer that sits in front of ECS
      SecurityGroupIngress:
        # Allow access from anywhere to our ECS services
        - CidrIp: 0.0.0.0/0
          IpProtocol: -1


  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: 'my-cluster'

  EcsInstanceAsg:
    DependsOn: ECSCluster
    Type: 'AWS::AutoScaling::AutoScalingGroup'
    Properties:
      LaunchConfigurationName: !Ref EcsInstanceLc
      AvailabilityZones:
        - ap-southeast-1a
        - ap-southeast-1b
      MinSize: '2'
      MaxSize: '3'
      DesiredCapacity: '2'

      Tags:
        - Key: Name
          Value: !Sub 'ECS Instance stack'
          PropagateAtLaunch: 'true'
        - Key: Description
          Value: >-
            This instance is the part of the Auto Scaling group which was
            created through ECS Console
          PropagateAtLaunch: 'true'
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 80731e0b-a9e5-461c-9049-e215aed2ad3d

  EcsInstanceLc:
      # DependsOn
      Type: 'AWS::AutoScaling::LaunchConfiguration'
      Properties:
        ImageId: 'ami-050865a806e0dae53'
        InstanceType: 't2.large'
        # AssociatePublicIpAddress: false
        SecurityGroups:
          - !Ref EcsSecurityGroup

      Metadata:
        'AWS::CloudFormation::Designer':
          id: 0e8e3b5a-7b14-4ffc-92af-ef9be7e51689

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: 'my-load-balancer'
      Subnets:
        - !Ref PubSubnetAz1
        - !Ref PubSubnetAz2
      Listeners:
        InstancePort: 80
        InstanceProtocol: HTTP
        LoadBalancerPort: 80
        Protocol: HTTP
      HealthCheck:
        HealthyThreshold: '10'
        Interval: '5'
        Target: '10'
        Timeout: '15'
        UnhealthyThreshold: '20'
      SecurityGroups: !Ref LoadBalancerSecurityGroup  



      Tags:
        - Key: Name
          Value: !Ref EcsClusterNam

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      VpcId: !Ref Vpc
      Port: 80
      Protocol: HTTP
      HealthCheckIntervalSeconds: 10
      HealthCheckPort: 80
      HealthCheckPath: '/actuator/health'
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 3
      TargetType: instance
      Matcher:
        HttpCode: '200'

  Listener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - Type: forward
        TargetGroupArn: !Ref TargetGroup
      LoadBalancerArn: !Ref LoadBalancer
      Port: '80'
      Protocol: HTTP


  ListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
       - Type: forward
      TargetGroupArn: !Ref TargetGroup
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: tcp
      Priority: 1
      Conditions:
      - Field: path-pattern
        Values: "/*"
      ListenerArn: !Ref Listener

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: 'product-service'
      Cpu: '256'
      Memory: '512'
      NetworkMode: bridge
      RequiresCompatibilities:
        - EC2
      ExecutionRoleArn: 'ecserviceRole'
      ContainerDefinitions:
        - Name: 'product-service'
          Cpu: '128'
          Memory: '256'
          Image: 'ccmcwolf/microservices:awstest'
          PortMappings:
            - HostPort: '80'
              ContainerPort: '80'
              Protocol: 'tcp'

          # LogConfiguration:
          #   LogDriver: awslogs
          #   Options:
          #     awslogs-group: !Ref CloudWatchLogsGroup
          #     awslogs-region: !Ref AWS::Region


  Service:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref ECSCluster
      Role: 'ecserviceRole'
      DesiredCount: '2'
      TaskDefinition: !Ref TaskDefinition
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerPort: 80
          ContainerName: "product-service"

but when I run the script in Cloudformation it throws an error

The target group with targetGroupArn arn:aws:elasticloadbalancing:ap-southeast-1:xxxxxxxxxxxx:targetgroup/iy6-TargetG-A6FWY20V6B6P/7e5d12f4cb4758a1 does not have an associated load balancer

. Entire AWS Cloud formation script available at https://notepad.pw/ecsaws

like image 229
mmc Avatar asked Dec 29 '18 17:12

mmc


People also ask

How do I associate a target group with a load balancer?

In the navigation pane, under Load Balancing, choose Target Groups. Choose Create target group. For Choose a target type, select Instances to register targets by instance ID; IP addresses to register targets by IP address; or Application Load Balancer to register an Application Load Balancer as a target.

What is target group in load balancer?

A target group tells a load balancer where to direct traffic to : EC2 instances, fixed IP addresses; or AWS Lambda functions, amongst others. When creating a load balancer, you create one or more listeners and configure listener rules to direct the traffic to one target group.

Can a target group be attached to multiple load balancers?

Now, you can attach multiple target groups per ECS service. This allows you to maintain a single ECS service that can serve traffic from both internal and external load balancers and support multiple path based routing rules and applications that need to expose more than one port.

Can I associate target groups created in different VPCS?

You can't do this. You can only add targets from different regions, but not target groups.


2 Answers

This case is now covered on the examples section of AWS::ECS::Service CloudFormation page, under "Associate an Application Load Balancer with a service".

The Amazon ECS service requires an explicit dependency on the Application Load Balancer listener rule and the Application Load Balancer listener. This prevents the service from starting before the listener is ready.

The ultimate issue that you have is due to AWS::ECS::Service trying to attach to the target group before the target group is added to the load balancer. The fix for that is very easy:

 Service:
    Type: AWS::ECS::Service
    DependsOn: Listener       # Line Added
    Properties:
      Cluster: !Ref ECSCluster
      Role: 'ecserviceRole'
      DesiredCount: '2'
      TaskDefinition: !Ref TaskDefinition
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerPort: 80
          ContainerName: "product-service"

With that being said, you will also have to update your LoadBalancer definition because it has a lot of errors. It should be:

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: 'my-load-balancer'
      Subnets:
        - !Ref PubSubnetAz1
        - !Ref PubSubnetAz2
      SecurityGroups: 
        - !Ref LoadBalancerSecurityGroup 
like image 67
tyron Avatar answered Oct 14 '22 00:10

tyron


Add DependsOn not just Listener but also the ListenerRule like so:

ECSService:
  Type: AWS::ECS::Service
  DependsOn:
    - ListenerHTTPS
    - ListenerRule
like image 6
Red Bottle Avatar answered Oct 14 '22 00:10

Red Bottle