Error: TargetGroup cannot be associated with more than one load balancer

1

When a TargetGroup, LoadBalancer, and Listener are setup, if an update triggers a replace of the LoadBalancer the stack can't be updated. Below is an example stack. After creating it the first time, update it and change the ELBScheme parameter. Doing this results in the error:

Target group 'arn:aws:elasticloadbalancing:...' cannot be associated with more than one load balancer

My understanding of the problem is that when the load balancer gets replaced, this causes the Listener to also be replaced. But when the listener is replaced, it now tries to connect to the existing TargetGroup. And this causes the problem.

If the TargetGroup cannot be associated with more than one load balancer, then the TargetGroup should have an explicit reference to the load balancer in CloudFormation, and then the TargetGroup can be replaced when the load balancer is replaced. Or perhaps I'm missing something here.

I'm going to experiment with some hacky solutions around this and will report back.

AWSTemplateFormatVersion: '2010-09-09'
Description: Test of an issue with CloudFormation TargetGroups
Parameters:
  ELBScheme:
    Type: String
    Default: internet-facing
    AllowedValues: [ 'internet-facing', 'internal']
  Subnet1:
    Type: AWS::EC2::Subnet::Id
  Subnet2:
    Type: AWS::EC2::Subnet::Id
  VPC:
    Type: AWS::EC2::VPC::Id
Resources:
  ELBv2:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Subnets:
      - !Ref Subnet1
      - !Ref Subnet2
      Scheme: !Ref ELBScheme
  ELBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Port: '80'
      Protocol: HTTP
      VpcId: !Ref VPC
  ELBListener80:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - TargetGroupArn: !Ref 'ELBTargetGroup'
        Type: forward
      LoadBalancerArn: !Ref 'ELBv2'
      Port: '80'
      Protocol: HTTP
asked 7 years ago7418 views
3 Answers
1

The following template fixes this issue. It uses the Name property of the TargetGroup resource. Whenever the Name property changes the TargetGroup needs to be recreated. So this template uses the unique identifier part of the load balancer name and adds a prefix to it. The TG1 prefix is there incase you have multiple target groups connected to this same load balancer. Each of these groups should use a different prefix so the Names don't conflict.

AWSTemplateFormatVersion: '2010-09-09'
Description: Test of an issue with CloudFormation TargetGroups
Parameters:
  ELBScheme:
    Type: String
    Default: internet-facing
    AllowedValues: [ 'internet-facing', 'internal']
  Subnet1:
    Type: AWS::EC2::Subnet::Id
  Subnet2:
    Type: AWS::EC2::Subnet::Id
  VPC:
    Type: AWS::EC2::VPC::Id
Resources:
  ELBv2:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Subnets:
      - !Ref Subnet1
      - !Ref Subnet2
      Scheme: !Ref ELBScheme
  ELBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Join
      - '-'
      - - 'TG1'
        - !Select [ 2, !Split [ '-', !GetAtt ELBv2.LoadBalancerName]]
      Port: '80'
      Protocol: HTTP
      VpcId: !Ref VPC
  ELBListener80:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - TargetGroupArn: !Ref 'ELBTargetGroup'
        Type: forward
      LoadBalancerArn: !Ref 'ELBv2'
      Port: '80'
      Protocol: HTTP
answered 7 years ago
0

Thanks! This helped immensely. In the end I just named my target group the same as my loadbalancer and that was enough to draw a dependency between em.

answered 7 years ago
0

Quick update:

  • CloudFormation uses the first 6 characters of the stack name, followed by "-ELBv2-RandomString" as the name for AWS::ElasticLoadBalancingV2::LoadBalancer resource.
  • If the CFN stack name contains '-' delimited string, such as 'abc-def', make sure to adjust what element gets used accordingly, for the TG name in the section "- !Select [ 2, !Split [ '-', !GetAtt ELBv2.LoadBalancerName]]".
  • As it needs to include the 'RandomString' section, as that is what triggers the 'AWS::ElasticLoadBalancingV2::TargetGroup' resource replacement and avoid a conflict that way.
AWS
answered 5 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions