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

Add IPv6 support #317

Merged
merged 10 commits into from
Sep 2, 2019
28 changes: 26 additions & 2 deletions README.md

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions examples/ipv6/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# VPC with IPv6 enabled

Configuration in this directory creates set of VPC resources with IPv6 enabled on VPC and subnets.

## Usage

To run this example you need to execute:

```bash
$ terraform init
$ terraform plan
$ terraform apply
```

Note that this example may create resources which can cost money (AWS Elastic IP, for example). Run `terraform destroy` when you don't need these resources.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Outputs

| Name | Description |
|------|-------------|
| ipv6\_association\_id | The IPv6 CIDR block |
| ipv6\_cidr\_block | The association ID for the IPv6 CIDR block |
| vpc\_id | The ID of the VPC |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
37 changes: 37 additions & 0 deletions examples/ipv6/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
provider "aws" {
region = "eu-west-1"
}

data "aws_availability_zones" "available" {}

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

name = "ipv6"

cidr = "10.0.0.0/16"

azs = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1]]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
database_subnets = ["10.0.103.0/24", "10.0.104.0/24"]

enable_nat_gateway = false

create_database_subnet_route_table = true
create_database_internet_gateway_route = true

enable_ipv6 = true
assign_ipv6_address_on_creation = true

private_subnet_assign_ipv6_address_on_creation = false

public_subnet_ipv6_prefixes = [0, 1]
private_subnet_ipv6_prefixes = [2, 3]
database_subnet_ipv6_prefixes = [4, 5]

tags = {
Owner = "user"
Environment = "dev"
}
}
15 changes: 15 additions & 0 deletions examples/ipv6/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# VPC
output "vpc_id" {
description = "The ID of the VPC"
value = module.vpc.vpc_id
}

output "ipv6_association_id" {
description = "The IPv6 CIDR block"
value = module.vpc.vpc_ipv6_cidr_block
}

output "ipv6_cidr_block" {
description = "The association ID for the IPv6 CIDR block"
value = module.vpc.vpc_ipv6_association_id
}
2 changes: 1 addition & 1 deletion examples/network-acls/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module "vpc" {

private_dedicated_network_acl = true

assign_generated_ipv6_cidr_block = true
enable_ipv6 = true

enable_nat_gateway = false
single_nat_gateway = true
Expand Down
7 changes: 4 additions & 3 deletions examples/secondary-cidr-blocks/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ module "vpc" {
private_subnets = ["10.0.1.0/24", "10.1.2.0/24", "10.2.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.1.102.0/24", "10.2.103.0/24"]

assign_generated_ipv6_cidr_block = true
enable_nat_gateway = true
single_nat_gateway = true
enable_ipv6 = true

enable_nat_gateway = true
single_nat_gateway = true

public_subnet_tags = {
Name = "overridden-name-public"
Expand Down
2 changes: 1 addition & 1 deletion examples/simple-vpc/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module "vpc" {
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

assign_generated_ipv6_cidr_block = true
enable_ipv6 = true

enable_nat_gateway = true
single_nat_gateway = true
Expand Down
92 changes: 72 additions & 20 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ resource "aws_vpc" "this" {
instance_tenancy = var.instance_tenancy
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support
assign_generated_ipv6_cidr_block = var.assign_generated_ipv6_cidr_block
assign_generated_ipv6_cidr_block = var.enable_ipv6

tags = merge(
{
Expand Down Expand Up @@ -95,6 +95,12 @@ resource "aws_internet_gateway" "this" {
)
}

resource "aws_egress_only_internet_gateway" "this" {
count = var.create_vpc && var.enable_ipv6 && local.max_subnet_length > 0 ? 1 : 0

vpc_id = local.vpc_id
}

################
# Publiс routes
################
Expand Down Expand Up @@ -124,6 +130,14 @@ resource "aws_route" "public_internet_gateway" {
}
}

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

route_table_id = aws_route_table.public[0].id
destination_ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.this[0].id
}

#################
# Private routes
# There are as many routing tables as the number of NAT gateways
Expand Down Expand Up @@ -193,6 +207,18 @@ resource "aws_route" "database_nat_gateway" {
}
}

resource "aws_route" "database_ipv6_egress" {
count = var.create_vpc && var.enable_ipv6 && var.create_database_subnet_route_table && length(var.database_subnets) > 0 && var.create_database_internet_gateway_route ? 1 : 0

route_table_id = aws_route_table.database[0].id
destination_ipv6_cidr_block = "::/0"
egress_only_gateway_id = aws_egress_only_internet_gateway.this[0].id

timeouts {
create = "5m"
}
}

#################
# Redshift routes
#################
Expand Down Expand Up @@ -250,10 +276,13 @@ resource "aws_route_table" "intra" {
resource "aws_subnet" "public" {
count = var.create_vpc && length(var.public_subnets) > 0 && (false == var.one_nat_gateway_per_az || length(var.public_subnets) >= length(var.azs)) ? length(var.public_subnets) : 0

vpc_id = local.vpc_id
cidr_block = element(concat(var.public_subnets, [""]), count.index)
availability_zone = element(var.azs, count.index)
map_public_ip_on_launch = var.map_public_ip_on_launch
vpc_id = local.vpc_id
cidr_block = element(concat(var.public_subnets, [""]), count.index)
availability_zone = element(var.azs, count.index)
map_public_ip_on_launch = var.map_public_ip_on_launch
assign_ipv6_address_on_creation = var.public_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.public_subnet_assign_ipv6_address_on_creation

ipv6_cidr_block = var.enable_ipv6 && length(var.public_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.public_subnet_ipv6_prefixes[count.index]) : null

tags = merge(
{
Expand All @@ -274,9 +303,12 @@ resource "aws_subnet" "public" {
resource "aws_subnet" "private" {
count = var.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0

vpc_id = local.vpc_id
cidr_block = var.private_subnets[count.index]
availability_zone = element(var.azs, count.index)
vpc_id = local.vpc_id
cidr_block = var.private_subnets[count.index]
availability_zone = element(var.azs, count.index)
assign_ipv6_address_on_creation = var.private_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.private_subnet_assign_ipv6_address_on_creation

ipv6_cidr_block = var.enable_ipv6 && length(var.private_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.private_subnet_ipv6_prefixes[count.index]) : null

tags = merge(
{
Expand All @@ -297,9 +329,12 @@ resource "aws_subnet" "private" {
resource "aws_subnet" "database" {
count = var.create_vpc && length(var.database_subnets) > 0 ? length(var.database_subnets) : 0

vpc_id = local.vpc_id
cidr_block = var.database_subnets[count.index]
availability_zone = element(var.azs, count.index)
vpc_id = local.vpc_id
cidr_block = var.database_subnets[count.index]
availability_zone = element(var.azs, count.index)
assign_ipv6_address_on_creation = var.database_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.database_subnet_assign_ipv6_address_on_creation

ipv6_cidr_block = var.enable_ipv6 && length(var.database_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.database_subnet_ipv6_prefixes[count.index]) : null

tags = merge(
{
Expand Down Expand Up @@ -336,9 +371,12 @@ resource "aws_db_subnet_group" "database" {
resource "aws_subnet" "redshift" {
count = var.create_vpc && length(var.redshift_subnets) > 0 ? length(var.redshift_subnets) : 0

vpc_id = local.vpc_id
cidr_block = var.redshift_subnets[count.index]
availability_zone = element(var.azs, count.index)
vpc_id = local.vpc_id
cidr_block = var.redshift_subnets[count.index]
availability_zone = element(var.azs, count.index)
assign_ipv6_address_on_creation = var.redshift_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.redshift_subnet_assign_ipv6_address_on_creation

ipv6_cidr_block = var.enable_ipv6 && length(var.redshift_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.redshift_subnet_ipv6_prefixes[count.index]) : null

tags = merge(
{
Expand Down Expand Up @@ -375,9 +413,12 @@ resource "aws_redshift_subnet_group" "redshift" {
resource "aws_subnet" "elasticache" {
count = var.create_vpc && length(var.elasticache_subnets) > 0 ? length(var.elasticache_subnets) : 0

vpc_id = local.vpc_id
cidr_block = var.elasticache_subnets[count.index]
availability_zone = element(var.azs, count.index)
vpc_id = local.vpc_id
cidr_block = var.elasticache_subnets[count.index]
availability_zone = element(var.azs, count.index)
assign_ipv6_address_on_creation = var.elasticache_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.elasticache_subnet_assign_ipv6_address_on_creation

ipv6_cidr_block = var.enable_ipv6 && length(var.elasticache_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.elasticache_subnet_ipv6_prefixes[count.index]) : null

tags = merge(
{
Expand Down Expand Up @@ -406,9 +447,12 @@ resource "aws_elasticache_subnet_group" "elasticache" {
resource "aws_subnet" "intra" {
count = var.create_vpc && length(var.intra_subnets) > 0 ? length(var.intra_subnets) : 0

vpc_id = local.vpc_id
cidr_block = var.intra_subnets[count.index]
availability_zone = element(var.azs, count.index)
vpc_id = local.vpc_id
cidr_block = var.intra_subnets[count.index]
availability_zone = element(var.azs, count.index)
assign_ipv6_address_on_creation = var.intra_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.intra_subnet_assign_ipv6_address_on_creation

ipv6_cidr_block = var.enable_ipv6 && length(var.intra_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.intra_subnet_ipv6_prefixes[count.index]) : null

tags = merge(
{
Expand Down Expand Up @@ -824,6 +868,14 @@ resource "aws_route" "private_nat_gateway" {
}
}

resource "aws_route" "private_ipv6_egress" {
count = var.enable_ipv6 ? length(var.private_subnets) : 0

route_table_id = element(aws_route_table.private.*.id, count.index)
destination_ipv6_cidr_block = "::/0"
egress_only_gateway_id = element(aws_egress_only_internet_gateway.this.*.id, 0)
}

######################
# VPC Endpoint for S3
######################
Expand Down
Loading