Skip to content

Commit cb10833

Browse files
Merge pull request #178 from devxp-ca/137-load-bal
137 load balancer support
2 parents dbd41ad + 5315395 commit cb10833

File tree

8 files changed

+235
-70
lines changed

8 files changed

+235
-70
lines changed

backend/src/controllers/terraform.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {rootBlockSplitBackend} from "../terraform/terraform";
2323
import {internalErrorHandler} from "../types/errorHandler";
2424
import {TerraformResource} from "../types/terraform";
2525
import {jsonToHcl} from "../util";
26+
import {AwsLoadBalancer} from "../terraform/awsLoadBalancer";
2627

2728
export const createTerraformSettings = (req: Request, res: Response): void => {
2829
const provider = req.body.settings?.provider as "aws" | "google" | "azure";
@@ -31,6 +32,7 @@ export const createTerraformSettings = (req: Request, res: Response): void => {
3132
const allowSsh = req.body.settings.allowSsh ?? false;
3233
const allowEgressWeb = req.body.settings.allowEgressWeb ?? false;
3334
const allowIngressWeb = req.body.settings.allowIngressWeb ?? false;
35+
const autoLoadBalance = req.body.settings.autoLoadBalance ?? false;
3436

3537
//Only needed for google
3638
const project =
@@ -88,7 +90,30 @@ export const createTerraformSettings = (req: Request, res: Response): void => {
8890
return;
8991
}
9092

91-
const [gce, lambda, networkedResources] = splitForPrefab(resources);
93+
/* eslint-disable prefer-const */
94+
let [gce, lambda, networkedResources] = splitForPrefab(resources);
95+
/* eslint-enable prefer-const */
96+
97+
if (autoLoadBalance) {
98+
networkedResources = [
99+
...networkedResources,
100+
new AwsLoadBalancer(
101+
`http_load_balancer`,
102+
"TBD",
103+
"application",
104+
true,
105+
"TBD",
106+
"TBD",
107+
undefined,
108+
undefined,
109+
undefined,
110+
undefined,
111+
undefined,
112+
undefined,
113+
"http-load-balancer"
114+
)
115+
];
116+
}
92117

93118
const network =
94119
networkedResources.length > 0 && provider === "aws"

backend/src/index.ts

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,43 @@ server.serve("/about");
1515
server.serve("/contact");
1616
server.route("/", mainRouter);
1717

18-
// import {testToFileAws} from "./util";
19-
// import {Ec2} from "./terraform/ec2";
20-
// import {prefabNetwork} from "./terraform/prefab";
21-
// import {S3} from "./terraform/s3";
22-
// import {GlacierVault} from "./terraform/glacierVault";
23-
// import {DynamoDb} from "./terraform/DynamoDb";
18+
import {testToFileAws} from "./util";
19+
import {Ec2} from "./terraform/ec2";
20+
import {prefabNetwork} from "./terraform/prefab";
21+
import {AwsLoadBalancer} from "./terraform/awsLoadBalancer";
2422

25-
// testToFileAws(
26-
// "/home/brennan/aws_test/devxp.tf",
27-
// prefabNetwork(
28-
// {
29-
// ec2: [new Ec2("AUTO_UBUNTU", "t2.micro", "instance_a", true)],
30-
// s3: [
31-
// new S3(
32-
// "devxp_test_bucket_a",
33-
// false,
34-
// false,
35-
// "devxp-test-bucket-a"
36-
// )
37-
// ],
38-
// glacier: new GlacierVault(
39-
// "devxp_test_vault",
40-
// false,
41-
// "devxp-test-vault"
42-
// ),
43-
// dynamo: new DynamoDb("devxp_test_dynamo_db", [
44-
// {
45-
// name: "field1",
46-
// type: "S",
47-
// isHash: true
48-
// }
49-
// ])
50-
// },
51-
// {
52-
// ssh: true,
53-
// webEgress: true,
54-
// webIngress: true
55-
// }
56-
// )
57-
// );
23+
testToFileAws(
24+
"/home/brennan/aws_test/devxp.tf",
25+
prefabNetwork(
26+
{
27+
ec2: [
28+
new Ec2("AUTO_UBUNTU", "t2.micro", "instance_a", true),
29+
new Ec2("AUTO_UBUNTU", "t2.micro", "instance_b", true),
30+
new Ec2("AUTO_UBUNTU", "t2.micro", "instance_c", true)
31+
],
32+
load_balancer: new AwsLoadBalancer(
33+
`http_load_balancer`,
34+
"TBD",
35+
"application",
36+
true,
37+
"TBD",
38+
"TBD",
39+
undefined,
40+
undefined,
41+
undefined,
42+
undefined,
43+
undefined,
44+
undefined,
45+
"http-load-balancer"
46+
)
47+
},
48+
{
49+
ssh: true,
50+
webEgress: true,
51+
webIngress: true
52+
}
53+
)
54+
);
5855

5956
mongoose.connection.on(
6057
"error",
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import {jsonRoot} from "./util";
2+
import {Resource} from "./resource";
3+
import {load_balancer_type} from "../types/terraform";
4+
import {arr} from "../util";
5+
import {Ec2} from "./ec2";
6+
7+
export interface AwsLoadBalancer {
8+
vpc: string;
9+
internal: boolean;
10+
type: load_balancer_type;
11+
securityGroups: string[];
12+
subnet: string[];
13+
protocol: string;
14+
port: number;
15+
instances: Ec2[];
16+
enable_http2: boolean;
17+
enable_deletion_protection: boolean;
18+
}
19+
export class AwsLoadBalancer
20+
extends Resource<AwsLoadBalancer>
21+
implements AwsLoadBalancer
22+
{
23+
constructor(
24+
id: string,
25+
26+
vpc: string,
27+
type: load_balancer_type,
28+
internal: boolean,
29+
securityGroups: string[] | string,
30+
subnet: string | string[],
31+
protocol = "HTTP",
32+
port = 80,
33+
34+
instances: Ec2[] = [],
35+
36+
enable_http2 = false,
37+
enable_deletion_protection = true,
38+
39+
autoIam?: boolean,
40+
name?: string
41+
) {
42+
super(id, "AwsLoadBalancer", autoIam, name);
43+
44+
this.vpc = vpc;
45+
this.type = type;
46+
this.internal = internal;
47+
this.securityGroups = arr(securityGroups);
48+
this.subnet = arr(subnet);
49+
this.protocol = protocol;
50+
this.port = port;
51+
this.instances = instances;
52+
this.enable_http2 = enable_http2;
53+
this.enable_deletion_protection = enable_deletion_protection;
54+
}
55+
56+
//Returns a resource block
57+
toJSON() {
58+
return [
59+
jsonRoot("aws_lb", this.id, {
60+
name: this.name,
61+
internal: this.internal,
62+
security_groups: this.securityGroups.map(
63+
g => `\${aws_security_group.${g}.id}`
64+
),
65+
subnets: this.subnet.map(s => `\${aws_subnet.${s}.id}`),
66+
enable_http2: this.enable_http2,
67+
enable_deletion_protection: this.enable_deletion_protection
68+
}),
69+
jsonRoot("aws_lb_target_group", `${this.id}_target`, {
70+
name: `${this.name}-target`,
71+
port: this.port,
72+
protocol: this.protocol,
73+
vpc_id: `\${aws_vpc.${this.vpc}.id}`
74+
}),
75+
jsonRoot("aws_lb_listener", `${this.id}_listener`, {
76+
port: this.port,
77+
protocol: this.protocol,
78+
load_balancer_arn: `\${aws_lb.${this.id}.id}`,
79+
default_action: {
80+
type: "forward",
81+
target_group_arn: `\${aws_lb_target_group.${this.id}_target.arn}`
82+
}
83+
}),
84+
...this.instances.map(ec2 =>
85+
jsonRoot(
86+
"aws_lb_target_group_attachment",
87+
`${this.id}_${ec2.id}_attachment`,
88+
{
89+
target_group_arn: `\${aws_lb_target_group.${this.id}_target.arn}`,
90+
target_id: `\${aws_instance.${ec2.id}.id}`,
91+
port: this.port
92+
}
93+
)
94+
)
95+
];
96+
}
97+
}

backend/src/terraform/awsVpc.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@ import {AwsSubnet} from "./awsSubnet";
44
import {AwsInternetGateway} from "./AwsInternetGateway";
55
import {AwsRouteTable} from "./AwsRouteTable";
66
import {AwsRoute} from "./AwsRoute";
7+
import {awsRegion} from "../types/terraform";
78

89
export interface AwsVpc {
910
cidr_block: string;
1011
private_cidr: string;
11-
public_cidr: string;
12+
public_cidr: string[];
1213
privateDns: boolean;
14+
zones: awsRegion[];
1315
}
1416

1517
export class AwsVpc extends Resource<AwsVpc> implements AwsVpc {
1618
constructor(
1719
cidr_block: string,
1820
private_cidr: string,
19-
public_cidr: string,
21+
public_cidr: string[],
2022
id: string,
23+
zones: awsRegion[] = ["us-west-2a"],
2124
autoIam?: boolean,
2225
name?: string,
2326
privateDns = false
@@ -27,19 +30,20 @@ export class AwsVpc extends Resource<AwsVpc> implements AwsVpc {
2730
this.private_cidr = private_cidr;
2831
this.public_cidr = public_cidr;
2932
this.privateDns = privateDns;
33+
this.zones = zones;
3034
}
3135

3236
//Returns an array of resource blocks
3337
toJSON() {
3438
const gatewayId = `${this.id}_internetgateway`;
3539
const publicRouteTableId = `${this.id}_routetable_pub`;
36-
const privateRouteTableId = `${this.id}_routetable_priv`;
40+
//const privateRouteTableId = `${this.id}_routetable_priv`;
3741
const publicSubetId = `${this.id}_subnet_public`;
38-
const privateSubnetId = `${this.id}_subnet_private`;
42+
//const privateSubnetId = `${this.id}_subnet_private`;
3943

4044
return [
4145
//PRIVATE
42-
new AwsSubnet(
46+
/*new AwsSubnet(
4347
this.id,
4448
this.private_cidr,
4549
false,
@@ -53,17 +57,20 @@ export class AwsVpc extends Resource<AwsVpc> implements AwsVpc {
5357
subnet_id: `\${aws_subnet.${privateSubnetId}.id}`,
5458
route_table_id: `\${aws_route_table.${privateRouteTableId}.id}`
5559
}
56-
),
60+
),*/
5761

5862
//----------------------------------------------------------------//
5963

6064
//PUBLIC
61-
new AwsSubnet(
62-
this.id,
63-
this.public_cidr,
64-
true,
65-
publicSubetId
66-
).toJSON(),
65+
...this.zones.map((zone, i) =>
66+
new AwsSubnet(
67+
this.id,
68+
this.public_cidr[i] ?? this.public_cidr[0],
69+
true,
70+
`${publicSubetId}${i}`,
71+
zone
72+
).toJSON()
73+
),
6774
new AwsInternetGateway(gatewayId, this.id).toJSON(),
6875
new AwsRouteTable(
6976
publicRouteTableId,
@@ -86,7 +93,7 @@ export class AwsVpc extends Resource<AwsVpc> implements AwsVpc {
8693
"aws_route_table_association",
8794
`${this.id}_subnet_public_assoc`,
8895
{
89-
subnet_id: `\${aws_subnet.${publicSubetId}.id}`,
96+
subnet_id: `\${aws_subnet.${publicSubetId}0.id}`,
9097
route_table_id: `\${aws_route_table.${publicRouteTableId}.id}`
9198
}
9299
),

0 commit comments

Comments
 (0)