Terraform: Don't reinvent the modules
Last year when I was learning Terraform to build CyberLabs infrastructure, it was a good lesson to build my own Terraform modules so I could learn from scratch. And that's a good start when you are learning new technology. But now working as a consultant at Sensedia, I know a lot of Terraform. At least for AWS. And maintaining my modules, and handling corner cases, or best practices was exhausting and time-consuming, so I started to check out on Terraform Registry about public AWS modules that are validated by the Terraform Community that would make my client not depending on my modules or to write it's own modules.
And in that search I have found this repository:
That repository contains a good amount of modules to create basic resources in AWS as VPC's, EKS, RDS, IAM… And at the part that is validated by the community, the Terraform Registry shows that the VPC module has been provisioned around 7 million times.
So, on my checklist:
[ x ] Module is public and foss
[ x ] Module is currently maintained
[ x ] Module is validated by the community
[ x ] Module provides embedded good practices
[ x ] Module provides examples on how to configure it
We are good to go. Here is an example of how to configure the VPC module with tags to support further implementation of a Kubernetes Cluster and private subnets for RDS databases.
data "aws_availability_zones" "available" {}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
azs = data.aws_availability_zones.available.names
cidr = var.vpc_cidr
create_database_subnet_group = false
database_subnets = var.database_subnets_cidrs
default_network_acl_name = "${var.name}-default-acl"
default_security_group_name = "${var.name}-default-sg"
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support
enable_nat_gateway = var.setup_nat_gateway
name = var.name
private_subnets = var.private_subnets_cidrs
public_subnets = var.public_subnets_cidrs
single_nat_gateway = var.setup_nat_gateway
tags = merge(
var.tags, {
"kubernetes.io/cluster/${var.name}" = "shared"
})
public_subnet_tags = merge(
var.tags, {
"kubernetes.io/cluster/${var.name}" = "shared"
"kubernetes.io/role/elb" = "1"
})
private_subnet_tags = merge(
var.tags, {
"kubernetes.io/cluster/${var.name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
})
}
At the module documentation you will find all the inputs and outputs that the module provides.
That's all folks!