Skip to content

Conversation

puretension
Copy link
Contributor

@puretension puretension commented Sep 16, 2025

fix(ecs-patterns): resolve target group conflict when switching ALB public/private

Fixes #33253

Issue # (if applicable)

Closes #33253.

Reason for this change

When switching ApplicationLoadBalancedFargateService from public to private (or vice versa), CloudFormation fails with "target group cannot be associated with more than one load balancer" error. This happens because both old and new load balancers try to use the same target group during replacement.

Updating the loadBalancerName of ApplicationLoadBalancedFargateService can also trigger the same issue.

Description of changes

Modified target group naming in ApplicationLoadBalancedServiceBase to include the load balancer type and name. e.g:

  • Public load balancer: target group named "ECS"
  • Private load balancer: target group named "ECSPrivate"
  • Private load balancer with name "Foo": target group named "ECSFooPrivate"

This ensures each load balancer gets its own target group, preventing conflicts during CloudFormation updates.

⚠️ Destructive Changes

This PR contains intentional destructive changes to fix the target group conflict issue:

Breaking Change: ❌ No - This only affects the internal target group naming, not user-facing APIs.

Describe any new or updated permissions being added

No new IAM permissions required.

Description of how you validated changes

  • Added unit tests verifying target group names for both public and private configurations
  • Created integration test integ.alb-fargate-service-public-private-switch.ts that deploys both public and private ALB services
  • Verified CloudFormation templates generate different target group names

Checklist

@github-actions github-actions bot added the beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK label Sep 16, 2025
@aws-cdk-automation aws-cdk-automation requested a review from a team September 16, 2025 15:53
@github-actions github-actions bot added bug This issue is a bug. effort/medium Medium work item – several days of effort p1 labels Sep 16, 2025
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review is outdated)

@aws-cdk-automation aws-cdk-automation dismissed their stale review September 16, 2025 16:00

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@Abogical Abogical self-assigned this Oct 10, 2025
Copy link
Member

@Abogical Abogical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @puretension, Thank you for your contribution!

As this PR has breaking (destructive) changes, a feature flag will be needed here. See this guide which will help you add a new feature flag for this PR. This fix will then only take effect when the feature flag is set.

Also, see my comment on setting the ID below.

@mergify mergify bot dismissed Abogical’s stale review October 10, 2025 12:28

Pull request has been modified.

Copy link
Member

@Abogical Abogical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the quick edit!

Following steps 4-6 in the feature flag guide, the following is needed:

  1. Add an entry for your feature flag in the README file.

  2. In your tests, ensure that you test your feature with and without the feature flag enabled. You can do this by passing the feature flag to the context property when instantiating an App.

    const myFeatureFlag = { [cxapi.MY_FEATURE_FLAG]: true };
    const app = new App({
       context: myFeatureFlag,
    }),
    const stackUnderTest = new Stack(app);
  3. In your PR title (which goes into CHANGELOG), add a (under feature flag) suffix. e.g:

    fix(core): impossible to use the same physical stack name for two stacks (under feature flag)
    context: myFeatureFlag,
    }),
    const stackUnderTest = new Stack(app);
    In your PR title (which goes into CHANGELOG), add a (under feature flag) suffix. e.g:

fix(core): impossible to use the same physical stack name for two stacks (under feature flag)

@puretension puretension changed the title fix(ecs-patterns): resolve target group conflict when switching ALB public/private fix(ecs-patterns): resolve target group conflict when switching ALB public/private (under feature flag) Oct 10, 2025
@mergify mergify bot dismissed Abogical’s stale review October 10, 2025 14:05

Pull request has been modified.

@puretension
Copy link
Contributor Author

Thank you for the really quick feedback! I've completed missed steps 4-6.

I added the feature flag documentation to the README, implemented tests for both enabled and disabled scenarios following
your specified pattern, and the PR title already includes the "(under feature flag)" suffix. I really appreciate your
detailed guidance as this is my first CDK contribution.

All changes have been committed and pushed. Please let me know if there's anything else needed!

README.md Outdated
When enabled, ECS patterns will generate unique target group IDs that include the load balancer name and type (public/private). This prevents CloudFormation conflicts when switching between public and private load balancers.

Without this flag, switching an ApplicationLoadBalancedFargateService from public to private (or vice versa) fails with "target group cannot be associated with more than one load balancer" error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the wrong README file to edit. The README file to edit is at packages/aws-cdk-lib/cx-api/README.md

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Abogical Thank you for the correction!
I apologize for the basic mistake of editing the wrong README file.😅
I've now moved the feature flag documentation from the root README.md to the correct location at packages/aws-cdk-lib/cx-api/README.md as requested.

I'll be more careful to follow the documentation guidelines precisely in future contributions.
Thank you for your patience and guidance!

@mergify mergify bot dismissed Abogical’s stale review October 13, 2025 08:55

Pull request has been modified.

Copy link
Member

@Abogical Abogical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration test snapshot needs to be updated:

CHANGED    aws-elasticloadbalancingv2-targets/test/integ.alb-target 3.735s
@aws-cdk-testing/framework-integ:       Resources
@aws-cdk-testing/framework-integ:       [-] AWS::ElasticLoadBalancingV2::TargetGroup ServiceLBPublicListenerECSGroup0CC8688C destroy
@aws-cdk-testing/framework-integ:       [+] AWS::ElasticLoadBalancingV2::TargetGroup ServiceLBPublicListenerECSPrivateGroup93D5832E
@aws-cdk-testing/framework-integ:       [~] AWS::ElasticLoadBalancingV2::Listener ServiceLBPublicListener46709EAA
@aws-cdk-testing/framework-integ:        └─ [~] DefaultActions
@aws-cdk-testing/framework-integ:            └─ @@ -1,7 +1,7 @@
@aws-cdk-testing/framework-integ:               [ ] [
@aws-cdk-testing/framework-integ:               [ ]   {
@aws-cdk-testing/framework-integ:               [ ]     "TargetGroupArn": {
@aws-cdk-testing/framework-integ:               [-]       "Ref": "ServiceLBPublicListenerECSGroup0CC8688C"
@aws-cdk-testing/framework-integ:               [+]       "Ref": "ServiceLBPublicListenerECSPrivateGroup93D5832E"
@aws-cdk-testing/framework-integ:               [ ]     },
@aws-cdk-testing/framework-integ:               [ ]     "Type": "forward"
@aws-cdk-testing/framework-integ:               [ ]   }
@aws-cdk-testing/framework-integ:       [~] AWS::ECS::Service Service9571FDD8
@aws-cdk-testing/framework-integ:        ├─ [~] LoadBalancers
@aws-cdk-testing/framework-integ:        │   └─ @@ -3,7 +3,7 @@
@aws-cdk-testing/framework-integ:        │      [ ]     "ContainerName": "nginx",
@aws-cdk-testing/framework-integ:        │      [ ]     "ContainerPort": 80,
@aws-cdk-testing/framework-integ:        │      [ ]     "TargetGroupArn": {
@aws-cdk-testing/framework-integ:        │      [-]       "Ref": "ServiceLBPublicListenerECSGroup0CC8688C"
@aws-cdk-testing/framework-integ:        │      [+]       "Ref": "ServiceLBPublicListenerECSPrivateGroup93D5832E"
@aws-cdk-testing/framework-integ:        │      [ ]     }
@aws-cdk-testing/framework-integ:        │      [ ]   }
@aws-cdk-testing/framework-integ:        │      [ ] ]
@aws-cdk-testing/framework-integ:        └─ [~] DependsOn
@aws-cdk-testing/framework-integ:            └─ @@ -1,5 +1,5 @@
@aws-cdk-testing/framework-integ:               [ ] [
@aws-cdk-testing/framework-integ:               [ ]   "ServiceLBPublicListener46709EAA",
@aws-cdk-testing/framework-integ:               [-]   "ServiceLBPublicListenerECSGroup0CC8688C",
@aws-cdk-testing/framework-integ:               [+]   "ServiceLBPublicListenerECSPrivateGroup93D5832E",
@aws-cdk-testing/framework-integ:               [ ]   "TaskTaskRoleE98524A1"
@aws-cdk-testing/framework-integ:               [ ] ]
@aws-cdk-testing/framework-integ:       [~] AWS::ElasticLoadBalancingV2::TargetGroup NlblistenerTargetsGroupDD2A3CB0
@aws-cdk-testing/framework-integ:        └─ [~] DependsOn
@aws-cdk-testing/framework-integ:            └─ @@ -1,4 +1,4 @@
@aws-cdk-testing/framework-integ:               [ ] [
@aws-cdk-testing/framework-integ:               [ ]   "ServiceLBPublicListener46709EAA",
@aws-cdk-testing/framework-integ:               [-]   "ServiceLBPublicListenerECSGroup0CC8688C"
@aws-cdk-testing/framework-integ:               [+]   "ServiceLBPublicListenerECSPrivateGroup93D5832E"
@aws-cdk-testing/framework-integ:               [ ] ]

Copy link
Member

@Abogical Abogical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yet another snapshot to be updated. Unfortunately, there can be a lot of snapshots to update especially modifying this package:

CHANGED    aws-ecs-patterns/test/fargate/integ.alb-fargate-service-public-private-switch

@mergify mergify bot dismissed Abogical’s stale review October 13, 2025 13:33

Pull request has been modified.

Copy link
Contributor

mergify bot commented Oct 15, 2025

This pull request has been removed from the queue for the following reason: pull request branch update failed.

The pull request can't be updated.

You should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again.
If you think this was a flaky issue, you can requeue the pull request, without updating it, by posting a @mergifyio requeue comment.

@mergify mergify bot removed the queued label Oct 15, 2025
Copy link
Contributor

mergify bot commented Oct 15, 2025

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@Abogical
Copy link
Member

@Mergifyio update

Copy link
Contributor

mergify bot commented Oct 15, 2025

update

❌ Mergify doesn't have permission to update

For security reasons, Mergify can't update this pull request. Try updating locally.
GitHub response: refusing to allow a GitHub App to create or update workflow .github/workflows/codeql.yml without workflows permission

@Abogical
Copy link
Member

@Mergifyio rebase

Copy link
Contributor

mergify bot commented Oct 15, 2025

rebase

✅ Branch has been successfully rebased

@Abogical Abogical force-pushed the fix/ecs-patterns-public-private-targetgroup-33253 branch from 9b7336d to e46ee93 Compare October 15, 2025 08:30
@puretension
Copy link
Contributor Author

@Abogical Thank you so much for your patience, guidance, and approval throughout this entire contribution process! 🙏

The previous CI Codebuild PR Build failure was likely due to the branch being out of sync🤔.
The rebase should have resolved the ESLint issues that were blocking the merge.

Should I change something more for safely merge? Or is there anything else I need to address before this can be merged?

@Abogical
Copy link
Member

@Abogical Thank you so much for your patience, guidance, and approval throughout this entire contribution process! 🙏

@puretension You're welcome!

The previous CI Codebuild PR Build failure was likely due to the branch being out of sync🤔.
The rebase should have resolved the ESLint issues that were blocking the merge.

Should I change something more for safely merge? Or is there anything else I need to address before this can be merged?

There seems to be a build issue in our workflow that approves PR's. We're working on this atm. Hopefully, when this is resolved, the PR can be merged.

@Abogical Abogical changed the title fix(ecs-patterns): resolve target group conflict when switching ALB public/private (under feature flag) fix(ecs-patterns): resolve target group conflict when updating ALB internetFacing or loadBalancerName (under feature flag) Oct 15, 2025
@Abogical
Copy link
Member

@Mergifyio rebase

puretension and others added 12 commits October 15, 2025 14:00
- Add snapshot files for integ.alb-fargate-service-public-private-switch.ts
- Includes CloudFormation template showing different target group names
- ECS target group for public ALB, ECSPrivate for private ALB
…d-balanced-service-base.ts

Co-authored-by: A. Abdel-Rahman <github@abogic.al>
…r feature flag)

- Add ECS_PATTERNS_UNIQUE_TARGET_GROUP_ID feature flag
- Include loadBalancerName in target group ID when flag is enabled
- Prevents CloudFormation conflicts during load balancer replacement
- Addresses both internetFacing and loadBalancerName changes

Fixes aws#33253

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
Signed-off-by: puretension <rlrlfhtm5@gmail.com>
…tests

- Add ECS_PATTERNS_UNIQUE_TARGET_GROUP_ID feature flag documentation to README
- Add comprehensive tests for feature flag enabled/disabled/default scenarios
- Addresses reviewer feedback for feature flag implementation

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
… location

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
…naming

Updates the integration test snapshot to reflect the new target group naming
convention introduced by the feature flag. Private ALB now uses 'ECSPrivate'
target group name to prevent CloudFormation conflicts during public/private
ALB switching.

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
… integration test

The integration test for switching between public and private ALB intentionally
creates destructive changes to demonstrate the fix for target group conflicts.
This is expected behavior when the feature flag is enabled.

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
…Destroy

Update allowDestroy to use the actual CloudFormation resource names
generated by CDK instead of construct IDs.

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
- Update allowDestroy list with correct resource IDs
- Regenerate snapshots to reflect ECSPrivate target group naming
- Fix integration test failures caused by target group name changes

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
…GroupId

Signed-off-by: puretension <rlrlfhtm5@gmail.com>
Copy link
Contributor

mergify bot commented Oct 15, 2025

rebase

✅ Branch has been successfully rebased

@Abogical Abogical force-pushed the fix/ecs-patterns-public-private-targetgroup-33253 branch from e46ee93 to cb7df73 Compare October 15, 2025 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. effort/medium Medium work item – several days of effort p1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(aws_ecs_patterns): ApplicationLoadBalancedFargateService fails to update when switched from public to private - Fails due to target group

3 participants