Skip to content

Error replacing Target Group with fixed name: ResourceInUse: Target group is currently in use by a listener or a rule #4220

Open

Description

Updating Target Group properties that cause replacements (e.g. port) fails if the Target Group has a fixed name and dependent resources (e.g. Listener).
Pulumi cannot perform "Create before Delete" if the Target Group is configured with a fixed name because Target Groups are required to have unique names. Instead Pulumi tries to delete the resource before replacing it.

This fails with a ResourceInUse error if the Target Group is referenced by other resources like a Listener:

aws:alb:TargetGroup (stack-tg2):
    error: deleting urn:pulumi:dev::stack::aws:alb/targetGroup:TargetGroup::stack-tg2: 1 error occurred:
    	* Error deleting Target Group: ResourceInUse: Target group 'arn:aws:elasticloadbalancing:*:*:targetgroup/stack-tg2/fdcc6be49a381f35' is currently in use by a listener or a rule
    	status code: 400, request id: 15e6ebc6-8993-48cb-a041-2bbfc2702d39

Expected Behavior

Updating Target Group properties that cause replacements works even when the Target Group has a fixed name and is referenced by other resources like listeners.

When modifying properties that cause replacements of a Target Group with a fixed name the following steps should happen:

  1. The resources referencing the Target Group should be deleted
  2. The Target Group should be deleted
  3. The Target Group should be re-created with updated configuration
  4. The resources referencing the Target Group should be recreated, pointing to the newly created Target Group

This could be achieved with the following enhancement by allowing to declare those replacement dependencies: pulumi/pulumi#14072

Current Behavior

Pulumi tries to perform Delete before Replace on the Target Group, which fails with a ResourceInUse error if the Target Group is referenced by other resources like a Listener.

Steps to Reproduce

Reproduction Program
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";

const vpc = new awsx.ec2.Vpc("example");

const sg = new aws.ec2.SecurityGroup("example", {
  ingress: [
    {
      protocol: "tcp",
      fromPort: 80,
      toPort: 80,
    },
  ],
  vpcId: vpc.vpcId,
});

const alb = new aws.alb.LoadBalancer("example", {
  name: "example-repro",
  loadBalancerType: aws.alb.LoadBalancerType.Application,
  internal: false,
  subnets: vpc.publicSubnetIds,
  securityGroups: [sg.id],
});

const targetGroup = new aws.alb.TargetGroup("example", {
  name: "example",
  vpcId: vpc.vpcId,
  targetType: "instance",
  protocol: "HTTP",
  port: 443,
});

const albListener = new aws.alb.Listener("example", {
  loadBalancerArn: alb.arn,
  port: 80,
  protocol: "HTTP",
  defaultActions: [
    {
      type: "forward",
      targetGroupArn: targetGroup.arn,
    },
  ],
});
  1. pulumi up with program above
  2. Change the Target Group port to a different number (e.g. 8080)
  3. pulumi up and observe error

Workaround

To circumvent Pulumi having to do a Delete before Replace, you can change the Target Group to use a namePrefix instead of a fixed name. This way Pulumi can Create a replacement for the Target Group before updating dependent resources and ultimately deleting the old Target Group.

Example
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";

const vpc = new awsx.ec2.Vpc("example");

const sg = new aws.ec2.SecurityGroup("example", {
  ingress: [
    {
      protocol: "tcp",
      fromPort: 80,
      toPort: 80,
    },
  ],
  vpcId: vpc.vpcId,
});

const alb = new aws.alb.LoadBalancer("example", {
  name: "example-repro",
  loadBalancerType: aws.alb.LoadBalancerType.Application,
  internal: false,
  subnets: vpc.publicSubnetIds,
  securityGroups: [sg.id],
});

const targetGroup = new aws.alb.TargetGroup("example", {
  namePrefix: "repro-",
  vpcId: vpc.vpcId,
  targetType: "instance",
  protocol: "HTTP",
  port: 443,
});

const albListener = new aws.alb.Listener("example", {
  loadBalancerArn: alb.arn,
  port: 80,
  protocol: "HTTP",
  defaultActions: [
    {
      type: "forward",
      targetGroupArn: targetGroup.arn,
    },
  ],
});

Context (Environment)

It's not the end of the world, but fairly annoying to have to manually delete the listeners, refresh the stack, then re-run update to make sure that the target groups can be replaced without issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    customer/feedbackFeedback from customersimpact/usabilitySomething that impacts users' ability to use the product easily and intuitivelykind/enhancementImprovements or new features

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions