pulumi-awsx: Auto-creating security group ingress can be problematic

If I specify a SecurityGroup explicitly for an ALB which already has all the ingress rules specified, the load balancer code then tries to create the same rules, and we get an error.

For example:

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

// Create a security group to let traffic flow.
const sg = new awsx.ec2.SecurityGroup("web-sg", {
    vpc: awsx.ec2.Vpc.getDefault(),
    ingress: [{ protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: [ "0.0.0.0/0" ] }],
    egress: [{ protocol: "-1", fromPort: 0, toPort: 0, cidrBlocks: [ "0.0.0.0/0" ] }],
});

// Create an ALB associated with the default VPC for this region and listen on port 80.
const nlb = new awsx.elasticloadbalancingv2.ApplicationLoadBalancer("web-traffic",
    { external: true, securityGroups: [ sg ] });
const listener = nlb.createListener("web-listener", { port: 80 });

This yields an error:

    error: Plan apply failed: [WARN] A duplicate Security Group rule was found on (sg-0616e60b838abac3a). This may be
    a side effect of a now-fixed Terraform issue causing two security groups with
    identical attributes but different source_security_group_ids to overwrite each
    other in the state. See https://github.com/hashicorp/terraform/pull/2376 for more
    information and instructions for recovery. Error message: the specified rule "peer: 0.0.0.0/0, TCP, from port: 80, to port: 80, ALLOW" already exists

I know how to fix this (just remove the explicit ingress rule), but it’s a little unfortunate. For my example, I need to specify the egress otherwise the EC2 instance target fails health checks.

This could just be a wart we need to live with, but I figured I would file an issue so we can have the discussion and searcahability for the problem in case it bites someone else down the road.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 12
  • Comments: 28 (7 by maintainers)

Most upvoted comments

+1 this issue needs to be addressed

@CyrusNajmabadi I just hit this again. I had a security group with ingress open to port 80 already, and then tried to add a load balancer to my program:

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

const sg = new aws.ec2.SecurityGroup("web-secgrp", {
    ingress: [
        { protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] },
    ],
});

const alb = new awsx.elasticloadbalancingv2.ApplicationLoadBalancer("web-traffic", {
    external: true,
    securityGroups: [ sg.id ],
});
const listener = alb.createListener("web-listener", { port: 80 });

const ami = aws.getAmi({
    filters: [{ name: "name", values: ["amzn-ami-hvm-*-x86_64-ebs"] }],
    owners: [ "137112412989" ],
    mostRecent: true,
}).then(ami => ami.id);

export const ips: any[] = [];
export const hostnames: any[] = [];
for (const az of aws.getAvailabilityZones().names) {
    const server = new aws.ec2.Instance(`web-server-${az}`, {
        instanceType: "t2.micro",
        securityGroups: [ sg.name ],
        ami: ami,
        availabilityZone: az,
        userData: "#!/bin/bash\n"+
            `echo 'Hello, World -- from ${az}!' > index.html\n` +
            "nohup python -m SimpleHTTPServer 80 &",
        tags: { "Name": "web-server" },
    });
    ips.push(server.publicIp);
    hostnames.push(server.publicDns);

    alb.attachTarget(`web-target-${az}`, server);
}

The act of creating the listener attempted to create a new security group, which conflicted with my existing security group, leading to the following error:

  aws:ec2:SecurityGroupRule (web-listener-external-0-ingress):
    error: Plan apply failed: [WARN] A duplicate Security Group rule was found on (sg-0a9a0c57408cc5d9d). This may be
    a side effect of a now-fixed Terraform issue causing two security groups with
    identical attributes but different source_security_group_ids to overwrite each
    other in the state. See https://github.com/hashicorp/terraform/pull/2376 for more
    information and instructions for recovery. Error message: the specified rule "peer: 0.0.0.0/0, TCP, from port: 80, to port: 80, ALLOW" already exists

Should we provide an option for the createListener to not create a security group? (For what it’s worth, I’d have assumed that would be the default…)

Our solution to this issue was to not use awsx for the listeners and just use the aws package. We then were able to specify the security groups without the listener creating its own ingress rules

    httpsListener = new aws.lb.Listener('name-https-listener', {
      loadBalancerArn: awsxLoadBalancer.loadBalancer.arn,
      port: 443,
      protocol,
      sslPolicy: "ELBSecurityPolicy-2016-08",
      certificateArn,
      defaultActions: [{
        type: "forward",
        targetGroupArn: awsxTg.targetGroup.arn,
      }],
    }, { parent: awsxLoadBalancer });

    const httpRedirectListener = new aws.lb.Listener('name-http-listener', {
      loadBalancerArn: awsxLoadBalancer.loadBalancer.arn,
      port: 80,
      protocol: "HTTP",
      defaultActions: [{
        type: "redirect",
        redirect: {
          port: "443",
          protocol: "HTTPS",
          statusCode: "HTTP_301",
        },
      }],
    }, { parent: awsxLoadBalancer });

I’ve run into this today, and it’s not the first time. I’m going the path of unawsxing all our resource declarations. It’s simply not worth the pain of going through abstractions that make some use cases so painful.

Just in case anyone comes looking for a workaround, we ended up commenting out these lines:

https://github.com/pulumi/pulumi-awsx/blob/master/nodejs/awsx/lb/application.ts#L244-L248

directly on the @pulumi/awsx installed on node_modules, less than ideal solution, but works for now while the Pulumi team gets around to fixing this.

This issue is seriously causing problems for my company adopting Pulumi, and it is disheartening seeing this being a problem for over a year with not even a workaround proposed.

The same issue right now, it painful enough…

I really waiting for this. This issue prevent two Load Balancers sharing one SecurityGroup.

There seems to be a deeper issue here, we tried just setting the SecurityGroup for the LoadBalancer (something we have done successfully before) and have two FargateService instances share the LoadBalancer and it failed with the exact same error.

Just his this issue too. (I don’t know if validating a report from the wild is appreciated; let me know if not).

It absolutely is! Thanks much!

just hit the issue today, so keeping it alive guys, still need to be addressed !