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 secondary CIDR block support #163

Merged
merged 8 commits into from
Sep 4, 2018
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ Terraform version 0.10.3 or newer is required for this module to work.
| redshift_subnet_tags | Additional tags for the redshift subnets | string | `<map>` | no |
| redshift_subnets | A list of redshift subnets | list | `<list>` | no |
| reuse_nat_ips | Should be true if you don't want EIPs to be created for your NAT Gateways and will instead pass them in via the 'external_nat_ip_ids' variable | string | `false` | no |
| secondary_cidr_blocks | List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool | string | `<list>` | no |
| single_nat_gateway | Should be true if you want to provision a single shared NAT Gateway across all of your private networks | string | `false` | no |
| tags | A map of tags to add to all resources | string | `<map>` | no |
| vpc_tags | Additional tags for the VPC | string | `<map>` | no |
Expand Down Expand Up @@ -280,6 +281,7 @@ Terraform version 0.10.3 or newer is required for this module to work.
| vpc_id | 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 |
| vpc_secondary_cidr_blocks | List of secondary CIDR blocks of the VPC |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Expand Down
32 changes: 32 additions & 0 deletions examples/secondary-cidr-blocks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Simple VPC with secondary CIDR blocks

Configuration in this directory creates set of VPC resources across multiple CIDR blocks.

There is a public and private subnet created per availability zone in addition to single NAT Gateway shared between all 3 availability zones.

## 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 |
|------|-------------|
| nat_public_ips | NAT gateways |
| private_subnets | Subnets |
| public_subnets | List of IDs of public subnets |
| vpc_cidr_block | CIDR blocks |
| vpc_id | VPC |
| vpc_secondary_cidr_blocks | List of secondary CIDR blocks of the VPC |

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

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

name = "secondary-cidr-blocks-example"

cidr = "10.0.0.0/16"
secondary_cidr_blocks = ["10.1.0.0/16", "10.2.0.0/16"]

azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
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

public_subnet_tags = {
Name = "overridden-name-public"
}

tags = {
Owner = "user"
Environment = "dev"
}

vpc_tags = {
Name = "vpc-name"
}
}
33 changes: 33 additions & 0 deletions examples/secondary-cidr-blocks/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# VPC
output "vpc_id" {
description = "The ID of the VPC"
value = "${module.vpc.vpc_id}"
}

# CIDR blocks
output "vpc_cidr_block" {
description = "The CIDR block of the VPC"
value = ["${module.vpc.vpc_cidr_block}"]
}

output "vpc_secondary_cidr_blocks" {
description = "List of secondary CIDR blocks of the VPC"
value = ["${module.vpc.vpc_secondary_cidr_blocks}"]
}

# 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}"]
}

# NAT gateways
output "nat_public_ips" {
description = "List of public Elastic IPs created for AWS NAT Gateway"
value = ["${module.vpc.nat_public_ips}"]
}
47 changes: 29 additions & 18 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ terraform {
locals {
max_subnet_length = "${max(length(var.private_subnets), length(var.elasticache_subnets), length(var.database_subnets), length(var.redshift_subnets))}"
nat_gateway_count = "${var.single_nat_gateway ? 1 : (var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length)}"

# Use `local.vpc_id` to give a hint to Terraform that subnets should be deleted before secondary CIDR blocks can be free!
vpc_id = "${element(concat(aws_vpc_ipv4_cidr_block_association.this.*.vpc_id, aws_vpc.this.*.id, list("")), 0)}"
}

######
Expand All @@ -22,6 +25,14 @@ resource "aws_vpc" "this" {
tags = "${merge(map("Name", format("%s", var.name)), var.vpc_tags, var.tags)}"
}

resource "aws_vpc_ipv4_cidr_block_association" "this" {
count = "${var.create_vpc && length(var.secondary_cidr_blocks) > 0 ? length(var.secondary_cidr_blocks) : 0}"

vpc_id = "${aws_vpc.this.id}"

cidr_block = "${element(var.secondary_cidr_blocks, count.index)}"
}

###################
# DHCP Options Set
###################
Expand All @@ -43,7 +54,7 @@ resource "aws_vpc_dhcp_options" "this" {
resource "aws_vpc_dhcp_options_association" "this" {
count = "${var.create_vpc && var.enable_dhcp_options ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
dhcp_options_id = "${aws_vpc_dhcp_options.this.id}"
}

Expand All @@ -53,7 +64,7 @@ resource "aws_vpc_dhcp_options_association" "this" {
resource "aws_internet_gateway" "this" {
count = "${var.create_vpc && length(var.public_subnets) > 0 ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(map("Name", format("%s", var.name)), var.igw_tags, var.tags)}"
}
Expand All @@ -64,7 +75,7 @@ resource "aws_internet_gateway" "this" {
resource "aws_route_table" "public" {
count = "${var.create_vpc && length(var.public_subnets) > 0 ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(map("Name", format("%s-public", var.name)), var.public_route_table_tags, var.tags)}"
}
Expand All @@ -88,7 +99,7 @@ resource "aws_route" "public_internet_gateway" {
resource "aws_route_table" "private" {
count = "${var.create_vpc && local.max_subnet_length > 0 ? local.nat_gateway_count : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(map("Name", (var.single_nat_gateway ? "${var.name}-private" : format("%s-private-%s", var.name, element(var.azs, count.index)))), var.private_route_table_tags, var.tags)}"

Expand All @@ -105,7 +116,7 @@ resource "aws_route_table" "private" {
resource "aws_route_table" "database" {
count = "${var.create_vpc && var.create_database_subnet_route_table && length(var.database_subnets) > 0 ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(var.tags, var.database_route_table_tags, map("Name", "${var.name}-database"))}"
}
Expand All @@ -116,7 +127,7 @@ resource "aws_route_table" "database" {
resource "aws_route_table" "redshift" {
count = "${var.create_vpc && var.create_redshift_subnet_route_table && length(var.redshift_subnets) > 0 ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(var.tags, var.redshift_route_table_tags, map("Name", "${var.name}-redshift"))}"
}
Expand All @@ -127,7 +138,7 @@ resource "aws_route_table" "redshift" {
resource "aws_route_table" "elasticache" {
count = "${var.create_vpc && var.create_elasticache_subnet_route_table && length(var.elasticache_subnets) > 0 ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(var.tags, var.elasticache_route_table_tags, map("Name", "${var.name}-elasticache"))}"
}
Expand All @@ -138,7 +149,7 @@ resource "aws_route_table" "elasticache" {
resource "aws_route_table" "intra" {
count = "${var.create_vpc && length(var.intra_subnets) > 0 ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(map("Name", "${var.name}-intra"), var.intra_route_table_tags, var.tags)}"
}
Expand All @@ -149,7 +160,7 @@ resource "aws_route_table" "intra" {
resource "aws_subnet" "public" {
count = "${var.create_vpc && length(var.public_subnets) > 0 && (!var.one_nat_gateway_per_az || length(var.public_subnets) >= length(var.azs)) ? length(var.public_subnets) : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
cidr_block = "${var.public_subnets[count.index]}"
availability_zone = "${element(var.azs, count.index)}"
map_public_ip_on_launch = "${var.map_public_ip_on_launch}"
Expand All @@ -163,7 +174,7 @@ resource "aws_subnet" "public" {
resource "aws_subnet" "private" {
count = "${var.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
cidr_block = "${var.private_subnets[count.index]}"
availability_zone = "${element(var.azs, count.index)}"

Expand All @@ -176,7 +187,7 @@ resource "aws_subnet" "private" {
resource "aws_subnet" "database" {
count = "${var.create_vpc && length(var.database_subnets) > 0 ? length(var.database_subnets) : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
cidr_block = "${var.database_subnets[count.index]}"
availability_zone = "${element(var.azs, count.index)}"

Expand All @@ -199,7 +210,7 @@ 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 = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
cidr_block = "${var.redshift_subnets[count.index]}"
availability_zone = "${element(var.azs, count.index)}"

Expand All @@ -222,7 +233,7 @@ 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 = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
cidr_block = "${var.elasticache_subnets[count.index]}"
availability_zone = "${element(var.azs, count.index)}"

Expand All @@ -243,7 +254,7 @@ 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 = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
cidr_block = "${var.intra_subnets[count.index]}"
availability_zone = "${element(var.azs, count.index)}"

Expand Down Expand Up @@ -308,7 +319,7 @@ data "aws_vpc_endpoint_service" "s3" {
resource "aws_vpc_endpoint" "s3" {
count = "${var.create_vpc && var.enable_s3_endpoint ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
service_name = "${data.aws_vpc_endpoint_service.s3.service_name}"
}

Expand Down Expand Up @@ -345,7 +356,7 @@ data "aws_vpc_endpoint_service" "dynamodb" {
resource "aws_vpc_endpoint" "dynamodb" {
count = "${var.create_vpc && var.enable_dynamodb_endpoint ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
service_name = "${data.aws_vpc_endpoint_service.dynamodb.service_name}"
}

Expand Down Expand Up @@ -421,15 +432,15 @@ resource "aws_route_table_association" "public" {
resource "aws_vpn_gateway" "this" {
count = "${var.create_vpc && var.enable_vpn_gateway ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"

tags = "${merge(map("Name", format("%s", var.name)), var.vpn_gateway_tags, var.tags)}"
}

resource "aws_vpn_gateway_attachment" "this" {
count = "${var.vpn_gateway_id != "" ? 1 : 0}"

vpc_id = "${aws_vpc.this.id}"
vpc_id = "${local.vpc_id}"
vpn_gateway_id = "${var.vpn_gateway_id}"
}

Expand Down
5 changes: 5 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ output "vpc_main_route_table_id" {
// value = "${element(concat(aws_vpc.this.*.ipv6_cidr_block, list("")), 0)}"
//}

output "vpc_secondary_cidr_blocks" {
description = "List of secondary CIDR blocks of the VPC"
value = ["${aws_vpc_ipv4_cidr_block_association.this.*.cidr_block}"]
}

# Subnets
output "private_subnets" {
description = "List of IDs of private subnets"
Expand Down
5 changes: 5 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ variable "assign_generated_ipv6_cidr_block" {
default = false
}

variable "secondary_cidr_blocks" {
description = "List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool"
default = []
}

variable "instance_tenancy" {
description = "A tenancy option for instances launched into the VPC"
default = "default"
Expand Down