Commit 07654cff authored by Anton Babenko's avatar Anton Babenko Committed by GitHub

Added possibility to create VPC conditionally (#74)

* Added possibility to create VPC conditionally

* Added editorconfig and pre-commit hooks
parent 2985eba4
......@@ -10,9 +10,9 @@ jobs:
<<: *terraform
steps:
- checkout
- run:
name: Add github.com to ~/.ssh/known_hosts
command: mkdir ~/.ssh && ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
# - run:
# name: Add github.com to ~/.ssh/known_hosts
# command: mkdir ~/.ssh && ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
- run:
name: terraform init
command: terraform init -input=false
......
# EditorConfig is awesome: http://EditorConfig.org
# Uses editorconfig to maintain consistent coding styles
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true
[*.{tf,tfvars}]
indent_size = 2
indent_style = space
[*.md]
max_line_length = 0
trim_trailing_whitespace = false
[Makefile]
tab_width = 2
indent_style = tab
[COMMIT_EDITMSG]
max_line_length = 0
\ No newline at end of file
repos:
- repo: git://github.com/antonbabenko/pre-commit-terraform
sha: v1.4.0
hooks:
- id: terraform_fmt
- repo: git://github.com/pre-commit/pre-commit-hooks
sha: v1.2.0
hooks:
- id: check-merge-conflict
......@@ -19,16 +19,13 @@ These types of resources are supported:
* [ElastiCache Subnet Group](https://www.terraform.io/docs/providers/aws/r/elasticache_subnet_group.html)
* [Redshift Subnet Group](https://www.terraform.io/docs/providers/aws/r/redshift_subnet_group.html)
* [DHCP Options Set](https://www.terraform.io/docs/providers/aws/r/vpc_dhcp_options.html)
* [Main VPC Routing Table](https://www.terraform.io/docs/providers/aws/r/main_route_table_assoc.html)
* [Default VPC Routing Table](https://www.terraform.io/docs/providers/aws/r/default_route_table.html)
Usage
-----
```hcl
provider "aws" {
version = "~> 1.0.0"
region = "eu-west-1"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
......@@ -85,6 +82,21 @@ Note that in the example we allocate 3 IPs because we will be provisioning 3 NAT
If, on the other hand, `single_nat_gateway = true`, then `aws_eip.nat` would only need to allocate 1 IP.
Passing the IPs into the module is done by setting two variables `reuse_nat_ips = true` and `external_nat_ip_ids = ["${aws_eip.nat.*.id}"]`.
Conditional creation
--------------------
Sometimes you need to have a way to create VPC resources conditionally but Terraform does not allow to use `count` inside `module` block, so the solution is to specify argument `create_vpc`.
```hcl
# This VPC will not be created
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
create_vpc = false
# ... omitted
}
```
Terraform version
-----------------
......
......@@ -2,10 +2,16 @@ terraform {
required_version = ">= 0.10.3" # introduction of Local Values configuration language feature
}
locals {
max_subnet_length = "${max(length(var.private_subnets), length(var.elasticache_subnets), length(var.database_subnets), length(var.redshift_subnets))}"
}
######
# VPC
######
resource "aws_vpc" "this" {
count = "${var.create_vpc ? 1 : 0}"
cidr_block = "${var.cidr}"
instance_tenancy = "${var.instance_tenancy}"
enable_dns_hostnames = "${var.enable_dns_hostnames}"
......@@ -18,7 +24,7 @@ resource "aws_vpc" "this" {
# DHCP Options Set
###################
resource "aws_vpc_dhcp_options" "this" {
count = "${var.enable_dhcp_options ? 1 : 0}"
count = "${var.create_vpc && var.enable_dhcp_options ? 1 : 0}"
domain_name = "${var.dhcp_options_domain_name}"
domain_name_servers = "${var.dhcp_options_domain_name_servers}"
......@@ -33,7 +39,7 @@ resource "aws_vpc_dhcp_options" "this" {
# DHCP Options Set Association
###############################
resource "aws_vpc_dhcp_options_association" "this" {
count = "${var.enable_dhcp_options ? 1 : 0}"
count = "${var.create_vpc && var.enable_dhcp_options ? 1 : 0}"
vpc_id = "${aws_vpc.this.id}"
dhcp_options_id = "${aws_vpc_dhcp_options.this.id}"
......@@ -43,7 +49,7 @@ resource "aws_vpc_dhcp_options_association" "this" {
# Internet Gateway
###################
resource "aws_internet_gateway" "this" {
count = "${length(var.public_subnets) > 0 ? 1 : 0}"
count = "${var.create_vpc && length(var.public_subnets) > 0 ? 1 : 0}"
vpc_id = "${aws_vpc.this.id}"
......@@ -54,7 +60,7 @@ resource "aws_internet_gateway" "this" {
# Publiс routes
################
resource "aws_route_table" "public" {
count = "${length(var.public_subnets) > 0 ? 1 : 0}"
count = "${var.create_vpc && length(var.public_subnets) > 0 ? 1 : 0}"
vpc_id = "${aws_vpc.this.id}"
propagating_vgws = ["${var.public_propagating_vgws}"]
......@@ -63,7 +69,7 @@ resource "aws_route_table" "public" {
}
resource "aws_route" "public_internet_gateway" {
count = "${length(var.public_subnets) > 0 ? 1 : 0}"
count = "${var.create_vpc && length(var.public_subnets) > 0 ? 1 : 0}"
route_table_id = "${aws_route_table.public.id}"
destination_cidr_block = "0.0.0.0/0"
......@@ -72,10 +78,10 @@ resource "aws_route" "public_internet_gateway" {
#################
# Private routes
# There are so many route-tables as the largest amount of subnets of each type (really?)
# There are so many routing tables as the largest amount of subnets of each type (really?)
#################
resource "aws_route_table" "private" {
count = "${max(length(var.private_subnets), length(var.elasticache_subnets), length(var.database_subnets), length(var.redshift_subnets))}"
count = "${var.create_vpc && local.max_subnet_length > 0 ? local.max_subnet_length : 0}"
vpc_id = "${aws_vpc.this.id}"
propagating_vgws = ["${var.private_propagating_vgws}"]
......@@ -93,7 +99,7 @@ resource "aws_route_table" "private" {
# Public subnet
################
resource "aws_subnet" "public" {
count = "${length(var.public_subnets)}"
count = "${var.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0}"
vpc_id = "${aws_vpc.this.id}"
cidr_block = "${var.public_subnets[count.index]}"
......@@ -107,7 +113,7 @@ resource "aws_subnet" "public" {
# Private subnet
#################
resource "aws_subnet" "private" {
count = "${length(var.private_subnets)}"
count = "${var.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0}"
vpc_id = "${aws_vpc.this.id}"
cidr_block = "${var.private_subnets[count.index]}"
......@@ -120,7 +126,7 @@ resource "aws_subnet" "private" {
# Database subnet
##################
resource "aws_subnet" "database" {
count = "${length(var.database_subnets)}"
count = "${var.create_vpc && length(var.database_subnets) > 0 ? length(var.database_subnets) : 0}"
vpc_id = "${aws_vpc.this.id}"
cidr_block = "${var.database_subnets[count.index]}"
......@@ -130,7 +136,7 @@ resource "aws_subnet" "database" {
}
resource "aws_db_subnet_group" "database" {
count = "${length(var.database_subnets) > 0 && var.create_database_subnet_group ? 1 : 0}"
count = "${var.create_vpc && length(var.database_subnets) > 0 && var.create_database_subnet_group ? 1 : 0}"
name = "${lower(var.name)}"
description = "Database subnet group for ${var.name}"
......@@ -143,7 +149,7 @@ resource "aws_db_subnet_group" "database" {
# Redshift subnet
##################
resource "aws_subnet" "redshift" {
count = "${length(var.redshift_subnets)}"
count = "${var.create_vpc && length(var.redshift_subnets) > 0 ? length(var.redshift_subnets) : 0}"
vpc_id = "${aws_vpc.this.id}"
cidr_block = "${var.redshift_subnets[count.index]}"
......@@ -153,7 +159,7 @@ resource "aws_subnet" "redshift" {
}
resource "aws_redshift_subnet_group" "redshift" {
count = "${length(var.redshift_subnets) > 0 ? 1 : 0}"
count = "${var.create_vpc && length(var.redshift_subnets) > 0 ? 1 : 0}"
name = "${var.name}"
description = "Redshift subnet group for ${var.name}"
......@@ -166,7 +172,7 @@ resource "aws_redshift_subnet_group" "redshift" {
# ElastiCache subnet
#####################
resource "aws_subnet" "elasticache" {
count = "${length(var.elasticache_subnets)}"
count = "${var.create_vpc && length(var.elasticache_subnets) > 0 ? length(var.elasticache_subnets) : 0}"
vpc_id = "${aws_vpc.this.id}"
cidr_block = "${var.elasticache_subnets[count.index]}"
......@@ -176,7 +182,7 @@ resource "aws_subnet" "elasticache" {
}
resource "aws_elasticache_subnet_group" "elasticache" {
count = "${length(var.elasticache_subnets) > 0 ? 1 : 0}"
count = "${var.create_vpc && length(var.elasticache_subnets) > 0 ? 1 : 0}"
name = "${var.name}"
description = "ElastiCache subnet group for ${var.name}"
......@@ -199,7 +205,7 @@ locals {
}
resource "aws_eip" "nat" {
count = "${(var.enable_nat_gateway && !var.reuse_nat_ips) ? (var.single_nat_gateway ? 1 : length(var.azs)) : 0}"
count = "${var.create_vpc && (var.enable_nat_gateway && !var.reuse_nat_ips) ? (var.single_nat_gateway ? 1 : length(var.azs)) : 0}"
vpc = true
......@@ -207,7 +213,7 @@ resource "aws_eip" "nat" {
}
resource "aws_nat_gateway" "this" {
count = "${var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.azs)) : 0}"
count = "${var.create_vpc && var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.azs)) : 0}"
allocation_id = "${element(local.nat_gateway_ips, (var.single_nat_gateway ? 0 : count.index))}"
subnet_id = "${element(aws_subnet.public.*.id, (var.single_nat_gateway ? 0 : count.index))}"
......@@ -218,7 +224,7 @@ resource "aws_nat_gateway" "this" {
}
resource "aws_route" "private_nat_gateway" {
count = "${var.enable_nat_gateway ? length(var.private_subnets) : 0}"
count = "${var.create_vpc && var.enable_nat_gateway ? length(var.private_subnets) : 0}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
destination_cidr_block = "0.0.0.0/0"
......@@ -229,27 +235,27 @@ resource "aws_route" "private_nat_gateway" {
# VPC Endpoint for S3
######################
data "aws_vpc_endpoint_service" "s3" {
count = "${var.enable_s3_endpoint}"
count = "${var.create_vpc && var.enable_s3_endpoint ? 1 : 0}"
service = "s3"
}
resource "aws_vpc_endpoint" "s3" {
count = "${var.enable_s3_endpoint}"
count = "${var.create_vpc && var.enable_s3_endpoint ? 1 : 0}"
vpc_id = "${aws_vpc.this.id}"
service_name = "${data.aws_vpc_endpoint_service.s3.service_name}"
}
resource "aws_vpc_endpoint_route_table_association" "private_s3" {
count = "${var.enable_s3_endpoint ? length(var.private_subnets) : 0}"
count = "${var.create_vpc && var.enable_s3_endpoint ? length(var.private_subnets) : 0}"
vpc_endpoint_id = "${aws_vpc_endpoint.s3.id}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
}
resource "aws_vpc_endpoint_route_table_association" "public_s3" {
count = "${var.enable_s3_endpoint ? 1 : 0}"
count = "${var.create_vpc && var.enable_s3_endpoint ? 1 : 0}"
vpc_endpoint_id = "${aws_vpc_endpoint.s3.id}"
route_table_id = "${aws_route_table.public.id}"
......@@ -259,27 +265,27 @@ resource "aws_vpc_endpoint_route_table_association" "public_s3" {
# VPC Endpoint for DynamoDB
############################
data "aws_vpc_endpoint_service" "dynamodb" {
count = "${var.enable_dynamodb_endpoint}"
count = "${var.create_vpc && var.enable_dynamodb_endpoint ? 1 : 0}"
service = "dynamodb"
}
resource "aws_vpc_endpoint" "dynamodb" {
count = "${var.enable_dynamodb_endpoint}"
count = "${var.create_vpc && var.enable_dynamodb_endpoint ? 1 : 0}"
vpc_id = "${aws_vpc.this.id}"
service_name = "${data.aws_vpc_endpoint_service.dynamodb.service_name}"
}
resource "aws_vpc_endpoint_route_table_association" "private_dynamodb" {
count = "${var.enable_dynamodb_endpoint ? length(var.private_subnets) : 0}"
count = "${var.create_vpc && var.enable_dynamodb_endpoint ? length(var.private_subnets) : 0}"
vpc_endpoint_id = "${aws_vpc_endpoint.dynamodb.id}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
}
resource "aws_vpc_endpoint_route_table_association" "public_dynamodb" {
count = "${var.enable_dynamodb_endpoint ? length(var.public_subnets) : 0}"
count = "${var.create_vpc && var.enable_dynamodb_endpoint ? length(var.public_subnets) : 0}"
vpc_endpoint_id = "${aws_vpc_endpoint.dynamodb.id}"
route_table_id = "${aws_route_table.public.id}"
......@@ -289,35 +295,35 @@ resource "aws_vpc_endpoint_route_table_association" "public_dynamodb" {
# Route table association
##########################
resource "aws_route_table_association" "private" {
count = "${length(var.private_subnets)}"
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, count.index)}"
}
resource "aws_route_table_association" "database" {
count = "${length(var.database_subnets)}"
count = "${var.create_vpc && length(var.database_subnets) > 0 ? length(var.database_subnets) : 0}"
subnet_id = "${element(aws_subnet.database.*.id, count.index)}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
}
resource "aws_route_table_association" "redshift" {
count = "${length(var.redshift_subnets)}"
count = "${var.create_vpc && length(var.redshift_subnets) > 0 ? length(var.redshift_subnets) : 0}"
subnet_id = "${element(aws_subnet.redshift.*.id, count.index)}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
}
resource "aws_route_table_association" "elasticache" {
count = "${length(var.elasticache_subnets)}"
count = "${var.create_vpc && length(var.elasticache_subnets) > 0 ? length(var.elasticache_subnets) : 0}"
subnet_id = "${element(aws_subnet.elasticache.*.id, count.index)}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
}
resource "aws_route_table_association" "public" {
count = "${length(var.public_subnets)}"
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.id}"
......@@ -327,7 +333,7 @@ resource "aws_route_table_association" "public" {
# VPN Gateway
##############
resource "aws_vpn_gateway" "this" {
count = "${var.enable_vpn_gateway ? 1 : 0}"
count = "${var.create_vpc && var.enable_vpn_gateway ? 1 : 0}"
vpc_id = "${aws_vpc.this.id}"
......@@ -338,12 +344,16 @@ resource "aws_vpn_gateway" "this" {
# Defaults
###########
resource "aws_default_route_table" "default" {
count = "${var.create_vpc ? 1 : 0}"
default_route_table_id = "${aws_vpc.this.default_route_table_id}"
tags = "${merge(var.tags, var.default_route_table_tags, map("Name", format("%s-default", var.name)))}"
}
resource "aws_main_route_table_association" "default" {
count = "${var.create_vpc ? 1 : 0}"
vpc_id = "${aws_vpc.this.id}"
route_table_id = "${aws_default_route_table.default.default_route_table_id}"
}
# VPC
output "vpc_id" {
description = "The ID of the VPC"
value = "${aws_vpc.this.id}"
value = "${element(concat(aws_vpc.this.*.id, list("")), 0)}"
}
output "vpc_cidr_block" {
description = "The CIDR block of the VPC"
value = "${aws_vpc.this.cidr_block}"
value = "${element(concat(aws_vpc.this.*.cidr_block, list("")), 0)}"
}
output "default_security_group_id" {
description = "The ID of the security group created by default on VPC creation"
value = "${aws_vpc.this.default_security_group_id}"
value = "${element(concat(aws_vpc.this.*.default_security_group_id, list("")), 0)}"
}
output "default_network_acl_id" {
description = "The ID of the default network ACL"
value = "${aws_vpc.this.default_network_acl_id}"
value = "${element(concat(aws_vpc.this.*.default_network_acl_id, list("")), 0)}"
}
output "default_route_table_id" {
description = "The ID of the default route table"
value = "${aws_vpc.this.default_route_table_id}"
value = "${element(concat(aws_vpc.this.*.default_route_table_id, list("")), 0)}"
}
# Subnets
......
variable "create_vpc" {
description = "Controls if VPC should be created (it affects almost all resources)"
default = true
}
variable "name" {
description = "Name to be used on all the resources as identifier"
default = ""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment