Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Everything and the kitchen sink vpc #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
21 changes: 21 additions & 0 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions development/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

234 changes: 234 additions & 0 deletions development/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
provider "aws" {
region = "us-west-2"
}

locals {
name = "complete-example"
region = "us-west-2"
tags = {
Owner = "Bjorn"
Environment = "development"
Name = "complete"
}
}

################################################################################
# VPC Module
################################################################################

module "vpc" {
source = "../modules/vpc/"

name = local.name
cidr = "20.10.0.0/16" # 10.0.0.0/8 is reserved for EC2-Classic

azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
private_subnets = ["20.10.1.0/24", "20.10.2.0/24", "20.10.3.0/24"]
public_subnets = ["20.10.11.0/24", "20.10.12.0/24", "20.10.13.0/24"]
database_subnets = ["20.10.21.0/24", "20.10.22.0/24", "20.10.23.0/24"]
elasticache_subnets = ["20.10.31.0/24", "20.10.32.0/24", "20.10.33.0/24"]
redshift_subnets = ["20.10.41.0/24", "20.10.42.0/24", "20.10.43.0/24"]
intra_subnets = ["20.10.51.0/24", "20.10.52.0/24", "20.10.53.0/24"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious about the choice of network here. 20.10.x.x is a publicly routable block. Choosing this as the internal network would shadow these public IPs, making them unreachable.

As a theoretical example: If I were to dig google.com and get the response 20.10.66.129 back, google.com would fail to load from any machine in this VPC. Now obviously this is probably NOT one of Google's addresses, but any services out there with public IPs in this range will be unreachable, leading to bizarre troubleshooting issues later.

To my knowledge, the only "safe" private IP blocks are 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. So 192.168.x.x is okay, but somebody out there might already have 192.160.x.x and we might want our servers to be able to reach them.

Ref: https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses


create_database_subnet_group = false

manage_default_route_table = true
default_route_table_tags = { DefaultRouteTable = true }

enable_dns_hostnames = true
enable_dns_support = true

enable_classiclink = true
enable_classiclink_dns_support = true

enable_nat_gateway = true
single_nat_gateway = true

customer_gateways = {
IP1 = {
bgp_asn = 65112
ip_address = "1.2.3.4"
device_name = "some_name"
},
IP2 = {
bgp_asn = 65112
ip_address = "5.6.7.8"
}
}

enable_vpn_gateway = true

enable_dhcp_options = true
dhcp_options_domain_name = "service.consul"
dhcp_options_domain_name_servers = ["127.0.0.1", "10.10.0.2"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recognize much of this is boilerplate, so this is directed at the boilerplate and not you:

dhcp_options_domain_name_servers needs further attention, since 10.10.0.2 probably isn't going to answer DNS requests for our network. 😅


# Default security group - ingress/egress rules cleared to deny all
manage_default_security_group = true
default_security_group_ingress = []
default_security_group_egress = []

# VPC Flow Logs (Cloudwatch log group and IAM role will be created)
enable_flow_log = true
create_flow_log_cloudwatch_log_group = true
create_flow_log_cloudwatch_iam_role = true
flow_log_max_aggregation_interval = 60

tags = local.tags
}

################################################################################
# VPC Endpoints Module
################################################################################

module "vpc_endpoints" {
source = "../modules/vpc-endpoints"

vpc_id = module.vpc.vpc_id
security_group_ids = [data.aws_security_group.default.id]

endpoints = {
s3 = {
service = "s3"
tags = { Name = "s3-vpc-endpoint" }
},
dynamodb = {
service = "dynamodb"
service_type = "Gateway"
route_table_ids = flatten([module.vpc.intra_route_table_ids, module.vpc.private_route_table_ids, module.vpc.public_route_table_ids])
policy = data.aws_iam_policy_document.dynamodb_endpoint_policy.json
tags = { Name = "dynamodb-vpc-endpoint" }
},
ssm = {
service = "ssm"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
ssmmessages = {
service = "ssmmessages"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
lambda = {
service = "lambda"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
ecs = {
service = "ecs"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
ecs_telemetry = {
service = "ecs-telemetry"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
ec2 = {
service = "ec2"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
ec2messages = {
service = "ec2messages"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
ecr_api = {
service = "ecr.api"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
policy = data.aws_iam_policy_document.generic_endpoint_policy.json
},
ecr_dkr = {
service = "ecr.dkr"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
policy = data.aws_iam_policy_document.generic_endpoint_policy.json
},
kms = {
service = "kms"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
codedeploy = {
service = "codedeploy"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
codedeploy_commands_secure = {
service = "codedeploy-commands-secure"
private_dns_enabled = true
subnet_ids = module.vpc.private_subnets
},
}

tags = merge(local.tags, {
Project = "Secret"
Endpoint = "true"
})
}
Copy link
Contributor

@beporter beporter Aug 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're angling towards [redacted] specifically, then I'm seconding that just about everything can come out of vpc_endpoints here. ecs is probably the only keeper? Maybe ecr_api?


module "vpc_endpoints_nocreate" {
source = "../modules/vpc-endpoints"

create = false
}

################################################################################
# Supporting Resources
################################################################################

data "aws_security_group" "default" {
name = "default"
vpc_id = module.vpc.vpc_id
}

# Data source used to avoid race condition
data "aws_vpc_endpoint_service" "dynamodb" {
service = "dynamodb"

filter {
name = "service-type"
values = ["Gateway"]
}
}

data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
statement {
effect = "Deny"
actions = ["dynamodb:*"]
resources = ["*"]

principals {
type = "*"
identifiers = ["*"]
}

condition {
test = "StringNotEquals"
variable = "aws:sourceVpce"

values = [data.aws_vpc_endpoint_service.dynamodb.id]
}
}
}

data "aws_iam_policy_document" "generic_endpoint_policy" {
statement {
effect = "Deny"
actions = ["*"]
resources = ["*"]

principals {
type = "*"
identifiers = ["*"]
}

condition {
test = "StringNotEquals"
variable = "aws:sourceVpce"

values = [data.aws_vpc_endpoint_service.dynamodb.id]
}
}
}
84 changes: 84 additions & 0 deletions development/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# VPC
output "vpc_id" {
description = "The ID of the VPC"
value = module.vpc.vpc_id
}

# Subnets
output "private_subnets" {
description = "List of IDs of private subnets"
value = module.vpc.private_subnets
}

output "public_subnets" {
description = "List of IDs of public subnets"
value = module.vpc.public_subnets
}

output "database_subnets" {
description = "List of IDs of database subnets"
value = module.vpc.database_subnets
}

output "elasticache_subnets" {
description = "List of IDs of elasticache subnets"
value = module.vpc.elasticache_subnets
}

output "redshift_subnets" {
description = "List of IDs of redshift subnets"
value = module.vpc.redshift_subnets
}

output "intra_subnets" {
description = "List of IDs of intra subnets"
value = module.vpc.intra_subnets
}

# NAT gateways
output "nat_public_ips" {
description = "List of public Elastic IPs created for AWS NAT Gateway"
value = module.vpc.nat_public_ips
}

# VPC endpoints
output "vpc_endpoint_ssm_id" {
description = "The ID of VPC endpoint for SSM"
value = module.vpc_endpoints.endpoints["ssm"].id
}

output "vpc_endpoint_ssm_network_interface_ids" {
description = "One or more network interfaces for the VPC Endpoint for SSM."
value = module.vpc_endpoints.endpoints["ssm"].network_interface_ids
}

output "vpc_endpoint_ssm_dns_entry" {
description = "The DNS entries for the VPC Endpoint for SSM."
value = module.vpc_endpoints.endpoints["ssm"].dns_entry
}

output "vpc_endpoint_lambda_id" {
description = "The ID of VPC endpoint for Lambda"
value = module.vpc_endpoints.endpoints["lambda"].id
}

output "vpc_endpoint_lambda_network_interface_ids" {
description = "One or more network interfaces for the VPC Endpoint for Lambda."
value = module.vpc_endpoints.endpoints["lambda"].network_interface_ids
}

output "vpc_endpoint_lambda_dns_entry" {
description = "The DNS entries for the VPC Endpoint for Lambda."
value = module.vpc_endpoints.endpoints["lambda"].dns_entry
}

# Customer Gateway
output "cgw_ids" {
description = "List of IDs of Customer Gateway"
value = module.vpc.cgw_ids
}

output "this_customer_gateway" {
description = "Map of Customer Gateway attributes"
value = module.vpc.this_customer_gateway
}
Empty file added development/variables.tf
Empty file.
10 changes: 10 additions & 0 deletions development/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 0.12.31"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.28"
}
}
}
Loading