From 2c854d512f26a20dc9d87ed346c188ba55a5017b Mon Sep 17 00:00:00 2001 From: jcastaldo08 Date: Thu, 30 Aug 2018 09:36:17 -0700 Subject: [PATCH 1/8] Add secondary CIDR block support using a local variable to derive the vpc id to ensure the CIDR block operations are applied before the CIDR operations --- README.md | 3 ++- main.tf | 45 +++++++++++++++++++++++++++------------------ variables.tf | 6 ++++++ 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 44571477d..0f5f69f6d 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,8 @@ Terraform version 0.10.3 or newer is required for this module to work. | assign_generated_ipv6_cidr_block | Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IP addresses, or the size of the CIDR block | string | `false` | no | | azs | A list of availability zones in the region | string | `` | no | | cidr | The CIDR block for the VPC. Default value is a valid CIDR, but not acceptable by AWS and should be overridden | string | `0.0.0.0/0` | no | -| create_database_subnet_group | Controls if database subnet group should be created | string | `true` | no | + secondary_cidr_blocks | A List of secondary CIDR blocks to add to the vpc. Will append the CIDR blocks before subnet operations are applied | string | `` | no | + create_database_subnet_group | Controls if database subnet group should be created | string | `true` | no | | create_database_subnet_route_table | Controls if separate route table for database should be created | string | `false` | no | | create_elasticache_subnet_route_table | Controls if separate route table for elasticache should be created | string | `false` | no | | create_redshift_subnet_route_table | Controls if separate route table for redshift should be created | string | `false` | no | diff --git a/main.tf b/main.tf index c1d3eaf75..4964ef913 100644 --- a/main.tf +++ b/main.tf @@ -5,6 +5,7 @@ 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)}" + vpc_id = "${length(var.secondary_cidr_blocks) > 0 ? element(concat(aws_vpc_ipv4_cidr_block_association.this.*.vpc_id, list("")), 0) : aws_vpc.this.id}" } ###### @@ -22,6 +23,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 = "${length(var.secondary_cidr_blocks)}" + + vpc_id = "${aws_vpc.this.id}" + + cidr_block = "${element(var.secondary_cidr_blocks, count.index)}" +} + ################### # DHCP Options Set ################### @@ -43,7 +52,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}" } @@ -53,7 +62,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)}" } @@ -64,7 +73,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)}" } @@ -88,7 +97,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)}" @@ -105,7 +114,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"))}" } @@ -116,7 +125,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"))}" } @@ -127,7 +136,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"))}" } @@ -138,7 +147,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)}" } @@ -149,7 +158,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}" @@ -163,7 +172,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)}" @@ -176,7 +185,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)}" @@ -199,7 +208,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)}" @@ -222,7 +231,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)}" @@ -243,7 +252,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)}" @@ -308,7 +317,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}" } @@ -345,7 +354,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}" } @@ -421,7 +430,7 @@ 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)}" } @@ -429,7 +438,7 @@ resource "aws_vpn_gateway" "this" { 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}" } diff --git a/variables.tf b/variables.tf index c5c753c9c..0faa4a010 100644 --- a/variables.tf +++ b/variables.tf @@ -18,6 +18,12 @@ variable "assign_generated_ipv6_cidr_block" { default = false } +variable "secondary_cidr_blocks" { + type = "list" + description = "Seceibdary 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" From f606f49d2f9b658629f009d6001b9d94146318c7 Mon Sep 17 00:00:00 2001 From: jcastaldo08 Date: Thu, 30 Aug 2018 12:01:29 -0700 Subject: [PATCH 2/8] Add secondary cidr block outputs to module output --- examples/secondary-cidr-blocks/README.md | 0 examples/secondary-cidr-blocks/main.tf | 0 examples/secondary-cidr-blocks/outputs.tf | 0 outputs.tf | 5 +++++ 4 files changed, 5 insertions(+) create mode 100644 examples/secondary-cidr-blocks/README.md create mode 100644 examples/secondary-cidr-blocks/main.tf create mode 100644 examples/secondary-cidr-blocks/outputs.tf diff --git a/examples/secondary-cidr-blocks/README.md b/examples/secondary-cidr-blocks/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/examples/secondary-cidr-blocks/main.tf b/examples/secondary-cidr-blocks/main.tf new file mode 100644 index 000000000..e69de29bb diff --git a/examples/secondary-cidr-blocks/outputs.tf b/examples/secondary-cidr-blocks/outputs.tf new file mode 100644 index 000000000..e69de29bb diff --git a/outputs.tf b/outputs.tf index 2fe5dca89..ee0de7e6a 100644 --- a/outputs.tf +++ b/outputs.tf @@ -231,6 +231,11 @@ output "default_vpc_cidr_block" { value = "${element(concat(aws_default_vpc.this.*.cidr_block, list("")), 0)}" } +output "vpc_secondary_cidr_blocks" { + description = "Secondary CIDR blocks of the VPC" + value = ["${aws_vpc_ipv4_cidr_block_association.this.*.cidr_block}"] +} + output "default_vpc_default_security_group_id" { description = "The ID of the security group created by default on VPC creation" value = "${element(concat(aws_default_vpc.this.*.default_security_group_id, list("")), 0)}" From 549842872e9e65bf6f86044c9e4f9f32b6702e37 Mon Sep 17 00:00:00 2001 From: jcastaldo08 Date: Thu, 30 Aug 2018 12:02:23 -0700 Subject: [PATCH 3/8] Add the wonderful examples from matthiasr's PR located at https://github.com/terraform-aws-modules/terraform-aws-vpc/pull/162 all credit goes to them for this wonderful example --- examples/secondary-cidr-blocks/README.md | 22 +++++++++++++++++ examples/secondary-cidr-blocks/main.tf | 25 +++++++++++++++++++ examples/secondary-cidr-blocks/outputs.tf | 29 +++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/examples/secondary-cidr-blocks/README.md b/examples/secondary-cidr-blocks/README.md index e69de29bb..44e9bcb0b 100644 --- a/examples/secondary-cidr-blocks/README.md +++ b/examples/secondary-cidr-blocks/README.md @@ -0,0 +1,22 @@ +# 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. + + ## 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_secondary_cidr_blocks | Secondary CIDR blocks | +| vpc_id | VPC | + diff --git a/examples/secondary-cidr-blocks/main.tf b/examples/secondary-cidr-blocks/main.tf index e69de29bb..a01142120 100644 --- a/examples/secondary-cidr-blocks/main.tf +++ b/examples/secondary-cidr-blocks/main.tf @@ -0,0 +1,25 @@ +provider "aws" { + region = "eu-west-1" +} +module "vpc" { + source = "../../" + name = "secondary-cidr-blocks-example" + cidr = "10.0.0.0/16" + secondary_cidrs = ["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" + } +} diff --git a/examples/secondary-cidr-blocks/outputs.tf b/examples/secondary-cidr-blocks/outputs.tf index e69de29bb..361071142 100644 --- a/examples/secondary-cidr-blocks/outputs.tf +++ b/examples/secondary-cidr-blocks/outputs.tf @@ -0,0 +1,29 @@ +# 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 = "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}"] +} From d66fadda4cd4ff743ed43dd36d919f836600165c Mon Sep 17 00:00:00 2001 From: jcastaldo08 Date: Thu, 30 Aug 2018 12:03:48 -0700 Subject: [PATCH 4/8] From copy and paste accidentally used variable name that differed from these variables --- examples/secondary-cidr-blocks/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/secondary-cidr-blocks/main.tf b/examples/secondary-cidr-blocks/main.tf index a01142120..e1d5aae94 100644 --- a/examples/secondary-cidr-blocks/main.tf +++ b/examples/secondary-cidr-blocks/main.tf @@ -5,7 +5,7 @@ module "vpc" { source = "../../" name = "secondary-cidr-blocks-example" cidr = "10.0.0.0/16" - secondary_cidrs = ["10.1.0.0/16", "10.2.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"] From f65c62dd67f4b8c260fd7a8a1121b56a0f656029 Mon Sep 17 00:00:00 2001 From: jcastaldo08 Date: Thu, 30 Aug 2018 14:40:44 -0700 Subject: [PATCH 5/8] Resolve typo in secondary_cidr_blocks --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 0faa4a010..36a38df18 100644 --- a/variables.tf +++ b/variables.tf @@ -20,7 +20,7 @@ variable "assign_generated_ipv6_cidr_block" { variable "secondary_cidr_blocks" { type = "list" - description = "Seceibdary CIDR blocks to associate with the VPC to extend the IP Address pool." + description = "Secondary CIDR blocks to associate with the VPC to extend the IP Address pool." default = [] } From e08058dc1ee66a505a3ada69510d650ad6cf1bb4 Mon Sep 17 00:00:00 2001 From: jcastaldo08 Date: Thu, 30 Aug 2018 14:43:30 -0700 Subject: [PATCH 6/8] Fixed README formatting --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0f5f69f6d..6e41de9ba 100644 --- a/README.md +++ b/README.md @@ -166,8 +166,8 @@ Terraform version 0.10.3 or newer is required for this module to work. | assign_generated_ipv6_cidr_block | Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IP addresses, or the size of the CIDR block | string | `false` | no | | azs | A list of availability zones in the region | string | `` | no | | cidr | The CIDR block for the VPC. Default value is a valid CIDR, but not acceptable by AWS and should be overridden | string | `0.0.0.0/0` | no | - secondary_cidr_blocks | A List of secondary CIDR blocks to add to the vpc. Will append the CIDR blocks before subnet operations are applied | string | `` | no | - create_database_subnet_group | Controls if database subnet group should be created | string | `true` | no | +| secondary_cidr_blocks | A List of secondary CIDR blocks to add to the vpc. Will append the CIDR blocks before subnet operations are applied | string | `` | no | +| create_database_subnet_group | Controls if database subnet group should be created | string | `true` | no | | create_database_subnet_route_table | Controls if separate route table for database should be created | string | `false` | no | | create_elasticache_subnet_route_table | Controls if separate route table for elasticache should be created | string | `false` | no | | create_redshift_subnet_route_table | Controls if separate route table for redshift should be created | string | `false` | no | From bcea34a42f62628d5cfe312262fe1e00507a3e14 Mon Sep 17 00:00:00 2001 From: Anton Babenko Date: Tue, 4 Sep 2018 14:36:05 +0200 Subject: [PATCH 7/8] Followups for #161 --- README.md | 3 +- examples/secondary-cidr-blocks/README.md | 30 +++++++++++------ examples/secondary-cidr-blocks/main.tf | 14 ++++++-- examples/secondary-cidr-blocks/outputs.tf | 6 +++- main.tf | 39 +++++++++++------------ outputs.tf | 10 +++--- variables.tf | 5 ++- 7 files changed, 64 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 6e41de9ba..e7406a36e 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,6 @@ Terraform version 0.10.3 or newer is required for this module to work. | assign_generated_ipv6_cidr_block | Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IP addresses, or the size of the CIDR block | string | `false` | no | | azs | A list of availability zones in the region | string | `` | no | | cidr | The CIDR block for the VPC. Default value is a valid CIDR, but not acceptable by AWS and should be overridden | string | `0.0.0.0/0` | no | -| secondary_cidr_blocks | A List of secondary CIDR blocks to add to the vpc. Will append the CIDR blocks before subnet operations are applied | string | `` | no | | create_database_subnet_group | Controls if database subnet group should be created | string | `true` | no | | create_database_subnet_route_table | Controls if separate route table for database should be created | string | `false` | no | | create_elasticache_subnet_route_table | Controls if separate route table for elasticache should be created | string | `false` | no | @@ -222,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 | `` | no | | redshift_subnets | A list of redshift subnets | 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 | `` | 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 | `` | no | | vpc_tags | Additional tags for the VPC | string | `` | no | @@ -281,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 | diff --git a/examples/secondary-cidr-blocks/README.md b/examples/secondary-cidr-blocks/README.md index 44e9bcb0b..6d7cade4d 100644 --- a/examples/secondary-cidr-blocks/README.md +++ b/examples/secondary-cidr-blocks/README.md @@ -1,22 +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 + +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. - - ## Outputs - | Name | Description | + +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. + + + +## 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_secondary_cidr_blocks | Secondary CIDR blocks | | vpc_id | VPC | +| vpc_secondary_cidr_blocks | List of secondary CIDR blocks of the VPC | + diff --git a/examples/secondary-cidr-blocks/main.tf b/examples/secondary-cidr-blocks/main.tf index e1d5aae94..e4cc43231 100644 --- a/examples/secondary-cidr-blocks/main.tf +++ b/examples/secondary-cidr-blocks/main.tf @@ -1,24 +1,32 @@ provider "aws" { region = "eu-west-1" } + module "vpc" { source = "../../" + name = "secondary-cidr-blocks-example" - cidr = "10.0.0.0/16" + + 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 + 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" } diff --git a/examples/secondary-cidr-blocks/outputs.tf b/examples/secondary-cidr-blocks/outputs.tf index 361071142..7cc6480d8 100644 --- a/examples/secondary-cidr-blocks/outputs.tf +++ b/examples/secondary-cidr-blocks/outputs.tf @@ -3,13 +3,15 @@ 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 = "Secondary CIDR blocks of the VPC" + description = "List of secondary CIDR blocks of the VPC" value = ["${module.vpc.vpc_secondary_cidr_blocks}"] } @@ -18,10 +20,12 @@ 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" diff --git a/main.tf b/main.tf index 4964ef913..30c11d0c4 100644 --- a/main.tf +++ b/main.tf @@ -5,7 +5,6 @@ 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)}" - vpc_id = "${length(var.secondary_cidr_blocks) > 0 ? element(concat(aws_vpc_ipv4_cidr_block_association.this.*.vpc_id, list("")), 0) : aws_vpc.this.id}" } ###### @@ -24,7 +23,7 @@ resource "aws_vpc" "this" { } resource "aws_vpc_ipv4_cidr_block_association" "this" { - count = "${length(var.secondary_cidr_blocks)}" + count = "${var.create_vpc && length(var.secondary_cidr_blocks) > 0 ? length(var.secondary_cidr_blocks) : 0}" vpc_id = "${aws_vpc.this.id}" @@ -52,7 +51,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" dhcp_options_id = "${aws_vpc_dhcp_options.this.id}" } @@ -62,7 +61,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" tags = "${merge(map("Name", format("%s", var.name)), var.igw_tags, var.tags)}" } @@ -73,7 +72,7 @@ resource "aws_internet_gateway" "this" { resource "aws_route_table" "public" { count = "${var.create_vpc && length(var.public_subnets) > 0 ? 1 : 0}" - vpc_id = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" tags = "${merge(map("Name", format("%s-public", var.name)), var.public_route_table_tags, var.tags)}" } @@ -97,7 +96,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.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)}" @@ -114,7 +113,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" tags = "${merge(var.tags, var.database_route_table_tags, map("Name", "${var.name}-database"))}" } @@ -125,7 +124,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" tags = "${merge(var.tags, var.redshift_route_table_tags, map("Name", "${var.name}-redshift"))}" } @@ -136,7 +135,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" tags = "${merge(var.tags, var.elasticache_route_table_tags, map("Name", "${var.name}-elasticache"))}" } @@ -147,7 +146,7 @@ resource "aws_route_table" "elasticache" { resource "aws_route_table" "intra" { count = "${var.create_vpc && length(var.intra_subnets) > 0 ? 1 : 0}" - vpc_id = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" tags = "${merge(map("Name", "${var.name}-intra"), var.intra_route_table_tags, var.tags)}" } @@ -158,7 +157,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.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}" @@ -172,7 +171,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" cidr_block = "${var.private_subnets[count.index]}" availability_zone = "${element(var.azs, count.index)}" @@ -185,7 +184,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" cidr_block = "${var.database_subnets[count.index]}" availability_zone = "${element(var.azs, count.index)}" @@ -208,7 +207,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" cidr_block = "${var.redshift_subnets[count.index]}" availability_zone = "${element(var.azs, count.index)}" @@ -231,7 +230,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" cidr_block = "${var.elasticache_subnets[count.index]}" availability_zone = "${element(var.azs, count.index)}" @@ -252,7 +251,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 = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" cidr_block = "${var.intra_subnets[count.index]}" availability_zone = "${element(var.azs, count.index)}" @@ -317,7 +316,7 @@ data "aws_vpc_endpoint_service" "s3" { resource "aws_vpc_endpoint" "s3" { count = "${var.create_vpc && var.enable_s3_endpoint ? 1 : 0}" - vpc_id = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" service_name = "${data.aws_vpc_endpoint_service.s3.service_name}" } @@ -354,7 +353,7 @@ data "aws_vpc_endpoint_service" "dynamodb" { resource "aws_vpc_endpoint" "dynamodb" { count = "${var.create_vpc && var.enable_dynamodb_endpoint ? 1 : 0}" - vpc_id = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" service_name = "${data.aws_vpc_endpoint_service.dynamodb.service_name}" } @@ -430,7 +429,7 @@ resource "aws_route_table_association" "public" { resource "aws_vpn_gateway" "this" { count = "${var.create_vpc && var.enable_vpn_gateway ? 1 : 0}" - vpc_id = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" tags = "${merge(map("Name", format("%s", var.name)), var.vpn_gateway_tags, var.tags)}" } @@ -438,7 +437,7 @@ resource "aws_vpn_gateway" "this" { resource "aws_vpn_gateway_attachment" "this" { count = "${var.vpn_gateway_id != "" ? 1 : 0}" - vpc_id = "${local.vpc_id}" + vpc_id = "${aws_vpc.this.id}" vpn_gateway_id = "${var.vpn_gateway_id}" } diff --git a/outputs.tf b/outputs.tf index ee0de7e6a..43393a652 100644 --- a/outputs.tf +++ b/outputs.tf @@ -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" @@ -231,11 +236,6 @@ output "default_vpc_cidr_block" { value = "${element(concat(aws_default_vpc.this.*.cidr_block, list("")), 0)}" } -output "vpc_secondary_cidr_blocks" { - description = "Secondary CIDR blocks of the VPC" - value = ["${aws_vpc_ipv4_cidr_block_association.this.*.cidr_block}"] -} - output "default_vpc_default_security_group_id" { description = "The ID of the security group created by default on VPC creation" value = "${element(concat(aws_default_vpc.this.*.default_security_group_id, list("")), 0)}" diff --git a/variables.tf b/variables.tf index 36a38df18..c21d2872b 100644 --- a/variables.tf +++ b/variables.tf @@ -19,9 +19,8 @@ variable "assign_generated_ipv6_cidr_block" { } variable "secondary_cidr_blocks" { - type = "list" - description = "Secondary CIDR blocks to associate with the VPC to extend the IP Address pool." - default = [] + description = "List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool" + default = [] } variable "instance_tenancy" { From de3ed2df8ee428232064c7919772906e45d584c3 Mon Sep 17 00:00:00 2001 From: Anton Babenko Date: Tue, 4 Sep 2018 14:50:19 +0200 Subject: [PATCH 8/8] Added local.vpc_id with description --- main.tf | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/main.tf b/main.tf index 30c11d0c4..6b41a57a5 100644 --- a/main.tf +++ b/main.tf @@ -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)}" } ###### @@ -51,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}" } @@ -61,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)}" } @@ -72,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)}" } @@ -96,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)}" @@ -113,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"))}" } @@ -124,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"))}" } @@ -135,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"))}" } @@ -146,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)}" } @@ -157,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}" @@ -171,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)}" @@ -184,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)}" @@ -207,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)}" @@ -230,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)}" @@ -251,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)}" @@ -316,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}" } @@ -353,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}" } @@ -429,7 +432,7 @@ 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)}" } @@ -437,7 +440,7 @@ resource "aws_vpn_gateway" "this" { 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}" }