Skip to content

Commit

Permalink
Create public and private networks
Browse files Browse the repository at this point in the history
* This calculates the IP range for the 'private' and 'public' networks
  within the VPC. It does this by initially splitting the given vpc CIDR
  block into 2, and then calcalting the 'nebits' so that individual '/24'
  ranges can be calulated for subnets.
* A subnet for each given availability zone will be created, in both the
  'private' and 'public' ranges.
* A public route table will be created, along with an Internet Gateway,
  and a 0/0 route created for the gateway. The subnets within the
  'public' range will then be associated with this route table, allowing
  any resource launched within them to access the internet.
* A private route table will also be created. If 'public' networking is
  enabled, a NAT gateway will be created in one of the public subnets,
  and a route created to allow resources within the 'private' subnets
  access to the internet.
* Example subnets that will be created:
```
infrastructure_vpc_cidr_block                 = "10.0.0.0/16"
infrastructure_vpc_network_enable_public      = true
infrastructure_vpc_network_enable_private     = true
infrastructure_vpc_network_availability_zones = ["a", "b", "c"]

public subnets (Allocated "10.0.0.0/17"):
[
  "10.0.0.0/24",
  "10.0.1.0/24",
  "10.0.2.0/24"
]

private subnets (Allocated "10.0.128.0/17"):
[
  "10.0.128.0/24",
  "10.0.129.0/24",
  "10.0.130.0/24"
]
```
  • Loading branch information
Stretch96 committed Nov 22, 2023
1 parent 7ceeaa8 commit 2eb260e
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 1 deletion.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,31 @@ This project creates and manages resources within an AWS account for infrastruct
|------|------|
| [aws_athena_workgroup.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/athena_workgroup) | resource |
| [aws_cloudwatch_log_group.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_eip.infrastructure_nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
| [aws_flow_log.infrastructure_vpc_flow_logs_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/flow_log) | resource |
| [aws_flow_log.infrastructure_vpc_flow_logs_s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/flow_log) | resource |
| [aws_glue_catalog_database.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/glue_catalog_database) | resource |
| [aws_glue_catalog_table.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/glue_catalog_table) | resource |
| [aws_iam_role.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.infrastructure_vpc_flow_logs_allow_cloudwatch_rw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_internet_gateway.infrastructure_public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource |
| [aws_kms_alias.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
| [aws_kms_key.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_nat_gateway.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway) | resource |
| [aws_route.infrustructure_public_internet_gateway](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.private_nat_gateway](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route_table.infrastructure_private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
| [aws_route_table.infrastructure_public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
| [aws_route_table_association.infrastructure_private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.infrastructure_public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_s3_bucket.infrastructure_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
| [aws_s3_bucket_lifecycle_configuration.logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource |
| [aws_s3_bucket_policy.infrastructure_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
| [aws_s3_bucket_public_access_block.infrastructure_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [aws_s3_bucket_server_side_encryption_configuration.infrastructure_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
| [aws_s3_bucket_versioning.infrastructure_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
| [aws_subnet.infrastructure_private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.infrastructure_public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_vpc.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |

Expand All @@ -63,6 +74,9 @@ This project creates and manages resources within an AWS account for infrastruct
| <a name="input_infrastructure_vpc_flow_logs_s3_with_athena"></a> [infrastructure\_vpc\_flow\_logs\_s3\_with\_athena](#input\_infrastructure\_vpc\_flow\_logs\_s3\_with\_athena) | Enable VPC flow logs in infrastructure VPC to the S3 logs bucket. A compatible Glue table/database and Athena workgroup will also be created to allow querying the logs. | `bool` | n/a | yes |
| <a name="input_infrastructure_vpc_flow_logs_traffic_type"></a> [infrastructure\_vpc\_flow\_logs\_traffic\_type](#input\_infrastructure\_vpc\_flow\_logs\_traffic\_type) | Infrastructure VPC flow logs traffic type | `string` | n/a | yes |
| <a name="input_infrastructure_vpc_instance_tenancy"></a> [infrastructure\_vpc\_instance\_tenancy](#input\_infrastructure\_vpc\_instance\_tenancy) | Infrastructure VPC instance tenancy | `string` | n/a | yes |
| <a name="input_infrastructure_vpc_network_availability_zones"></a> [infrastructure\_vpc\_network\_availability\_zones](#input\_infrastructure\_vpc\_network\_availability\_zones) | A list of availability zone characters (eg. ["a", "b", "c"]) | `list(string)` | n/a | yes |
| <a name="input_infrastructure_vpc_network_enable_private"></a> [infrastructure\_vpc\_network\_enable\_private](#input\_infrastructure\_vpc\_network\_enable\_private) | Enable private networking on Infrastructure VPC. This will create subnets with a route to a NAT Gateway (If Public networking has been enabled) | `bool` | n/a | yes |
| <a name="input_infrastructure_vpc_network_enable_public"></a> [infrastructure\_vpc\_network\_enable\_public](#input\_infrastructure\_vpc\_network\_enable\_public) | Enable public networking on Infrastructure VPC. This will create subnets with a route to an Internet Gateway | `bool` | n/a | yes |
| <a name="input_project_name"></a> [project\_name](#input\_project\_name) | Project name to be used as a prefix for all resources | `string` | n/a | yes |

## Outputs
Expand Down
9 changes: 9 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ locals {
infrastructure_vpc_instance_tenancy = var.infrastructure_vpc_instance_tenancy
infrastructure_vpc_enable_network_address_usage_metrics = var.infrastructure_vpc_enable_network_address_usage_metrics
infrastructure_vpc_assign_generated_ipv6_cidr_block = var.infrastructure_vpc_assign_generated_ipv6_cidr_block
infrastructure_vpc_network_enable_public = local.infrastructure_vpc && var.infrastructure_vpc_network_enable_public
infrastructure_vpc_network_enable_private = local.infrastructure_vpc && var.infrastructure_vpc_network_enable_private
infrastructure_vpc_network_availability_zones = toset(sort(var.infrastructure_vpc_network_availability_zones))
infrastructure_vpc_network_public_cidr = cidrsubnet(local.infrastructure_vpc_cidr_block, 1, 0)
infrastructure_vpc_network_public_cidr_prefix = basename(local.infrastructure_vpc_network_public_cidr)
infrastructure_vpc_network_public_cidr_newbits = 24 - local.infrastructure_vpc_network_public_cidr_prefix
infrastructure_vpc_network_private_cidr = cidrsubnet(local.infrastructure_vpc_cidr_block, 1, 1)
infrastructure_vpc_network_private_cidr_prefix = basename(local.infrastructure_vpc_network_private_cidr)
infrastructure_vpc_network_private_cidr_newbits = 24 - local.infrastructure_vpc_network_private_cidr_prefix
infrastructure_vpc_flow_logs_cloudwatch_logs = var.infrastructure_vpc_flow_logs_cloudwatch_logs && local.infrastructure_vpc
infrastructure_vpc_flow_logs_s3_with_athena = var.infrastructure_vpc_flow_logs_s3_with_athena && local.infrastructure_vpc
infrastructure_vpc_flow_logs_s3_key_prefix = trim(var.infrastructure_vpc_flow_logs_s3_key_prefix, "/")
Expand Down
15 changes: 15 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,18 @@ variable "infrastructure_vpc_flow_logs_s3_key_prefix" {
description = "Flow Logs by default will go into the infrastructure S3 logs bucket. This is the key prefix used to isolate them from other logs"
type = string
}

variable "infrastructure_vpc_network_enable_public" {
description = "Enable public networking on Infrastructure VPC. This will create subnets with a route to an Internet Gateway"
type = bool
}

variable "infrastructure_vpc_network_enable_private" {
description = "Enable private networking on Infrastructure VPC. This will create subnets with a route to a NAT Gateway (If Public networking has been enabled)"
type = bool
}

variable "infrastructure_vpc_network_availability_zones" {
description = "A list of availability zone characters (eg. [\"a\", \"b\", \"c\"])"
type = list(string)
}
2 changes: 1 addition & 1 deletion vpc-infrastructure-flow-logs-cloudwatch.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ resource "aws_iam_role" "infrastructure_vpc_flow_logs" {
resource "aws_iam_role_policy" "infrastructure_vpc_flow_logs_allow_cloudwatch_rw" {
count = local.infrastructure_vpc_flow_logs_cloudwatch_logs ? 1 : 0

name = "${local.resource_prefix}-ecs-vpc-flow-logs-cloudwatch-logs-rw"
name = "${local.resource_prefix}-vpc-flow-logs-cloudwatch-logs-rw"
role = aws_iam_role.infrastructure_vpc_flow_logs[0].id
policy = templatefile("${path.root}/policies/cloudwatch-logs-rw.json.tpl", {})
}
Expand Down
59 changes: 59 additions & 0 deletions vpc-infrastructure-network-private.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
resource "aws_route_table" "infrastructure_private" {
count = local.infrastructure_vpc_network_enable_private ? 1 : 0

vpc_id = aws_vpc.infrastructure[0].id

tags = {
Name = "${local.resource_prefix}-infrastructure-private"
}
}

resource "aws_subnet" "infrastructure_private" {
for_each = local.infrastructure_vpc_network_enable_private ? local.infrastructure_vpc_network_availability_zones : []

vpc_id = aws_vpc.infrastructure[0].id
availability_zone = "${local.aws_region}${each.value}"

cidr_block = cidrsubnet(
local.infrastructure_vpc_network_private_cidr,
local.infrastructure_vpc_network_private_cidr_newbits,
index(tolist(local.infrastructure_vpc_network_availability_zones), each.value)
)

tags = {
Name = "${local.resource_prefix}-infrastructure-private-${each.value}"
}
}

resource "aws_route_table_association" "infrastructure_private" {
for_each = local.infrastructure_vpc_network_enable_private ? local.infrastructure_vpc_network_availability_zones : []

subnet_id = aws_subnet.infrastructure_private[each.value].id
route_table_id = aws_route_table.infrastructure_private[0].id
}

resource "aws_eip" "infrastructure_nat" {
count = local.infrastructure_vpc_network_enable_private && local.infrastructure_vpc_network_enable_public ? 1 : 0

domain = "vpc"

tags = {
Name = "${local.resource_prefix}-infrastructure-nat"
}
}

resource "aws_nat_gateway" "infrastructure" {
count = local.infrastructure_vpc_network_enable_private && local.infrastructure_vpc_network_enable_public ? 1 : 0

allocation_id = aws_eip.infrastructure_nat[0].id
subnet_id = aws_subnet.infrastructure_public[element(tolist(local.infrastructure_vpc_network_availability_zones), 0)].id
depends_on = [aws_internet_gateway.infrastructure_public]
}

resource "aws_route" "private_nat_gateway" {
count = local.infrastructure_vpc_network_enable_private && local.infrastructure_vpc_network_enable_public ? 1 : 0

route_table_id = aws_route_table.infrastructure_private[0].id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.infrastructure[0].id
}
51 changes: 51 additions & 0 deletions vpc-infrastructure-network-public.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
resource "aws_route_table" "infrastructure_public" {
count = local.infrastructure_vpc_network_enable_public ? 1 : 0

vpc_id = aws_vpc.infrastructure[0].id

tags = {
Name = "${local.resource_prefix}-infrastructure-public"
}
}

resource "aws_internet_gateway" "infrastructure_public" {
count = local.infrastructure_vpc_network_enable_public ? 1 : 0

vpc_id = aws_vpc.infrastructure[0].id

tags = {
Name = "${local.resource_prefix}-infrastructure-public"
}
}

resource "aws_route" "infrustructure_public_internet_gateway" {
count = local.infrastructure_vpc_network_enable_public ? 1 : 0

route_table_id = aws_route_table.infrastructure_public[0].id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.infrastructure_public[0].id
}

resource "aws_subnet" "infrastructure_public" {
for_each = local.infrastructure_vpc_network_enable_public ? local.infrastructure_vpc_network_availability_zones : []

vpc_id = aws_vpc.infrastructure[0].id
availability_zone = "${local.aws_region}${each.value}"

cidr_block = cidrsubnet(
local.infrastructure_vpc_network_public_cidr,
local.infrastructure_vpc_network_public_cidr_newbits,
index(tolist(local.infrastructure_vpc_network_availability_zones), each.value)
)

tags = {
Name = "${local.resource_prefix}-infrastructure-public-${each.value}"
}
}

resource "aws_route_table_association" "infrastructure_public" {
for_each = local.infrastructure_vpc_network_enable_public ? local.infrastructure_vpc_network_availability_zones : []

subnet_id = aws_subnet.infrastructure_public[each.value].id
route_table_id = aws_route_table.infrastructure_public[0].id
}

0 comments on commit 2eb260e

Please sign in to comment.