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

Initial VPC Module And Example #9

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
9 changes: 9 additions & 0 deletions 12-vpc/vpc-main/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## Usage

To run this example you need to execute:

```sh
$ terraform init
$ terraform plan
$ terraform apply
```
15 changes: 15 additions & 0 deletions 12-vpc/vpc-main/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
provider "aws" {
region = var.region
}

module "vpc-main" {
source = "../../modules/12-vpc/vpc-main"

enable_dns_hostnames = true
enable_dns_support = true
enable_nat_gateway = true
single_nat_gateway = true
public_subnets = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]

}
84 changes: 84 additions & 0 deletions 12-vpc/vpc-main/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
output "vpc_id" {
description = "The ID of the VPC"
value = module.vpc-main.vpc_id
}

output "vpc_cidr_block" {
description = "The CIDR block of the VPC"
value = module.vpc-main.vpc_cidr_block
}

output "vpc_instance_tenancy" {
description = "Tenancy of instances spin up within VPC"
value = module.vpc-main.vpc_instance_tenancy
}

output "vpc_enable_dns_support" {
description = "Whether or not the VPC has DNS support"
value = module.vpc-main.vpc_enable_dns_support
}

output "vpc_enable_dns_hostnames" {
description = "Whether or not the VPC has DNS hostname support"
value = module.vpc-main.vpc_enable_dns_hostnames
}

output "vpc_main_route_table_id" {
description = "The ID of the main route table associated with this VPC"
value = module.vpc-main.vpc_main_route_table_id
}

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

output "private_subnet_arns" {
description = "List of ARNs of private subnets"
value = module.vpc-main.private_subnet_arns
}

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

output "public_subnet_arns" {
description = "List of ARNs of public subnets"
value = module.vpc-main.public_subnet_arns
}

output "public_route_table_ids" {
description = "List of IDs of public route tables"
value = module.vpc-main.public_route_table_ids
}

output "private_route_table_ids" {
description = "List of IDs of private route tables"
value = module.vpc-main.private_route_table_ids
}

output "nat_ids" {
description = "List of allocation ID of Elastic IPs created for AWS NAT Gateway"
value = module.vpc-main.nat_ids
}

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

output "natgw_ids" {
description = "List of NAT Gateway IDs"
value = module.vpc-main.natgw_ids
}

output "igw_id" {
description = "The ID of the Internet Gateway"
value = module.vpc-main.igw_id
}

output "name" {
description = "The name of the VPC specified as argument to this module"
value = module.vpc-main.name
}
9 changes: 9 additions & 0 deletions 12-vpc/vpc-main/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# These parameters have reasonable defaults.
# ---------------------------------------------------------------------------------------------------------------------

variable "region" {
type = string
default = "us-east-1"
}
10 changes: 10 additions & 0 deletions 12-vpc/vpc-main/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}
75 changes: 75 additions & 0 deletions modules/12-vpc/vpc-main/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
## Requirements

| Name | Version |
|------|---------|
| terraform | >= 1.0 |
| aws | >= 4.0 |

## Providers

| Name | Version |
|------|---------|
| aws | >= 4.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| aws_eip.nat | resource |
| aws_internet_gateway.igw | resource |
| aws_nat_gateway.nat_gateway | resource |
| aws_route.private_nat_gateway | resource |
| aws_route.public_internet_gateway | resource |
| aws_route_table.private | resource |
| aws_route_table.public | resource |
| aws_route_table_association.private | resource |
| aws_route_table_association.public | resource |
| aws_security_group.instance | resource |
| aws_security_group_rule.allow_server_http_inbound | resource |
| aws_security_group_rule.allow_server_outbound | resource |
| aws_subnet.private | resource |
| aws_subnet.public | resource |
| aws_vpc.vpc | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
cidr | (Optional) The IPv4 CIDR block for the VPC. CIDR can be explicitly set or it can be derived from IPAM using `ipv4_netmask_length` & `ipv4_ipam_pool_id` | `string` | `"10.0.0.0/16"` | no |
| create\_igw | Controls if an Internet Gateway is created for public subnets and the related routes that connect them. | `bool` | `true` | no |
| create\_vpc | Controls if VPC should be created (it affects almost all resources) | `bool` | `true` | no |
| enable\_dns\_hostnames | Should be true to enable DNS hostnames in the VPC | `bool` | `false` | no |
| enable\_dns\_support | Should be true to enable DNS support in the VPC | `bool` | `true` | no |
| enable\_nat\_gateway | Should be true if you want to provision NAT Gateways for each of your private networks | `bool` | `false` | no |
| instance\_tenancy | A tenancy option for instances launched into the VPC | `string` | `"default"` | no |
| name | Name to be used on all the resources as identifier | `string` | `""` | no |
| nat\_gateway\_destination\_cidr\_block | Used to pass a custom destination route for private NAT Gateway. If not specified, the default 0.0.0.0/0 is used as a destination route. | `string` | `"0.0.0.0/0"` | no |
| private\_subnets | A list of private subnets inside the VPC | `list(string)` | `[]` | no |
| public\_subnets | A list of public subnets inside the VPC | `list(string)` | `[]` | no |
| <single\_nat\_gateway | Should be true if you want to provision a single shared NAT Gateway across all of your private networks | `bool` | `false` | no |

## Outputs

| Name | Description |
|------|-------------|
| igw\_id | The ID of the Internet Gateway |
| name | The name of the VPC specified as argument to this module |
| nat\_ids | List of allocation ID of Elastic IPs created for AWS NAT Gateway |
| nat\_public\_ips | List of public Elastic IPs created for AWS NAT Gateway |
| natgw\_ids | List of NAT Gateway IDs |
| private\_route\_table\_ids | List of IDs of private route tables |
| private\_subnet\_arns | List of ARNs of private subnets |
| private\_subnets | List of IDs of private subnets |
| public\_route\_table\_ids | List of IDs of public route tables |
| public\_subnet\_arns | List of ARNs of public subnets |
| public\_subnets | List of IDs of public subnets |
| vpc\_cidr\_block | The CIDR block of the VPC |
| vpc\_enable\_dns\_hostnames | Whether or not the VPC has DNS hostname support |
| vpc\_enable\_dns\_support | Whether or not the VPC has DNS support |
| vpc\_id | The ID of the VPC |
| vpc\_instance\_tenancy | Tenancy of instances spin up within VPC |
| vpc\_main\_route\_table\_id | The ID of the main route table associated with this VPC |
172 changes: 172 additions & 0 deletions modules/12-vpc/vpc-main/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
locals {
http_port = 80
any_port = 0
any_protocol = "-1"
tcp_protocol = "tcp"
all_ips = ["0.0.0.0/0"]
}

resource "aws_vpc" "vpc" {
count = var.create_vpc ? 1 : 0

cidr_block = var.cidr

instance_tenancy = var.instance_tenancy
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support

}

resource "aws_security_group" "instance" {
name = "${var.name}-instance"
vpc_id = aws_vpc.vpc[0].id
}

resource "aws_security_group_rule" "allow_server_http_inbound" {
type = "ingress"
security_group_id = aws_security_group.instance.id

from_port = local.http_port
to_port = local.http_port
protocol = local.tcp_protocol
cidr_blocks = local.all_ips
}

resource "aws_security_group_rule" "allow_server_outbound" {
type = "egress"
security_group_id = aws_security_group.instance.id

from_port = local.any_port
to_port = local.any_port
protocol = local.tcp_protocol
cidr_blocks = local.all_ips
}

resource "aws_internet_gateway" "igw" {
count = var.create_vpc && var.create_igw && length(var.public_subnets) > 0 ? 1 : 0

vpc_id = aws_vpc.vpc[0].id

}

# ---------------------------------------------------------------------------------------------------------------------
# Public Routes
# ---------------------------------------------------------------------------------------------------------------------

resource "aws_route_table" "public" {
count = var.create_vpc && length(var.public_subnets) > 0 ? 1 : 0

vpc_id = aws_vpc.vpc[0].id

}

resource "aws_route" "public_internet_gateway" {
count = var.create_vpc && var.create_igw && length(var.public_subnets) > 0 ? 1 : 0

route_table_id = aws_route_table.public[0].id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw[0].id

timeouts {
create = "5m"
}
}

# ---------------------------------------------------------------------------------------------------------------------
# Private Routes
# There Are As Many Routing Tables As The Number of NAT Gateways
# ---------------------------------------------------------------------------------------------------------------------

resource "aws_route_table" "private" {
count = var.create_vpc && length(var.private_subnets) > 0 ? local.nat_gateway_count : 0

vpc_id = aws_vpc.vpc[0].id

}

# ---------------------------------------------------------------------------------------------------------------------
# Public Subnet
# ---------------------------------------------------------------------------------------------------------------------

resource "aws_subnet" "public" {
count = var.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0

vpc_id = aws_vpc.vpc[0].id
cidr_block = element(var.public_subnets, count.index)

}

# ---------------------------------------------------------------------------------------------------------------------
# Private Subnet
# ---------------------------------------------------------------------------------------------------------------------

resource "aws_subnet" "private" {
count = var.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0

vpc_id = aws_vpc.vpc[0].id
cidr_block = element(var.private_subnets, count.index)
}

# ---------------------------------------------------------------------------------------------------------------------
# NAT Gateway
# ---------------------------------------------------------------------------------------------------------------------

locals {
nat_gateway_count = var.single_nat_gateway ? 1 : length(var.private_subnets)
nat_gateway_ips = try(aws_eip.nat[*].id, [])
}

resource "aws_eip" "nat" {
count = var.create_vpc && var.enable_nat_gateway ? local.nat_gateway_count : 0

vpc = true

}

resource "aws_nat_gateway" "nat_gateway" {
count = var.create_vpc && var.enable_nat_gateway ? local.nat_gateway_count : 0

allocation_id = element(
local.nat_gateway_ips,
count.index,
)
subnet_id = element(
aws_subnet.public[*].id,
count.index,
)

depends_on = [aws_internet_gateway.igw]
}

resource "aws_route" "private_nat_gateway" {
count = var.create_vpc && var.enable_nat_gateway ? local.nat_gateway_count : 0

route_table_id = element(aws_route_table.private[*].id, count.index)
destination_cidr_block = var.nat_gateway_destination_cidr_block
nat_gateway_id = element(aws_nat_gateway.nat_gateway[*].id, count.index)

timeouts {
create = "10m"
}
}

# ---------------------------------------------------------------------------------------------------------------------
# Route Table Association
# ---------------------------------------------------------------------------------------------------------------------

resource "aws_route_table_association" "private" {
count = var.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0

subnet_id = element(aws_subnet.private[*].id, count.index)
route_table_id = element(
aws_route_table.private[*].id,
var.single_nat_gateway ? 0 : count.index,
)
}

resource "aws_route_table_association" "public" {
count = var.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0

subnet_id = element(aws_subnet.public[*].id, count.index)
route_table_id = aws_route_table.public[0].id
}
Loading