Search code examples
aws-cloudformationamazon-elbamazon-ecs

AWS ECS service and ELBv2 in separate stacks


It is possible to have a CF stack for an ECS service (e.g. blue/green) and separate stack for the front ELBv2? I've tried having the ELB TargetGroup in the ECS stack and the load balancer and listener in another stack, but the Cloud Formation reports and error when building the target group

"The target group with targetGroupArn xxxxxx does not have an associated load balancer."

Yet there is nothing in the target group resource that defines any load balancer for it to depend on:

 ELB2TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 60
      UnhealthyThresholdCount: 10
      HealthCheckPath: /
      Port:     !Ref ALBPort
      Protocol: !Ref ALBProtocol
      VpcId:
        Fn::ImportValue: !Sub "${ECSClusterStack}-ClusterVPC"

Solution

  • I hope you have resolved this issue already. But, just in case someone else comes here looking for the same issue.

    Essentially, you have done nothing wrong. Just that, you need a Listener Rule to associate the Target Group with the Load Balancer Listener.

    Here's an example TargetGroup resource:

    ...
    ExampleTG:
      Type: AWS::ElasticLoadBalancingV2::TargetGroup
      Properties:
        HealthCheckIntervalSeconds: 30
        HealthCheckProtocol: HTTP
        HealthCheckTimeoutSeconds: 5
        HealthyThresholdCount: 2
        HealthCheckPath: /healthcheck
        HealthCheckPort: 80
        Matcher:
          HttpCode: '200'
        Name: !Join [ "-", [ Example, !Ref SomeParameter] ]
        Port: 80
        Protocol: HTTP
        TargetGroupAttributes:
        - Key: deregistration_delay.timeout_seconds
          Value: '15'
        UnhealthyThresholdCount: 3
        VpcId:
          'Fn::ImportValue': !Sub '${ParentVPCStack}-vpc'
    

    I think you had that already. All you need now is a ListernerRule:

    ...
    ExampleListernerRule:
      Type: AWS::ElasticLoadBalancingV2::ListenerRule
      Properties:
        Actions:
          - Type: forward
            TargetGroupArn: !Ref ExampleTG
        Conditions:
          - Field: host-header
            Values:
            - "example.*"
        ListenerArn:
          'Fn::ImportValue': !Sub '${ParentLBStack}-existing-listener'
        Priority: 1
    

    You can easily import the listener from an existing stack [ELBv2 in your case], which associates the Load Balancer with the Target Group.