Skip to content

Commit

Permalink
Add Security Group to NLBs (#1285)
Browse files Browse the repository at this point in the history
Since August 23 NLBs support Security Groups as well now (see [AWS blog
post](https://aws.amazon.com/blogs/containers/network-load-balancers-now-support-security-groups/)).

This change adds the parameter for configuring security groups to the
NLB component. The one notable difference compared to the ALB component
is that I refrained from adding the default security group. For NLBs
security groups cannot be added if none are currently present, and
cannot all be removed once added. Adding a default security group to
NLBs would cause replacements during upgrades.

Fixes #1282

Also re-enabled the LB upgrade tests and re-recorded them. They were
failing because they were using invokes under the hood to get the
default subnet. Invokes are not compatible with upgrade tests because
they don't use the recorded calls and instead reach out to the cloud
instead.
Fixes #1265 &
#1114
  • Loading branch information
flostadler committed May 14, 2024
1 parent 18bd13b commit 8bcfa31
Show file tree
Hide file tree
Showing 21 changed files with 2,381 additions and 1,097 deletions.
44 changes: 0 additions & 44 deletions awsx/lb/applicationLoadBalancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,50 +117,6 @@ export class ApplicationLoadBalancer extends schema.ApplicationLoadBalancer {
}
}

if (listener && listeners) {
throw new Error("Only one of [listener] and [listeners] can be specified");
}

if (!lbArgs.securityGroups && !defaultSecurityGroup?.skip) {
if (defaultSecurityGroup?.args && defaultSecurityGroup.securityGroupId) {
throw new Error(
"Only one of [defaultSecurityGroup] [args] or [securityGroupId] can be specified",
);
}
const securityGroupId = defaultSecurityGroup?.securityGroupId;
if (securityGroupId) {
lbArgs.securityGroups = [securityGroupId];
} else {
const securityGroup = new aws.ec2.SecurityGroup(
name,
defaultSecurityGroup?.args ?? {
// TO-DO: we default to open SG rules at this point - we should review this!
ingress: [
{
fromPort: 0,
toPort: 0,
protocol: "-1",
cidrBlocks: ["0.0.0.0/0"],
ipv6CidrBlocks: ["::/0"],
},
],
egress: [
{
fromPort: 0,
toPort: 65535,
protocol: "tcp",
cidrBlocks: ["0.0.0.0/0"],
ipv6CidrBlocks: ["::/0"],
},
],
},
{ parent: this },
);
this.defaultSecurityGroup = securityGroup;
lbArgs.securityGroups = [securityGroup.id];
}
}

// this is an application loadbalancer so we set this explicitly
// we have removed this from the input properties in the schema
lbArgs.loadBalancerType = "application";
Expand Down
1 change: 1 addition & 0 deletions awsx/schema-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ export interface NetworkLoadBalancerArgs {
readonly name?: pulumi.Input<string>;
readonly namePrefix?: pulumi.Input<string>;
readonly preserveHostHeader?: pulumi.Input<boolean>;
readonly securityGroups?: pulumi.Input<pulumi.Input<string>[]>;
readonly subnetIds?: pulumi.Input<pulumi.Input<string>[]>;
readonly subnetMappings?: pulumi.Input<pulumi.Input<aws.types.input.lb.LoadBalancerSubnetMapping>[]>;
readonly subnets?: pulumi.Input<pulumi.Input<aws.ec2.Subnet>[]>;
Expand Down
10 changes: 10 additions & 0 deletions examples/examples_nodejs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ func TestNlbSimple(t *testing.T) {
integration.ProgramTest(t, &test)
}

func TestNlbWithSecurityGroup(t *testing.T) {
test := getNodeJSBaseOptions(t).
With(integration.ProgramTestOptions{
RunUpdateTest: false,
Dir: filepath.Join(getCwd(t), "ts-nlb-with-security-group"),
})

integration.ProgramTest(t, &test)
}

func TestEcrSimple(t *testing.T) {
test := getNodeJSBaseOptions(t).
With(integration.ProgramTestOptions{
Expand Down
43 changes: 40 additions & 3 deletions examples/ts-lb-simple/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,51 @@ import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";

// Create VPC for the LB and ECS service
const vpc = new awsx.ec2.Vpc("test-vpc", {
subnetSpecs: [
{ type: "Public" }
],
natGateways: {
strategy: "None",
}
});

const cluster = new aws.ecs.Cluster("default-cluster");

// // Create a load balancer on port 80 and spin up two instances of Nginx.
const lb = new awsx.lb.ApplicationLoadBalancer("nginx-lb");
// Create a load balancer on port 80 and spin up two instances of Nginx.
const lb = new awsx.lb.ApplicationLoadBalancer("nginx-lb", {
subnets: vpc.subnets,
});

// Create a security group for the service that only allows ingress from the LB
const serviceSg = new aws.ec2.SecurityGroup(`test-service-sg`, {
vpcId: vpc.vpcId,
ingress: [
{
protocol: '-1',
fromPort: 0,
toPort: 0,
securityGroups: [lb.defaultSecurityGroup.apply(sg => sg!.id)],
},
],
egress: [
{
protocol: '-1',
fromPort: 0,
toPort: 0,
cidrBlocks: ['0.0.0.0/0'],
}
]
});

const service = new awsx.ecs.FargateService("my-service", {
cluster: cluster.arn,
assignPublicIp: true,
networkConfiguration: {
assignPublicIp: true,
securityGroups: [serviceSg.id],
subnets: vpc.publicSubnetIds,
},
taskDefinitionArgs: {
container: {
image: "nginx:latest",
Expand Down
16 changes: 14 additions & 2 deletions examples/ts-nlb-simple/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import * as awsx from "@pulumi/awsx";

// // Create a network load balancer.
const lb = new awsx.lb.NetworkLoadBalancer("nginx-lb");
// Create VPC for the LB
const vpc = new awsx.ec2.Vpc("test-vpc", {
subnetSpecs: [
{ type: "Public" }
],
natGateways: {
strategy: "None",
}
});

// Create a network load balancer.
const lb = new awsx.lb.NetworkLoadBalancer("nginx-lb", {
subnets: vpc.subnets,
});
3 changes: 3 additions & 0 deletions examples/ts-nlb-with-security-group/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: ts-nlb-with-security-group
runtime: nodejs
description: Minimal Network LoadBalancer Typescript component test
11 changes: 11 additions & 0 deletions examples/ts-nlb-with-security-group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as awsx from "@pulumi/awsx";
import * as aws from "@pulumi/aws";

const securityGroup = new aws.ec2.SecurityGroup(
"nlb-security-group",
);

// Create a network load balancer with the security group from above
const lb = new awsx.lb.NetworkLoadBalancer("nlb", {
securityGroups: [securityGroup.id]
});
11 changes: 11 additions & 0 deletions examples/ts-nlb-with-security-group/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "ts-lb-simple",
"devDependencies": {
"@types/node": "^18.0.0"
},
"dependencies": {
"@pulumi/aws": "^6.0.0",
"@pulumi/pulumi": "^3.0.0",
"@pulumi/awsx": "latest"
}
}
15 changes: 15 additions & 0 deletions examples/ts-nlb-with-security-group/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
}
}
2 changes: 0 additions & 2 deletions provider/provider_nodejs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,10 @@ func TestEcrRepositoryUpgrade(t *testing.T) {
}

func TestLoadBalancerUpgrade(t *testing.T) {
t.Skip("TODO[pulumi/pulumi-awsx#1265]")
testProviderUpgrade(t, "../examples/ts-lb-simple", &testProviderUpgradeOptions{linkNodeSDK: true})
}

func TestNetworkLoadBalancerUpgrade(t *testing.T) {
t.Skip("TODO[pulumi/pulumi-awsx#1265]")
testProviderUpgrade(t, "../examples/ts-nlb-simple", &testProviderUpgradeOptions{linkNodeSDK: true})
}

Expand Down

0 comments on commit 8bcfa31

Please sign in to comment.