Skip to content

Commit

Permalink
feat(platforms): tf-aws implicit platform now has 2 private subnets (
Browse files Browse the repository at this point in the history
…#6345)

Several resources require multi-az support, such as RDS clusters. This PR adds an additional private subnet to the VPC that is created implicitly for users using tf-aws platforms.

## Checklist

- [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted)
- [ ] Description explains motivation and solution
- [ ] Tests added (always)
- [ ] Docs updated (only required for features)
- [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing

*By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
  • Loading branch information
hasanaburayyan authored May 6, 2024
1 parent c76b1c0 commit d9ebe0a
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 22 deletions.
9 changes: 9 additions & 0 deletions docs/docs/055-platforms/tf-aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ private_subnet_ids = ["subnet-123xyz"]
public_subnet_ids = ["subnet-123xyz"]
```

### Implicit VPC

The `tf-aws` platform can create a new VPC for you if needed. The VPC is pretty standard and includes:

- A VPC with CIDR block `10.0.0.0/16`
- An Internet Gateway
- A NAT Gateway
- A single public subnet with CIDR block `10.0.0.0/24`
- Two private subnets with CIDR blocks `10.0.4.0/22` and `10.0.8.0/22` (both have Egress via NAT Gateway)

## Output

Expand Down
29 changes: 29 additions & 0 deletions libs/wingsdk/src/target-tf-aws/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@ export class App extends CdktfApp {
},
});

const privateSubnet2 = new Subnet(this, "PrivateSubnet2", {
vpcId: this._vpc.id,
cidrBlock: "10.0.8.0/22", // 10.0.8.0 - 10.0.11.255
availabilityZone: `${this.region}b`,
tags: {
Name: `${identifier}-private-subnet-2`,
},
});

// Create the internet gateway
const internetGateway = new InternetGateway(this, "InternetGateway", {
vpcId: this._vpc.id,
Expand Down Expand Up @@ -300,6 +309,20 @@ export class App extends CdktfApp {
},
});

const privateRouteTable2 = new RouteTable(this, "PrivateRouteTable2", {
vpcId: this._vpc.id,
route: [
{
// This will route all traffic to the NAT gateway
cidrBlock: "0.0.0.0/0",
natGatewayId: nat.id,
},
],
tags: {
Name: `${identifier}-private-route-table-2`,
},
});

// Associate route tables with subnets
new RouteTableAssociation(this, "PublicRouteTableAssociation", {
subnetId: publicSubnet.id,
Expand All @@ -311,8 +334,14 @@ export class App extends CdktfApp {
routeTableId: privateRouteTable.id,
});

new RouteTableAssociation(this, "PrivateRouteTableAssociation2", {
subnetId: privateSubnet2.id,
routeTableId: privateRouteTable2.id,
});

this.subnets.public.push(publicSubnet);
this.subnets.private.push(privateSubnet);
this.subnets.private.push(privateSubnet2);
return this._vpc;
}
}
36 changes: 36 additions & 0 deletions libs/wingsdk/test/target-tf-aws/__snapshots__/api.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,29 @@ exports[`api will be private when vpc_api_gateway is true 1`] = `
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PrivateRouteTable2": {
"route": [
{
"carrier_gateway_id": null,
"cidr_block": "0.0.0.0/0",
"core_network_arn": null,
"destination_prefix_list_id": null,
"egress_only_gateway_id": null,
"gateway_id": null,
"ipv6_cidr_block": null,
"local_gateway_id": null,
"nat_gateway_id": "\${aws_nat_gateway.NATGateway.id}",
"network_interface_id": null,
"transit_gateway_id": null,
"vpc_endpoint_id": null,
"vpc_peering_connection_id": null,
},
],
"tags": {
"Name": "Default-c82bf964-private-route-table-2",
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PublicRouteTable": {
"route": [
{
Expand Down Expand Up @@ -263,6 +286,10 @@ exports[`api will be private when vpc_api_gateway is true 1`] = `
"route_table_id": "\${aws_route_table.PrivateRouteTable.id}",
"subnet_id": "\${aws_subnet.PrivateSubnet.id}",
},
"PrivateRouteTableAssociation2": {
"route_table_id": "\${aws_route_table.PrivateRouteTable2.id}",
"subnet_id": "\${aws_subnet.PrivateSubnet2.id}",
},
"PublicRouteTableAssociation": {
"route_table_id": "\${aws_route_table.PublicRouteTable.id}",
"subnet_id": "\${aws_subnet.PublicSubnet.id}",
Expand Down Expand Up @@ -297,6 +324,14 @@ exports[`api will be private when vpc_api_gateway is true 1`] = `
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PrivateSubnet2": {
"availability_zone": "\${data.aws_region.Region.name}b",
"cidr_block": "10.0.8.0/22",
"tags": {
"Name": "Default-c82bf964-private-subnet-2",
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PublicSubnet": {
"availability_zone": "\${data.aws_region.Region.name}a",
"cidr_block": "10.0.0.0/24",
Expand Down Expand Up @@ -325,6 +360,7 @@ exports[`api will be private when vpc_api_gateway is true 1`] = `
"service_name": "\${data.aws_vpc_endpoint_service.Api_api_apiServiceLookup_C62CF75C.service_name}",
"subnet_ids": [
"\${aws_subnet.PrivateSubnet.id}",
"\${aws_subnet.PrivateSubnet2.id}",
],
"vpc_endpoint_type": "Interface",
"vpc_id": "\${aws_vpc.VPC.id}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,7 @@ exports[`function will be behind a vpc when vpc_lambda is set to true 1`] = `
],
"subnet_ids": [
"\${aws_subnet.PrivateSubnet.id}",
"\${aws_subnet.PrivateSubnet2.id}",
],
},
},
Expand Down Expand Up @@ -1535,6 +1536,29 @@ exports[`function will be behind a vpc when vpc_lambda is set to true 1`] = `
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PrivateRouteTable2": {
"route": [
{
"carrier_gateway_id": null,
"cidr_block": "0.0.0.0/0",
"core_network_arn": null,
"destination_prefix_list_id": null,
"egress_only_gateway_id": null,
"gateway_id": null,
"ipv6_cidr_block": null,
"local_gateway_id": null,
"nat_gateway_id": "\${aws_nat_gateway.NATGateway.id}",
"network_interface_id": null,
"transit_gateway_id": null,
"vpc_endpoint_id": null,
"vpc_peering_connection_id": null,
},
],
"tags": {
"Name": "Default-c82bf964-private-route-table-2",
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PublicRouteTable": {
"route": [
{
Expand Down Expand Up @@ -1564,6 +1588,10 @@ exports[`function will be behind a vpc when vpc_lambda is set to true 1`] = `
"route_table_id": "\${aws_route_table.PrivateRouteTable.id}",
"subnet_id": "\${aws_subnet.PrivateSubnet.id}",
},
"PrivateRouteTableAssociation2": {
"route_table_id": "\${aws_route_table.PrivateRouteTable2.id}",
"subnet_id": "\${aws_subnet.PrivateSubnet2.id}",
},
"PublicRouteTableAssociation": {
"route_table_id": "\${aws_route_table.PublicRouteTable.id}",
"subnet_id": "\${aws_subnet.PublicSubnet.id}",
Expand Down Expand Up @@ -1610,6 +1638,14 @@ exports[`function will be behind a vpc when vpc_lambda is set to true 1`] = `
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PrivateSubnet2": {
"availability_zone": "\${data.aws_region.Region.name}b",
"cidr_block": "10.0.8.0/22",
"tags": {
"Name": "Default-c82bf964-private-subnet-2",
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PublicSubnet": {
"availability_zone": "\${data.aws_region.Region.name}a",
"cidr_block": "10.0.0.0/24",
Expand Down
75 changes: 73 additions & 2 deletions libs/wingsdk/test/target-tf-aws/__snapshots__/redis.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ exports[`When creating a Redis resource > should create an elasticache cluster a
"num_cache_nodes": 1,
"parameter_group_name": "default.redis6.x",
"security_group_ids": [
"\${aws_security_group.Redis_KEN15securityGroup_9FF06889.id}",
"\${aws_security_group.Redis_KEN21securityGroup_139152DE.id}",
"\${aws_security_group.Redis_KEN24securityGroup_6EFFC29B.id}",
],
"subnet_group_name": "\${aws_elasticache_subnet_group.Redis_RedisSubnetGroup_E7D796E2.name}",
},
Expand All @@ -31,6 +32,7 @@ exports[`When creating a Redis resource > should create an elasticache cluster a
"name": "redis-c8cdb969-subnetGroup",
"subnet_ids": [
"\${aws_subnet.PrivateSubnet.id}",
"\${aws_subnet.PrivateSubnet2.id}",
],
},
},
Expand Down Expand Up @@ -75,6 +77,29 @@ exports[`When creating a Redis resource > should create an elasticache cluster a
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PrivateRouteTable2": {
"route": [
{
"carrier_gateway_id": null,
"cidr_block": "0.0.0.0/0",
"core_network_arn": null,
"destination_prefix_list_id": null,
"egress_only_gateway_id": null,
"gateway_id": null,
"ipv6_cidr_block": null,
"local_gateway_id": null,
"nat_gateway_id": "\${aws_nat_gateway.NATGateway.id}",
"network_interface_id": null,
"transit_gateway_id": null,
"vpc_endpoint_id": null,
"vpc_peering_connection_id": null,
},
],
"tags": {
"Name": "Default-c82bf964-private-route-table-2",
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PublicRouteTable": {
"route": [
{
Expand Down Expand Up @@ -104,13 +129,17 @@ exports[`When creating a Redis resource > should create an elasticache cluster a
"route_table_id": "\${aws_route_table.PrivateRouteTable.id}",
"subnet_id": "\${aws_subnet.PrivateSubnet.id}",
},
"PrivateRouteTableAssociation2": {
"route_table_id": "\${aws_route_table.PrivateRouteTable2.id}",
"subnet_id": "\${aws_subnet.PrivateSubnet2.id}",
},
"PublicRouteTableAssociation": {
"route_table_id": "\${aws_route_table.PublicRouteTable.id}",
"subnet_id": "\${aws_subnet.PublicSubnet.id}",
},
},
"aws_security_group": {
"Redis_KEN15securityGroup_9FF06889": {
"Redis_KEN21securityGroup_139152DE": {
"egress": [
{
"cidr_blocks": [
Expand Down Expand Up @@ -144,6 +173,40 @@ exports[`When creating a Redis resource > should create an elasticache cluster a
"name": "3542402a-securityGroup",
"vpc_id": "\${aws_vpc.VPC.id}",
},
"Redis_KEN24securityGroup_6EFFC29B": {
"egress": [
{
"cidr_blocks": [
"0.0.0.0/0",
],
"description": null,
"from_port": 0,
"ipv6_cidr_blocks": null,
"prefix_list_ids": null,
"protocol": "-1",
"security_groups": null,
"self": null,
"to_port": 0,
},
],
"ingress": [
{
"cidr_blocks": [
"\${aws_subnet.PrivateSubnet2.cidr_block}",
],
"description": null,
"from_port": 6379,
"ipv6_cidr_blocks": null,
"prefix_list_ids": null,
"protocol": "tcp",
"security_groups": null,
"self": true,
"to_port": 6379,
},
],
"name": "3542402a-securityGroup",
"vpc_id": "\${aws_vpc.VPC.id}",
},
},
"aws_subnet": {
"PrivateSubnet": {
Expand All @@ -154,6 +217,14 @@ exports[`When creating a Redis resource > should create an elasticache cluster a
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PrivateSubnet2": {
"availability_zone": "\${data.aws_region.Region.name}b",
"cidr_block": "10.0.8.0/22",
"tags": {
"Name": "Default-c82bf964-private-subnet-2",
},
"vpc_id": "\${aws_vpc.VPC.id}",
},
"PublicSubnet": {
"availability_zone": "\${data.aws_region.Region.name}a",
"cidr_block": "10.0.0.0/24",
Expand Down
2 changes: 1 addition & 1 deletion libs/wingsdk/test/target-tf-aws/function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ test("function will be behind a vpc when vpc_lambda is set to true", () => {
expect(tfResourcesOfCount(output, "aws_vpc")).toEqual(1);
expect(tfFunction.vpc_config).toBeDefined();
expect(tfFunction.vpc_config.security_group_ids.length).toEqual(1);
expect(tfFunction.vpc_config.subnet_ids.length).toEqual(1);
expect(tfFunction.vpc_config.subnet_ids.length).toEqual(2);
expect(tfSanitize(output)).toMatchSnapshot();
});

Expand Down
14 changes: 7 additions & 7 deletions libs/wingsdk/test/target-tf-aws/redis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ describe("When creating a Redis resource", () => {

// THEN
expect(tfResourcesOfCount(output, "aws_vpc")).toEqual(1);
expect(tfResourcesOfCount(output, "aws_subnet")).toEqual(2);
expect(tfResourcesOfCount(output, "aws_route_table")).toEqual(2);
expect(tfResourcesOfCount(output, "aws_subnet")).toEqual(3);
expect(tfResourcesOfCount(output, "aws_route_table")).toEqual(3);
expect(tfResourcesOfCount(output, "aws_nat_gateway")).toEqual(1);
expect(tfResourcesOfCount(output, "aws_internet_gateway")).toEqual(1);
});
Expand Down Expand Up @@ -93,10 +93,10 @@ describe("When creating multiple Redis resources", () => {
// THEN
// 2 clusters, 2 security groups, 1 vpc, 2 subnets, 2 route tables, 1 nat gateway, 1 internet gateway
expect(tfResourcesOfCount(output, "aws_elasticache_cluster")).toEqual(2);
expect(tfResourcesOfCount(output, "aws_security_group")).toEqual(2);
expect(tfResourcesOfCount(output, "aws_security_group")).toEqual(4);
expect(tfResourcesOfCount(output, "aws_vpc")).toEqual(1);
expect(tfResourcesOfCount(output, "aws_subnet")).toEqual(2);
expect(tfResourcesOfCount(output, "aws_route_table")).toEqual(2);
expect(tfResourcesOfCount(output, "aws_subnet")).toEqual(3);
expect(tfResourcesOfCount(output, "aws_route_table")).toEqual(3);
expect(tfResourcesOfCount(output, "aws_nat_gateway")).toEqual(1);
expect(tfResourcesOfCount(output, "aws_internet_gateway")).toEqual(1);
});
Expand All @@ -121,8 +121,8 @@ describe("When creating multiple Redis resources", () => {
const vpcConfig = JSON.parse(JSON.stringify(lambda.vpc_config));

// THEN
expect(vpcConfig.security_group_ids.length).toEqual(2);
expect(vpcConfig.subnet_ids.length).toEqual(2);
expect(vpcConfig.security_group_ids.length).toEqual(4);
expect(vpcConfig.subnet_ids.length).toEqual(4);
});
});
});
Loading

0 comments on commit d9ebe0a

Please sign in to comment.