Máy chủ web Cloud
figonkingx  

Terraform Modules: Tái sử dụng infrastructure code hiệu quả

Tiếp tục series Terraform, bài này hướng dẫn về Modules – cách tổ chức và tái sử dụng Terraform code hiệu quả cho production.

Nội dung chính

Terraform Modules là gì?

Module là container cho nhiều resources được sử dụng cùng nhau. Thay vì copy-paste code, bạn đóng gói thành module và tái sử dụng.

Cấu trúc Module

modules/
└── vpc/
    ├── main.tf       # Resources
    ├── variables.tf  # Input variables
    ├── outputs.tf    # Output values
    └── README.md     # Documentation

Tạo Module VPC

modules/vpc/variables.tf

variable "name" {
  description = "VPC name prefix"
  type        = string
}

variable "cidr" {
  description = "VPC CIDR block"
  type        = string
  default     = "10.0.0.0/16"
}

variable "azs" {
  description = "Availability zones"
  type        = list(string)
}

variable "enable_nat" {
  description = "Enable NAT gateway"
  type        = bool
  default     = true
}

modules/vpc/main.tf

resource "aws_vpc" "this" {
  cidr_block           = var.cidr
  enable_dns_hostnames = true
  
  tags = { Name = "${var.name}-vpc" }
}

resource "aws_subnet" "public" {
  count             = length(var.azs)
  vpc_id            = aws_vpc.this.id
  cidr_block        = cidrsubnet(var.cidr, 8, count.index)
  availability_zone = var.azs[count.index]
  
  tags = { Name = "${var.name}-public-${count.index + 1}" }
}

resource "aws_subnet" "private" {
  count             = length(var.azs)
  vpc_id            = aws_vpc.this.id
  cidr_block        = cidrsubnet(var.cidr, 8, count.index + 10)
  availability_zone = var.azs[count.index]
  
  tags = { Name = "${var.name}-private-${count.index + 1}" }
}

resource "aws_internet_gateway" "this" {
  vpc_id = aws_vpc.this.id
}

resource "aws_nat_gateway" "this" {
  count         = var.enable_nat ? 1 : 0
  allocation_id = aws_eip.nat[0].id
  subnet_id     = aws_subnet.public[0].id
}

resource "aws_eip" "nat" {
  count  = var.enable_nat ? 1 : 0
  domain = "vpc"
}

modules/vpc/outputs.tf

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

output "public_subnet_ids" {
  value = aws_subnet.public[*].id
}

output "private_subnet_ids" {
  value = aws_subnet.private[*].id
}

Sử dụng Module

# main.tf
module "vpc_prod" {
  source = "./modules/vpc"
  
  name       = "prod"
  cidr       = "10.0.0.0/16"
  azs        = ["ap-northeast-1a", "ap-northeast-1c"]
  enable_nat = true
}

module "vpc_staging" {
  source = "./modules/vpc"
  
  name       = "staging"
  cidr       = "10.1.0.0/16"
  azs        = ["ap-northeast-1a"]
  enable_nat = false  # Tiết kiệm chi phí
}

# Sử dụng outputs
resource "aws_instance" "web" {
  subnet_id = module.vpc_prod.public_subnet_ids[0]
  # ...
}

Module từ Terraform Registry

# Sử dụng module public
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-1a", "ap-northeast-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]

  enable_nat_gateway = true
}

Best Practices

  • Version modules – Dùng git tags hoặc semantic versioning
  • Documentation – README.md với examples
  • Validation – Dùng variable validation
  • Testing – Terratest cho automated testing
# Variable validation
variable "environment" {
  type = string
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Environment must be dev, staging, or prod."
  }
}

Module Composition

# Kết hợp nhiều modules
module "vpc" {
  source = "./modules/vpc"
  # ...
}

module "eks" {
  source     = "./modules/eks"
  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnet_ids
}

module "rds" {
  source     = "./modules/rds"
  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnet_ids
}

Fullstack Station Tips

Modules là cách organize Terraform code cho teams:

  • Bắt đầu với modules nhỏ, đơn giản
  • Dùng modules từ Registry khi phù hợp – đã được test kỹ
  • Pin versions để tránh breaking changes
  • Document inputs/outputs rõ ràng

Tham khảo

Comments

Leave A Comment