Phase 4: Infrastructure as Code & Cloud

Reusable Modules & Variables

Intermediate ~2 min read
Think of it this way A friendly analogy. Read this if the technical version feels dense. Show Hide

Imagine you love baking, and you often make cupcakes. Now, let’s say you need to make 100 cupcakes for a big school fair! If you had to write down every single step, like 'mix flour, add sugar, crack egg' for each of the 100 cupcakes, it would take forever and you’d probably make a mistake.

Instead, you probably have one really good 'cupcake recipe' in your head or on a card. This single recipe tells you all the steps to make one batch of perfect cupcakes. You just follow those steps, and boom, you have cupcakes. In the world of building computer things, we have something similar called 'modules.' A module is like that single, perfect recipe. It’s a complete set of instructions for building one specific part of a computer system, like a small mini-website or a special storage box for information. We use modules so we don't have to write the same instructions over and over again, saving a lot of time and avoiding mix-ups.

Now, what if sometimes you want chocolate cupcakes, and sometimes vanilla? Or maybe you need a big batch of 24 cupcakes, but other times just a small batch of 6? You don't need a totally new recipe for each one, right? Your main cupcake recipe probably has places where you decide these things. It might say, 'Add flavor here,' or 'Adjust servings for this many people.' These customizable parts of the recipe are exactly what we call 'variables.' They are like switches or empty spaces you fill in when you use the recipe, telling it exactly how you want this specific batch to turn out.

So, when engineers build big online services, they use modules (like our cupcake recipe) to quickly create common parts. Then, they use variables (like choosing the flavor or how many servings) to make each part unique without changing the main instructions. This means they can build many similar but slightly different pieces of a system very quickly and reliably. It's like having a super-powered recipe book where you only write things once, but can customize every dish!

Terraform modules are the cornerstone of scalable and maintainable Infrastructure as Code. Think of a module as a container for one or more related resources (e.g., an entire VPC, a single EC2 instance with its security group, or a database cluster). Their primary purpose is to encapsulate and reuse common configurations, preventing you from writing the same blocks of code repeatedly. This "Don't Repeat Yourself" (DRY) principle is crucial in large infrastructure projects, promoting consistency and reducing errors. Modules can be sourced locally from your project, or remotely from the Terraform Registry, Git repositories, and S3 buckets.

While modules provide the structure for reusability, variables are the mechanism that makes them truly flexible. A module is essentially a template, and variables are the parameters you pass into that template to customize its behavior without altering its core source code. For instance, an "EC2 instance" module might have variables for instance_type, ami_id, or environment. When you call the module, you provide specific values for these variables, allowing you to deploy a "dev" instance or a "prod" instance using the exact same module definition. This decoupling of configuration from implementation is powerful.

Together, reusable modules and variables significantly enhance collaboration, standardization, and maintainability across your infrastructure. They allow teams to build a library of proven, golden-path infrastructure components that are tested and secure, rather than re-inventing the wheel for every new service or environment. This hierarchical approach simplifies complex deployments, enabling you to build elaborate infrastructure by composing smaller, well-defined building blocks, ultimately accelerating your infrastructure delivery as a DevOps Engineer.

Key Takeaways

  • Modules encapsulate and reuse common infrastructure configurations, promoting the DRY principle.
  • Variables provide a way to customize module behavior without modifying its source code.
  • This combination enables standardization, consistency, and reduced errors across environments.
  • Modules can be sourced locally (from your project) or remotely (Terraform Registry, Git).
  • Passing different variable values allows a single module to deploy varying resource configurations.

Code Example

terraform
module "web_server_dev" {
  source        = "./modules/ec2" # Path to your local EC2 module
  ami_id        = "ami-0abcdef1234567890" # Example Dev AMI
  instance_type = "t2.micro"
  instance_name = "dev-web-server"
}

module "web_server_prod" {
  source        = "./modules/ec2"
  ami_id        = "ami-0fedcba9876543210" # Example Prod AMI
  instance_type = "t2.medium"
  instance_name = "prod-web-server"
}

How this code works

This code efficiently deploys two distinct web servers, one for development (web_server_dev) and one for production (web_server_prod), using a single, reusable blueprint. Instead of writing out the full configuration for an EC2 instance twice, it leverages a Terraform module. Each module block acts like a call to a function, allowing a reusable set of infrastructure resources to be defined once and invoked multiple times with different settings. This approach keeps the code organized and consistent.

The key to this reusability is the source argument within each module block, which points to "./modules/ec2". This tells Terraform where to find the definition for creating an EC2 instance. For each server, specific values like ami_id, instance_type, and instance_name are then passed into the module. This is powerful because the complex logic of how to create an EC2 instance (e.g., security groups, key pairs) lives only once inside modules/ec2. If that core logic needs updating, the change is made in just one place, benefiting both dev and prod servers without needing to edit individual server definitions, which greatly reduces the risk of errors and inconsistencies across environments.