Description
openedon Dec 9, 2020
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:
- The resources referencing the Target Group should be deleted
- The Target Group should be deleted
- The Target Group should be re-created with updated configuration
- 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,
},
],
});
pulumi up
with program above- Change the Target Group port to a different number (e.g.
8080
) 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.