Developing Terraform Modules at Scale
Tom Straub
(He/Him)
Delivery Manager of Infrastructure
Implementation Services
Rick
Systems Architect
Core Services Team
Morty
Application Developer
Billing Team
I wrote some awesome Terraform
Me too!
About Me
Delivery Manager of Infrastructure
Implementation Services at HashiCorp
Tom Straub
Terraform Enterprise
Terraform since: 0.6.0
Nickname: Terraform Tom
@straubt1
@terraform-tom
main.tf
variables.tf
outputs.tf
What is a Module
Spoiler alert: It’s just Terraform
main.tf
module "object_storage" {
source = "..."
bucket_name = "my_bucket"
}
output "bucket_id" {
value = module.object_storage .bucket_id
}
Module Reference
main.tf
variables.tf
outputs.tf
main.tf
module "object_storage" {
source = "..."
version = "=1.0.0"
bucket_name = "my_bucket"
}
output "bucket_id" {
value = module.object_storage .bucket_id
}
Module Reference
Producer Consumer
Producer vs. Consumer
main.tf
variables.tf
outputs.tf
How Many Resources?
How Many Resources?
Variables
Outputs
1:1
How Many Resources?
Variables
Outputs
Variables
Outputs
1:1 1:∞
How Many Resources?
Variables
Outputs
Variables
Outputs
1:1 1:∞
Goldilocks
Principle
Blast Radius
$ terraform destroy
Key Considerations
Blast Radius
$ terraform destroy
Key Considerations
Rate of Change
$ terraform apply
Blast Radius
$ terraform destroy
Dependencies
data "aws_vpc" "selected" {}
Key Considerations
Rate of Change
$ terraform apply
Define Module Structure
terraform-cloud-mymodule
variables.tf
outputs.tf
main.tf
Define Module Structure
terraform-google-mymodule
variables.tf
outputs.tf
README.md
CHANGELOG.md
main.tf
Define Module Structure
terraform-google-mymodule
variables.tf
outputs.tf
README.md
CHANGELOG.md
examples/
main.tf
Define Module Structure
terraform-google-mymodule
variables.tf
outputs.tf
README.md
CHANGELOG.md
examples/
tests/
main.tf
Example
Module
Data lookup within module
Example Module Code
variable "vpc_name" {}
data "aws_vpc" "main" {
tags {
Name = var.vpc_name
}
}
resource "aws_security_group" "allow_tls" {
vpc_id = data.aws_vpc.main.id
name = "allow_tls"
...
}
Example
Module
Module exposes a variable
Example Module Code
variable "vpc_id" {}
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
vpc_id = var.vpc_id
...
}
Dependency
Injection
Principle
Using
Module
Data lookup of Resource
Root Module Code
data "aws_vpc" "main" {
tags {
Name = "myTeamVPCName"
}
}
module "example" {
source = "./modules/example"
vpc_id = data.aws_vpc.main.id
}
Using
Module
Resource Create
Root Module Code
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
module "example" {
source = "./modules/example"
vpc_id = aws_vpc.main.id
}
Using
Module
Variable pass-through
Root Module Code
variable "vpc_id" {}
module "example" {
source = "./modules/example"
vpc_id = var.vpc_id
}
Module Depth Example
Module
Module Depth Example
Module
Module Depth Example
Module
Module Depth
Root Module Code
module "consul_cluster" {
source = ""
cluster_name = "my-cluster"
}
Consul Cluster
module "consul_vpc" {
source = ""
name = var.cluster_name
}
module "consul_servers" {
source = ""
name = var.cluster_name
}
Consul VPC
module "consul_sg" {
source = ""
name = var.name
}
Consul Servers
resource
"aws_autoscaling_group"
"consul" {
name = var.name
}
Module Depth
Example
Module
Module Depth Consul Cluster
module "consul_vpc" {
source = ""
name = var.cluster_name
}
module "consul_sg" {
source = ""
name = var.cluster_name
vpc_id = module.consul_vpc.vpc_id
}
module "consul_servers" {
source = ""
name = var.cluster_name
vpc_id = module.consul_vpc.vpc_id
}
Version Your Modules
▪ PATCH version when you make
backwards compatible bug fixes
Example: Fix a typo
▪ MINOR version when you add
functionality in a backwards
compatible
Example: Add a new feature
▪ MAJOR version when you make
incompatible API changes
Example: New behavior
v1.0.0
Major Version Minor Version Patch Version
Module Upgrade Scenarios
v1.0.0 v1.0.1
v1.1.0
v2.0.0
Module Version Constraints
v1.0.0
v1.1.0
v2.0.0
v1.0.1
v1.1.1
v1.1.2
versions
version = "= 1.0.0"
version = "~> 1.0.0"
version = "~> 1.1.0"
version = ">= 2.0.0"
module "object_storage"
{
source = "PMR"
version = "???"
}
main.tf
Depreciate Module Versions
v1.0.0
v1.1.0
v2.0.0
v1.0.1
v1.1.1
v1.1.2
versions
Module Discoverability
Where to find existing, new, updated modules
Module Release Pipeline
Automation, gates, releases are critical
Module When Ready
Do not over complicate early on
Additional
Thoughts on
Scale
So many things
So little time
Thank You
37
@straubt1
@terraform-tom

Developing Terraform Modules at Scale - HashiTalks 2021