Skip to content

Commit 11793ab

Browse files
authored
Refactor Terraform into pure-TF resource files and Jinja tfvars (#125)
Signed-off-by: Jim Enright <[email protected]>
1 parent 2a99e83 commit 11793ab

24 files changed

+1291
-749
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# ------- Dynamic Inventory VMs -------
2+
resource "aws_instance" "cdp_dynamic_inventory_vm" {
3+
4+
for_each = {for idx, vm in var.dynamic_inventory_vms: idx => vm}
5+
6+
vpc_security_group_ids = [aws_security_group.cdp_default_sg.id]
7+
key_name = var.dynamic_inventory_public_key_id
8+
instance_type = each.value.instance_type
9+
ami = each.value.ami
10+
ebs_optimized = true
11+
12+
# Volume / root_block_device
13+
root_block_device {
14+
delete_on_termination = each.value.volume.delete_on_termination
15+
volume_size = each.value.volume.volume_size
16+
volume_type = each.value.volume.volume_type
17+
}
18+
19+
# TODO: Review settng subnet_id to first public subnet (believe Ansible approach does this)
20+
subnet_id = aws_subnet.cdp_public_subnets[0].id
21+
22+
associate_public_ip_address = true
23+
24+
tags = merge(var.dynamic_inventory_tags,{Name = each.value.name})
25+
}
26+
27+
# ------- Localised Utility VM Instance -------
28+
resource "aws_instance" "cdp_utility_vms" {
29+
30+
for_each = {for idx, vm in var.utility_vms: idx => vm}
31+
32+
vpc_security_group_ids = [aws_security_group.cdp_default_sg.id]
33+
key_name = var.utility_vm_public_key_id
34+
instance_type = each.value.instance_type
35+
ami = each.value.ami
36+
ebs_optimized = true
37+
38+
subnet_id = aws_subnet.cdp_public_subnets[0].id
39+
40+
# Volume / root_block_device
41+
root_block_device {
42+
# Need to cast from string (yes) to bool
43+
delete_on_termination = each.value.volume.delete_on_termination
44+
volume_size = each.value.volume.volume_size
45+
volume_type = each.value.volume.volume_type
46+
}
47+
48+
49+
associate_public_ip_address = true
50+
51+
tags = merge(var.utility_vm_tags,{Name = each.value.name})
52+
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# ------- VPC -------
2+
# Create the VPC's
3+
resource "aws_vpc" "cdp_vpc" {
4+
cidr_block = var.vpc_cidr
5+
tags = merge(var.env_tags,{Name = var.vpc_name})
6+
7+
instance_tenancy = "default"
8+
enable_dns_support = true
9+
enable_dns_hostnames = true
10+
}
11+
12+
# ------- AWS Public Network infrastructure -------
13+
# Internet Gateway
14+
resource "aws_internet_gateway" "cdp_igw" {
15+
vpc_id = aws_vpc.cdp_vpc.id
16+
tags = merge(var.env_tags,{Name = var.igw_name})
17+
}
18+
19+
# AWS VPC Public Subnets
20+
resource "aws_subnet" "cdp_public_subnets" {
21+
for_each = {for idx, subnet in var.public_subnets: idx => subnet}
22+
23+
vpc_id = aws_vpc.cdp_vpc.id
24+
cidr_block = each.value.cidr
25+
map_public_ip_on_launch = true
26+
availability_zone = each.value.az
27+
tags = merge(var.env_tags,each.value.tags)
28+
}
29+
30+
# Public Route Table
31+
resource "aws_default_route_table" "cdp_public_route_table" {
32+
default_route_table_id = aws_vpc.cdp_vpc.default_route_table_id
33+
34+
route {
35+
cidr_block = "0.0.0.0/0"
36+
gateway_id = aws_internet_gateway.cdp_igw.id
37+
}
38+
39+
tags = merge(var.env_tags,{Name = var.public_route_table_name})
40+
41+
}
42+
43+
# Associate the Public Route Table with the Public Subnets
44+
resource "aws_route_table_association" "cdp_public_subnets" {
45+
46+
for_each = aws_subnet.cdp_public_subnets
47+
48+
subnet_id = each.value.id
49+
route_table_id = aws_vpc.cdp_vpc.default_route_table_id
50+
}
51+
52+
# ------- AWS Private Networking infrastructure -------
53+
54+
# AWS VPC Private Subnets
55+
resource "aws_subnet" "cdp_private_subnets" {
56+
for_each = {for idx, subnet in var.private_subnets: idx => subnet}
57+
58+
vpc_id = aws_vpc.cdp_vpc.id
59+
cidr_block = each.value.cidr
60+
map_public_ip_on_launch = false
61+
availability_zone = each.value.az
62+
tags = merge(var.env_tags,each.value.tags)
63+
}
64+
65+
# Private Route Table for the AWS VPC
66+
# - Not implemeted in Terraform because of "when: no" in Ansible
67+
68+
# Elastic IP for each NAT gateway
69+
resource "aws_eip" "cdp_nat_gateway_eip" {
70+
71+
for_each = {for idx, subnet in var.public_subnets: idx => subnet}
72+
73+
vpc = true
74+
tags = merge(var.env_tags,{Name = format("%s-%s-%02d", var.nat_gateway_name, "eip", index(var.public_subnets, each.value)+1)})
75+
}
76+
77+
# Network Gateways (NAT)
78+
resource "aws_nat_gateway" "cdp_nat_gateway" {
79+
80+
# for_each = { for s in aws_subnet.cdp_public_subnets : s.id => s }
81+
count = length(aws_subnet.cdp_public_subnets)
82+
83+
subnet_id = aws_subnet.cdp_public_subnets[count.index].id
84+
allocation_id = aws_eip.cdp_nat_gateway_eip[count.index].id
85+
connectivity_type = "public"
86+
87+
tags = merge(var.env_tags,{Name = format("%s-%02d", var.nat_gateway_name, count.index)})
88+
# tags = merge(var.env_tags,{Name = format("%s-%s-%02d", var.nat_gateway_name, "eip", index(aws_subnet.cdp_public_subnets, each.value)+1)})
89+
}
90+
91+
92+
# Private Route Tables
93+
resource "aws_route_table" "cdp_private_route_table" {
94+
for_each = {for idx, subnet in var.private_subnets: idx => subnet}
95+
96+
vpc_id = aws_vpc.cdp_vpc.id
97+
98+
tags = merge(var.env_tags,{Name = format("%s-%02d", var.private_route_table_name, index(var.private_subnets, each.value))})
99+
100+
route {
101+
cidr_block = "0.0.0.0/0"
102+
#nat_gateway_id = aws_nat_gateway.cdp_nat_gateway[0].id
103+
104+
nat_gateway_id = aws_nat_gateway.cdp_nat_gateway[(index(var.private_subnets, each.value) % length(aws_nat_gateway.cdp_nat_gateway))].id
105+
106+
}
107+
}
108+
109+
# Associate the Private Route Tables with the Private Subnets
110+
resource "aws_route_table_association" "cdp_private_subnets" {
111+
112+
count = length(aws_subnet.cdp_private_subnets)
113+
114+
subnet_id = aws_subnet.cdp_private_subnets[count.index].id
115+
route_table_id = aws_route_table.cdp_private_route_table[count.index].id
116+
}
117+
118+
# ------- Security Groups -------
119+
# Default SG
120+
resource "aws_security_group" "cdp_default_sg" {
121+
vpc_id = aws_vpc.cdp_vpc.id
122+
name = var.security_group_default_name
123+
description = var.security_group_default_name
124+
125+
tags = merge(var.env_tags,{Name = var.security_group_default_name})
126+
127+
# Create self reference ingress rule to allow
128+
# communication among resources in the security group.
129+
ingress {
130+
from_port = 0
131+
to_port = 0
132+
protocol = "all"
133+
self = true
134+
}
135+
136+
# Dynamic Block to create security group rule from var.sg_ingress
137+
dynamic "ingress" {
138+
for_each = var.security_group_rules_ingress
139+
140+
content {
141+
cidr_blocks = ingress.value.cidr
142+
from_port = ingress.value.from_port
143+
to_port = ingress.value.to_port
144+
protocol = ingress.value.protocol
145+
}
146+
147+
}
148+
149+
# Terraform removes the default ALLOW ALL egress. Let's recreate this
150+
egress {
151+
cidr_blocks = ["0.0.0.0/0"]
152+
from_port = 0
153+
to_port = 0
154+
protocol = "all"
155+
}
156+
}
157+
158+
# Knox SG
159+
resource "aws_security_group" "cdp_knox_sg" {
160+
vpc_id = aws_vpc.cdp_vpc.id
161+
name = var.security_group_knox_name
162+
description = var.security_group_knox_name
163+
164+
tags = merge(var.env_tags,{Name = var.security_group_knox_name})
165+
166+
# Create self reference ingress rule to allow
167+
# communication among resources in the security group.
168+
ingress {
169+
from_port = 0
170+
to_port = 0
171+
protocol = "all"
172+
self = true
173+
}
174+
175+
# Dynamic Block to create security group rule from var.sg_ingress
176+
dynamic "ingress" {
177+
for_each = var.security_group_rules_ingress
178+
179+
content {
180+
cidr_blocks = ingress.value.cidr
181+
from_port = ingress.value.from_port
182+
to_port = ingress.value.to_port
183+
protocol = ingress.value.protocol
184+
}
185+
186+
}
187+
188+
# Terraform removes the default ALLOW ALL egress. Let's recreate this
189+
egress {
190+
cidr_blocks = ["0.0.0.0/0"]
191+
from_port = 0
192+
to_port = 0
193+
protocol = "all"
194+
}
195+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# ------- S3 Buckets -------
2+
# NOTE: Variables cannot be used with the prevent_destroy lifecycle policy
3+
# To overcome this limitation and still support infra__teardown_deletes_data = False
4+
# we create two similar resource using a conditional on the for_each.
5+
# Resource cdp_storage_delete_data is created when teardown_deletes_data = True
6+
# Resource cdp_storage_retain_data is created when teardown_deletes_data = False
7+
# References:
8+
# * https://github.com/hashicorp/terraform/issues/22544#issuecomment-981575058
9+
# * https://discuss.hashicorp.com/t/conditionally-create-resources-when-a-for-each-loop-is-involved/20841/9
10+
11+
resource "aws_s3_bucket" "cdp_storage_delete_data" {
12+
for_each = var.teardown_deletes_data ? toset(var.storage_locations[*].bucket) : []
13+
14+
bucket = each.value
15+
tags = merge(var.env_tags,{Name = each.value})
16+
17+
# Purge storage locations during teardown?
18+
force_destroy = true
19+
lifecycle {
20+
# A Terraform destroy of this resource will result in an error message.
21+
prevent_destroy = false
22+
}
23+
}
24+
resource "aws_s3_bucket" "cdp_storage_retain_data" {
25+
for_each = var.teardown_deletes_data ? [] : toset(var.storage_locations[*].bucket)
26+
27+
bucket = each.value
28+
tags = merge(var.env_tags,{Name = each.value})
29+
30+
# Purge storage locations during teardown?
31+
force_destroy = false
32+
lifecycle {
33+
# A Terraform destroy of this resource will result in an error message.
34+
prevent_destroy = true
35+
}
36+
}
37+
38+
# Separate bucket acl resource definition
39+
resource "aws_s3_bucket_acl" "cdp_storage_acl" {
40+
for_each = var.teardown_deletes_data ? aws_s3_bucket.cdp_storage_delete_data : aws_s3_bucket.cdp_storage_retain_data
41+
42+
bucket = each.value.id
43+
acl = "private"
44+
}
45+
46+
# ------- AWS Buckets directory structures -------
47+
resource "aws_s3_object" "cdp_storage_object" {
48+
49+
for_each = {for idx, object in var.storage_locations: idx => object}
50+
51+
# Bucket is either from 'cdp_storage_delete_data' or 'cdp_storage_retain_data' resource depending on teardown_deletes_data'
52+
bucket = var.teardown_deletes_data ? aws_s3_bucket.cdp_storage_delete_data[each.value.bucket].id : aws_s3_bucket.cdp_storage_retain_data[each.value.bucket].id
53+
54+
key = each.value.object
55+
content_type = "application/x-directory"
56+
}
57+
58+
# ------- Download Mirror Bucket -------
59+
# TODO: Don't fail if Mirror Bucket already exists from non-Terraform code.
60+
# resource "aws_s3_bucket" "cdp_utility_bucket" {
61+
# bucket = var.utility_bucket
62+
# acl = "private"
63+
# force_destroy = true
64+
65+
# tags = merge(var.env_tags,{Name = var.utility_bucket})
66+
# }

0 commit comments

Comments
 (0)