Terraform Modules for Configuration Management in AWS

Introduction

Terraform adalah alat Infrastructure as Code (IaC) yang powerful, open-source, dan mendukung berbagai penyedia layanan cloud seperti AWS, GCP, Azure, dan lainnya. Dengan pendekatan deklaratif, Terraform memungkinkan engineer untuk membuat, mengubah, dan mengelola infrastruktur secara otomatis menggunakan file konfigurasi yang bisa dikontrol versinya.

Dalam praktik nyata, menjaga struktur kode agar tetap rapi, reusable, dan mudah dikelola sangat penting—terutama saat proyek mulai membesar dan melibatkan banyak komponen seperti VPC, EC2, S3, IAM, hingga load balancer. Di sinilah Terraform Modules memainkan peran kunci.

Artikel ini membahas bagaimana kita bisa menggunakan Terraform Modules untuk membuat konfigurasi infrastruktur AWS yang lebih terstruktur, efisien, dan scalable. Pendekatan modular ini juga membantu tim dalam kolaborasi serta mempercepat proses provisioning antar environment seperti dev, staging, dan production.

Preparation

Struktur Folder & Topology

├── README.md
├── live
│   ├── dev
│   │   ├── ec2
│   │   │   ├── ec2.tf
│   │   │   ├── terraform-private.tfvars
│   │   │   ├── terraform-public.tfvars
│   │   │   ├── terraform.tfstate
│   │   │   ├── terraform.tfstate.backup
│   │   │   └── variables.tf
│   │   ├── security_group
│   │   │   ├── sg.tf
│   │   │   ├── terraform.tfstate
│   │   │   ├── terraform.tfstate.backup
│   │   │   ├── terraform.tfvars
│   │   │   └── variables.tf
│   │   └── vpc
│   │       ├── terraform.tfstate
│   │       ├── terraform.tfstate.backup
│   │       ├── terraform.tfvars
│   │       ├── variabels.tf
│   │       └── vpc.tf
│   └── prod
│       ├── ec2
│       └── vpc
└── modules
    ├── ec2
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── varibales.tf
    ├── security_group
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    └── vpc
        ├── main.tf
        ├── outputs.tf
        └── varibales.tf

NB: abaikan terraform statenya , seharusnya disimpan ke dalam bucket S3

Step 1 – Contoh Module: VPC

Modules ini digunakan untuk template, lebih mudah di maintenance dan konsisten dalam implementasi IaC infrastructure as Code, File ini adalah inti dari module. Di sinilah kamu mendeklarasikan resource AWS atau konfigurasi lain.

modules/vpc/main.tf
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = var.vpc_name
    Environment = var.env_type
  }
}

resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.public_subnet_cidr
  availability_zone = var.public_az

  tags = {
    Name = "public-subnet"
  }
}

resource "aws_subnet" "private" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.private_subnet_cidr
  availability_zone = var.private_az

  tags = {
    Name = "private-subnet"
  }
}

resource "aws_eip" "nat" {
  domain = "vpc"
  tags = {
    Name = var.eip_name
    Environment = var.env_type
  }
}

resource "aws_nat_gateway" "main" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public.id

  tags = {
    Name = "main-nat-gateway"
    Environment = var.env_type
  }
  
  depends_on = [ aws_internet_gateway.main ]
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "main-internet-gateway"
    Environment = var.env_type
  }
  
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  tags = {
    Name = "${var.vpc_name}-public-route-table"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}


resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.main.id
  
}
  tags = {
    Name = "${var.vpc_name}-private-route-table"
  }
}

resource "aws_route_table_association" "private" {
  subnet_id      = aws_subnet.private.id
  route_table_id = aws_route_table.private.id
}


modules/vpc/variables.tf File ini berisi deklarasi variabel yang dibutuhkan oleh main.tf. Variabel ini akan diberi nilai oleh pengguna module saat memanggilnya.

variable "aws_region" {
  description = "AWS region to deploy resources"
  type        = string
}

variable "vpc_name" {
  description = "Name of the VPC"
  type        = string
}
variable "env_type" {
  description = "Environment type (e.g., dev, staging, prod)"
  type        = string
  
}

variable "vpc_cidr" {
  description = "VPC CIDR block"
  type        = string
}

variable "public_subnet_cidr" {
  description = "Public Subnet CIDR"
  type        = string
}

variable "private_subnet_cidr" {
  description = "Private Subnet CIDR"
  type        = string
}

variable "eip_name" {
  description = "Name for the NAT Gateway"
  type        = string
}

variable "public_az" {
  description = "Availability Zone for the public subnet"
  type        = string
}

variable "private_az" {
  description = "Availability Zone for the public subnet"
  type        = string
}

modules/vpc/outputs.tf File ini mendefinisikan output dari module yang bisa digunakan oleh module lain atau di consume.

output "vpc_id" {
  value = aws_vpc.main.id
}

output "eip_id" {
  value = aws_eip.nat.id
}

output "eip_name" {
  value = aws_eip.nat.tags["Name"]
}

output "nat_gateway_id" {
  value = aws_nat_gateway.main.id
}

output "nat_eip_id" {
  value = aws_eip.nat.id
}

output "public_subnet_id" {
  value = aws_subnet.public.id
}

output "private_subnet_id" {
  value = aws_subnet.private.id
}

Step 2 – Create environment VPC

Environment digunakan untuk pemeta’an atau metode key value, yang manage’able tentunya.

Akan ada file yang digunakan untuk remote backend — artinya file terraform.tfstate akan disimpan di AWS S3, bukan secara lokal. Ini bagus untuk kolaborasi & versioning.

live/dev/backend.tf

terraform {
  backend "s3" {
    bucket         = "terraform-learn-tfstate"
    key            = "dev/vpc/terraform.tfstate"
    region         = "ap-southeast-3"
    encrypt        = true
  }
}

live/dev/vpc.tf Memudahkan kita tentunya untuk versioning dengan struktur folder tersebut

provider "aws" {
  region = var.aws_region
}

module "vpc" {
  source              = "../../../modules/vpc"
  vpc_cidr            = var.vpc_cidr
  public_subnet_cidr  = var.public_subnet_cidr
  private_subnet_cidr = var.private_subnet_cidr
  env_type            = var.env_type
  aws_region          = var.aws_region
  vpc_name            = var.vpc_name
  eip_name            = var.eip_name
  public_az           = var.public_az
  private_az          = var.private_az
}

live/dev/variables.tf Variable sebagai bridge yang dimana valuenya disimpan dalam file tf.vars

variable "env_type" {}
variable "vpc_name" {}
variable "aws_region" {}
variable "vpc_cidr" {}
variable "public_subnet_cidr" {}
variable "private_subnet_cidr" {}
variable "eip_name"{}
variable "public_az" {}
variable "private_az" {}

live/dev/terraform.tfvars Variables yang akan kita gunakan nantinya, dan berisi nilai dari variabel yang didefinisikan di variables.tf.

vpc_name            = "gunawan-vpc"
env_type            = "dev"
aws_region          = "ap-southeast-3"
vpc_cidr            = "10.0.0.0/16"
public_subnet_cidr  = "10.0.0.0/22"
private_subnet_cidr = "10.0.4.0/22"
eip_name            = "gunawan-eip"
public_az           = "ap-southeast-3a"
private_az          = "ap-southeast-3b"

How to run?

cd live/dev/vpc
terraform init       # Menghubungkan ke backend S3
terraform plan       # Membaca vpc.tf, variabel, dan tfvars
terraform apply      # Deploy resource, state disimpan di S3

File terraform.tfstate sudah berada di S3 bucket meminimalisir terjadinya miss configuration, dan kita bisa improve untuk langkah selanjutnya yaitu running via CICD, selamat mencoba.

Leave a Reply

Your email address will not be published. Required fields are marked *