Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions roles/infrastructure/files/aws/infra_aws_compute.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# ------- Dynamic Inventory VMs -------
resource "aws_instance" "cdp_dynamic_inventory_vm" {

for_each = {for idx, vm in var.dynamic_inventory_vms: idx => vm}

vpc_security_group_ids = [aws_security_group.cdp_default_sg.id]
key_name = var.dynamic_inventory_public_key_id
instance_type = each.value.instance_type
ami = each.value.ami
ebs_optimized = true

# Volume / root_block_device
root_block_device {
delete_on_termination = each.value.volume.delete_on_termination
volume_size = each.value.volume.volume_size
volume_type = each.value.volume.volume_type
}

# TODO: Review settng subnet_id to first public subnet (believe Ansible approach does this)
subnet_id = aws_subnet.cdp_public_subnets[0].id

associate_public_ip_address = true

tags = merge(var.dynamic_inventory_tags,{Name = each.value.name})
}

# ------- Localised Utility VM Instance -------
resource "aws_instance" "cdp_utility_vms" {

for_each = {for idx, vm in var.utility_vms: idx => vm}

vpc_security_group_ids = [aws_security_group.cdp_default_sg.id]
key_name = var.utility_vm_public_key_id
instance_type = each.value.instance_type
ami = each.value.ami
ebs_optimized = true

subnet_id = aws_subnet.cdp_public_subnets[0].id

# Volume / root_block_device
root_block_device {
# Need to cast from string (yes) to bool
delete_on_termination = each.value.volume.delete_on_termination
volume_size = each.value.volume.volume_size
volume_type = each.value.volume.volume_type
}


associate_public_ip_address = true

tags = merge(var.utility_vm_tags,{Name = each.value.name})
}
195 changes: 195 additions & 0 deletions roles/infrastructure/files/aws/infra_aws_network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# ------- VPC -------
# Create the VPC's
resource "aws_vpc" "cdp_vpc" {
cidr_block = var.vpc_cidr
tags = merge(var.env_tags,{Name = var.vpc_name})

instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
}

# ------- AWS Public Network infrastructure -------
# Internet Gateway
resource "aws_internet_gateway" "cdp_igw" {
vpc_id = aws_vpc.cdp_vpc.id
tags = merge(var.env_tags,{Name = var.igw_name})
}

# AWS VPC Public Subnets
resource "aws_subnet" "cdp_public_subnets" {
for_each = {for idx, subnet in var.public_subnets: idx => subnet}

vpc_id = aws_vpc.cdp_vpc.id
cidr_block = each.value.cidr
map_public_ip_on_launch = true
availability_zone = each.value.az
tags = merge(var.env_tags,each.value.tags)
}

# Public Route Table
resource "aws_default_route_table" "cdp_public_route_table" {
default_route_table_id = aws_vpc.cdp_vpc.default_route_table_id

route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.cdp_igw.id
}

tags = merge(var.env_tags,{Name = var.public_route_table_name})

}

# Associate the Public Route Table with the Public Subnets
resource "aws_route_table_association" "cdp_public_subnets" {

for_each = aws_subnet.cdp_public_subnets

subnet_id = each.value.id
route_table_id = aws_vpc.cdp_vpc.default_route_table_id
}

# ------- AWS Private Networking infrastructure -------

# AWS VPC Private Subnets
resource "aws_subnet" "cdp_private_subnets" {
for_each = {for idx, subnet in var.private_subnets: idx => subnet}

vpc_id = aws_vpc.cdp_vpc.id
cidr_block = each.value.cidr
map_public_ip_on_launch = false
availability_zone = each.value.az
tags = merge(var.env_tags,each.value.tags)
}

# Private Route Table for the AWS VPC
# - Not implemeted in Terraform because of "when: no" in Ansible

# Elastic IP for each NAT gateway
resource "aws_eip" "cdp_nat_gateway_eip" {

for_each = {for idx, subnet in var.public_subnets: idx => subnet}

vpc = true
tags = merge(var.env_tags,{Name = format("%s-%s-%02d", var.nat_gateway_name, "eip", index(var.public_subnets, each.value)+1)})
}

# Network Gateways (NAT)
resource "aws_nat_gateway" "cdp_nat_gateway" {

# for_each = { for s in aws_subnet.cdp_public_subnets : s.id => s }
count = length(aws_subnet.cdp_public_subnets)

subnet_id = aws_subnet.cdp_public_subnets[count.index].id
allocation_id = aws_eip.cdp_nat_gateway_eip[count.index].id
connectivity_type = "public"

tags = merge(var.env_tags,{Name = format("%s-%02d", var.nat_gateway_name, count.index)})
# tags = merge(var.env_tags,{Name = format("%s-%s-%02d", var.nat_gateway_name, "eip", index(aws_subnet.cdp_public_subnets, each.value)+1)})
}


# Private Route Tables
resource "aws_route_table" "cdp_private_route_table" {
for_each = {for idx, subnet in var.private_subnets: idx => subnet}

vpc_id = aws_vpc.cdp_vpc.id

tags = merge(var.env_tags,{Name = format("%s-%02d", var.private_route_table_name, index(var.private_subnets, each.value))})

route {
cidr_block = "0.0.0.0/0"
#nat_gateway_id = aws_nat_gateway.cdp_nat_gateway[0].id

nat_gateway_id = aws_nat_gateway.cdp_nat_gateway[(index(var.private_subnets, each.value) % length(aws_nat_gateway.cdp_nat_gateway))].id

}
}

# Associate the Private Route Tables with the Private Subnets
resource "aws_route_table_association" "cdp_private_subnets" {

count = length(aws_subnet.cdp_private_subnets)

subnet_id = aws_subnet.cdp_private_subnets[count.index].id
route_table_id = aws_route_table.cdp_private_route_table[count.index].id
}

# ------- Security Groups -------
# Default SG
resource "aws_security_group" "cdp_default_sg" {
vpc_id = aws_vpc.cdp_vpc.id
name = var.security_group_default_name
description = var.security_group_default_name

tags = merge(var.env_tags,{Name = var.security_group_default_name})

# Create self reference ingress rule to allow
# communication among resources in the security group.
ingress {
from_port = 0
to_port = 0
protocol = "all"
self = true
}

# Dynamic Block to create security group rule from var.sg_ingress
dynamic "ingress" {
for_each = var.security_group_rules_ingress

content {
cidr_blocks = ingress.value.cidr
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
}

}

# Terraform removes the default ALLOW ALL egress. Let's recreate this
egress {
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 0
protocol = "all"
}
}

# Knox SG
resource "aws_security_group" "cdp_knox_sg" {
vpc_id = aws_vpc.cdp_vpc.id
name = var.security_group_knox_name
description = var.security_group_knox_name

tags = merge(var.env_tags,{Name = var.security_group_knox_name})

# Create self reference ingress rule to allow
# communication among resources in the security group.
ingress {
from_port = 0
to_port = 0
protocol = "all"
self = true
}

# Dynamic Block to create security group rule from var.sg_ingress
dynamic "ingress" {
for_each = var.security_group_rules_ingress

content {
cidr_blocks = ingress.value.cidr
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
}

}

# Terraform removes the default ALLOW ALL egress. Let's recreate this
egress {
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 0
protocol = "all"
}
}
66 changes: 66 additions & 0 deletions roles/infrastructure/files/aws/infra_aws_storage.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# ------- S3 Buckets -------
# NOTE: Variables cannot be used with the prevent_destroy lifecycle policy
# To overcome this limitation and still support infra__teardown_deletes_data = False
# we create two similar resource using a conditional on the for_each.
# Resource cdp_storage_delete_data is created when teardown_deletes_data = True
# Resource cdp_storage_retain_data is created when teardown_deletes_data = False
# References:
# * https://github.com/hashicorp/terraform/issues/22544#issuecomment-981575058
# * https://discuss.hashicorp.com/t/conditionally-create-resources-when-a-for-each-loop-is-involved/20841/9

resource "aws_s3_bucket" "cdp_storage_delete_data" {
for_each = var.teardown_deletes_data ? toset(var.storage_locations[*].bucket) : []

bucket = each.value
tags = merge(var.env_tags,{Name = each.value})

# Purge storage locations during teardown?
force_destroy = true
lifecycle {
# A Terraform destroy of this resource will result in an error message.
prevent_destroy = false
}
}
resource "aws_s3_bucket" "cdp_storage_retain_data" {
for_each = var.teardown_deletes_data ? [] : toset(var.storage_locations[*].bucket)

bucket = each.value
tags = merge(var.env_tags,{Name = each.value})

# Purge storage locations during teardown?
force_destroy = false
lifecycle {
# A Terraform destroy of this resource will result in an error message.
prevent_destroy = true
}
}

# Separate bucket acl resource definition
resource "aws_s3_bucket_acl" "cdp_storage_acl" {
for_each = var.teardown_deletes_data ? aws_s3_bucket.cdp_storage_delete_data : aws_s3_bucket.cdp_storage_retain_data

bucket = each.value.id
acl = "private"
}

# ------- AWS Buckets directory structures -------
resource "aws_s3_object" "cdp_storage_object" {

for_each = {for idx, object in var.storage_locations: idx => object}

# Bucket is either from 'cdp_storage_delete_data' or 'cdp_storage_retain_data' resource depending on teardown_deletes_data'
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

key = each.value.object
content_type = "application/x-directory"
}

# ------- Download Mirror Bucket -------
# TODO: Don't fail if Mirror Bucket already exists from non-Terraform code.
# resource "aws_s3_bucket" "cdp_utility_bucket" {
# bucket = var.utility_bucket
# acl = "private"
# force_destroy = true

# tags = merge(var.env_tags,{Name = var.utility_bucket})
# }
Loading