We begin Part V: Advanced Terraform. Until now, you wrote all your infrastructure in separate files. That works for something small, but as you grow, that approach becomes repetitive and unmanageable. The solution is modules, the key piece for reusing and organizing your Terraform code like a pro. In this subchapter, you'll understand what they are and how they're structured.

The problem: repetition

Imagine you need to create the same infrastructure over and over again. For example, in your company, every new project needs a VPC with public and private subnets, just like in Chapter 12. Without modules, you would have to copy and paste all that code into each project:

Project A: 200 lines of VPC code (copied)
Project B: 200 lines of VPC code (copied, again)
Project C: 200 lines of VPC code (copied, yet again)

This is a mess: if you find an error or want to improve the VPC, you have to change it in every place. This is exactly the problem that programming solved decades ago with functions: write something once and reuse it.

What is a module

A Terraform module is a set of grouped and reusable resources, packaged as a unit with well-defined input and output. It's the equivalent of a function in programming: you define it once and "call" it as many times as you need, changing only the details.

   Module "vpc" (defined once)
        │
        ├──► used in Project A (with its values)
        ├──► used in Project B (with other values)
        └──► used in Project C (with other values)

Analogy: a module is like a reusable recipe. You write the "pizza" recipe once, indicating which ingredients it accepts (the ingredients are the parameters). Then you use it many times, changing the ingredients: a ham pizza, a mushroom pizza, a vegetarian pizza. The recipe (the module) is the same; the ingredients (the variables) change.

The anatomy: the three key files

A module is simply a folder with .tf files. By convention, they are organized into three main files (remember the blocks from Chapter 10):

modulo-vpc/
 ├── variables.tf   ← the INPUTS (what can be configured)
 ├── main.tf        ← the RESOURCES (what the module creates)
 └── outputs.tf     ← the OUTPUTS (what information it returns)

  1. variables.tf — the inputs

Defines what can be configured in the module from the outside. They're like the "parameters" of the recipe. For example, the VPC range or the project name:

variable "cidr_vpc" {
  description = "VPC address range"
  type        = string
}

variable "nombre" {
  description = "Project name"
  type        = string
}

  1. main.tf — the resources

Contains the resources the module creates, using the input variables. It's the "body" of the recipe:

resource "aws_vpc" "esta" {
  cidr_block = var.cidr_vpc      # uses the input variable

  tags = {
    Name = var.nombre
  }
}
# ... more resources (subnets, gateway, routes...) ...

  1. outputs.tf — the outputs

Defines what information the module returns so others can use it (remember the outputs from subchapter 12.4). For example, the ID of the created VPC:

output "id_vpc" {
  description = "ID of the created VPC"
  value       = aws_vpc.esta.id
}

The contract: inputs and outputs

The elegance of a module is that it works like a box with a clear "contract":

              ┌──────────────────────┐
  Inputs ──►  │       MODULE         │──► Outputs
 (variables)  │  (creates resources) │  (outputs)
              └──────────────────────┘

Whoever uses the module doesn't need to know how it's made inside: they just provide the inputs it needs and receive the outputs they're interested in. This is abstraction: hiding complexity behind a simple interface. Just like you use a function without knowing how it's programmed inside.

Real-world example: a company's platform team creates a corporate-network module that sets up a VPC with all the company's best security and connectivity practices. Other teams just have to use that module by giving it a name and a range; they get a perfect network without being network experts. All the complexity is encapsulated in the module.

What you should remember

  • Without modules, you end up copying and pasting the same infrastructure code, which is repetitive and unmaintainable (changing something forces you to touch it in many places).
  • A module is a set of grouped and reusable resources, the equivalent of a function in programming: you define it once and use it many times. Like a reusable recipe.
  • A module is a folder with .tf files, conventionally organized into three: variables.tf (inputs), main.tf (resources), and outputs.tf (outputs).
  • It works like a box with a contract: you give it inputs (variables) and receive outputs, without needing to know how it's made inside. That's abstraction.

In the next subchapter, we'll dive deeper into how a module connects with the outside world: its input variables, its outputs, and how dependencies between modules are established.

Cloud, AWS & Terraform — From Zero to Expert

Chapter 1 · What is cloud computing

Chapter 2 · The cloud market and major providers

Chapter 3 · Regions, availability zones and edge

Chapter 4 · Compute: EC2

Chapter 5 · Storage: S3

Chapter 6 · Networking: VPC

Chapter 7 · Identity and access: IAM

Chapter 8 · Managed databases

Chapter 9 · Why Infrastructure as Code

Chapter 10 · HCL: the Terraform language

Chapter 11 · Providers and state

Chapter 12 · Your first real infrastructure in Terraform

Chapter 13 · Load balancing and auto scaling

Chapter 14 · Serverless with Lambda

Chapter 15 · Messaging and events

Chapter 16 · Content delivery and DNS

Chapter 17 · Containers on AWS

Chapter 18 · Modules: reuse and composition

Chapter 19 · Workspaces and environment management

Chapter 20 · Remote backends and locking

Chapter 21 · Infrastructure testing

Chapter 22 · Terraform in CI/CD

Chapter 23 · Defense in depth

Chapter 24 · Observability: logs, metrics and traces

Chapter 25 · Cost optimization

Chapter 26 · High availability and disaster recovery

Chapter 27 · AWS Well-Architected Framework

Chapter 28 · Serverless architectures at scale

Chapter 29 · Data platforms on AWS

Chapter 30 · Multi-account and landing zones

Chapter 31 · Platform Engineering and Internal Developer Platform

Chapter 32 · Relevant AWS certifications

Chapter 33 · Projects to consolidate what you've learned

Chapter 34 · Resources and community

© Copyright 2024. All rights reserved