Danh sách bài viết trong series Terraform Associate (003)
- Bài 0: Giới Thiệu Series Và Tổng Quan Về Chứng Chỉ Terraform Associate (003)
- Bài 1: Terraform Là Gì? Tổng Quan Và Vai Trò Trong IaC
- Bài 2: Cài Đặt Terraform Trên Các Hệ Điều Hành
- Bài 3: Terraform Workflow: Init, Plan, Apply, Destroy
- Bải 4: Terraform CLI Nâng Cao: Lệnh Taint, Import, Refresh
- Bài 5: Quản Lý Provider Trong Terraform
- Bài 6: Quản Lý Resource Trong Terraform
- Bài 7: Sử Dụng Biến (Variables) Trong Terraform
- Bài 8: Sử Dụng Output Trong Terraform
- Bài 9: Hiểu Terraform State Quản Lý Trạng Thái Hạ Tầng
- Bài 10: Sử Dụng Remote State Với Backend Như S3 Trong Terraform
- Bài 11: Terraform Workspace Quản Lý Nhiều Môi Trường
- Bài 12: Terraform Module: Mô-đun Hóa Cấu Hình
- Bài 13: Terraform Data Sources Truy Vấn Thông Tin Hạ Tầng
- Bài 14: Quản Lý Vòng Đời Tài Nguyên Với Terraform
- Bài 15: Tự Động Hóa Và Tích Hợp CI/CD Với Terraform
- Bài 16: Xử Lý Lỗi Và Debug Trong Terraform
- Bài 17: Tối Ưu Hóa Hiệu Suất Với Terraform
- Bài 18: Bảo Mật Cấu Hình Terraform
- Bài 19: Triển Khai Hạ Tầng Đa Vùng Với Terraform
- Bài 20: Triển Khai Hạ Tầng Serverless Với Terraform
- Bài 21: Triển Khai Hạ Tầng Container Với Terraform (ECS, EKS)
- Bài 22: Triển Khai Hạ Tầng Multi-Cloud Với Terraform
- Bài 23: Tổng Kết Series Và Chuẩn Bị Cho Kỳ Thi Terraform Associate (003)
Terraform Module Là Gì?
Terraform Module là một tập hợp các file Terraform (.tf
hoặc .tfvars
) được đóng gói thành một đơn vị tái sử dụng, cho phép bạn tổ chức và tái sử dụng mã cấu hình. Một module có thể bao gồm các resource, variable, output, và thậm chí các module con (nested modules). Module giúp bạn mô-đun hóa hạ tầng, giảm trùng lặp mã, và quản lý cấu hình phức tạp một cách hiệu quả. Hiểu và sử dụng module là kỹ năng quan trọng được kiểm tra trong kỳ thi Terraform Associate (003), liên quan đến mục tiêu 7 (Read, Generate, and Modify Configuration).
Vai Trò Của Module Trong Quản Lý Hạ Tầng
Module đóng vai trò quan trọng trong quản lý hạ tầng:
- Tái sử dụng mã: Dùng lại cấu hình (VD: EC2 instance) cho nhiều môi trường hoặc dự án.
- Tổ chức mã: Chia nhỏ mã thành các module (VD: module cho network, module cho compute) để dễ quản lý.
- Chuẩn hóa hạ tầng: Đảm bảo tài nguyên được triển khai nhất quán giữa các nhóm.
- Hỗ trợ hợp tác: Các nhóm có thể chia sẻ module qua Terraform Registry hoặc Git.
- Tăng tốc triển khai: Giảm thời gian viết mã bằng cách sử dụng module có sẵn.
Cấu Trúc Và Khai Báo Module
Cấu Trúc Thư Mục Của Module
Một module thường được tổ chức trong một thư mục riêng:
modules/
└── ec2-instance/
├── main.tf
├── variables.tf
├── outputs.tf
main.tf
: Chứa khai báo tài nguyên (resources).variables.tf
: Khai báo biến đầu vào.outputs.tf
: Khai báo giá trị đầu ra.
Khai Báo Module Trong File Terraform
Module được gọi trong file chính bằng block module
:
module "<NAME>" {
source = "<PATH>"
[VARIABLES]
}
<NAME>
: Tên module, duy nhất trong dự án.source
: Đường dẫn đến module (cục bộ, Git, hoặc Terraform Registry).[VARIABLES]
: Biến đầu vào truyền vào module.
Sử Dụng Module Từ Nguồn Cục Bộ
- Thư mục module
modules/ec2-instance/main.tf
:resource "aws_instance" "instance" { ami = var.ami instance_type = var.instance_type tags = { Name = "${var.environment}-instance" } }
-
Thư mục module
modules/ec2-instance/variables.tf
:variable "ami" { type = string description = "AMI ID for the EC2 instance" } variable "instance_type" { type = string description = "EC2 instance type" default = "t2.micro" } variable "environment" { type = string description = "Environment name (e.g., dev, prod)" }
-
Thư mục module
modules/ec2-instance/outputs.tf
:output "instance_id" { value = aws_instance.instance.id description = "The ID of the EC2 instance" } output "instance_public_ip" { value = aws_instance.instance.public_ip description = "The public IP of the EC2 instance" }
-
File chính
main.tf
:provider "aws" { region = "us-east-1" access_key = "YOUR_ACCESS_KEY" secret_key = "YOUR_SECRET_KEY" } module "ec2_dev" { source = "./modules/ec2-instance" ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" environment = "dev" } output "dev_instance_id" { value = module.ec2_dev.instance_id } output "dev_instance_public_ip" { value = module.ec2_dev.instance_public_ip }
- Quy trình:
terraform init
: Output:Initializing provider plugins... Finding hashicorp/aws versions matching "~> 5.0"... Installing hashicorp/aws v5.17.0... Installed hashicorp/aws v5.17.0 (signed by HashiCorp) Terraform has been successfully initialized!
terraform apply -auto-approve
: Output:module.ec2_dev.aws_instance.instance: Creating... module.ec2_dev.aws_instance.instance: Creation complete after 45s [id=i-0abcdef123456789] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: dev_instance_id = "i-0abcdef123456789" dev_instance_public_ip = "54.123.45.67"
Sử Dụng Module Từ Registry
- Ví dụ: Sử dụng module chính thức từ Terraform Registry (VD: module
aws-vpc
). -
File
main.tf
:provider "aws" { region = "us-east-1" access_key = "YOUR_ACCESS_KEY" secret_key = "YOUR_SECRET_KEY" } module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.8.1" name = "my-vpc" cidr = "10.0.0.0/16" azs = ["us-east-1a", "us-east-1b"] 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 single_nat_gateway = true } output "vpc_id" { value = module.vpc.vpc_id }
- Quy trình:
terraform init
: Output:Initializing modules... vpc in .terraform/modules/vpc/terraform-aws-modules-vpc-aws-5.8.1 Initializing provider plugins... Finding hashicorp/aws versions matching "~> 5.0"... Installing hashicorp/aws v5.17.0... Installed hashicorp/aws v5.17.0 (signed by HashiCorp) Terraform has been successfully initialized!
terraform apply -auto-approve
: Output (tóm tắt):module.vpc.aws_vpc.this[0]: Creating... module.vpc.aws_vpc.this[0]: Creation complete after 10s [id=vpc-12345678] module.vpc.aws_subnet.public[0]: Creating... module.vpc.aws_subnet.public[1]: Creating... module.vpc.aws_subnet.public[0]: Creation complete after 5s [id=subnet-12345678] module.vpc.aws_subnet.public[1]: Creation complete after 5s [id=subnet-87654321] Apply complete! Resources: 10 added, 0 changed, 0 destroyed. Outputs: vpc_id = "vpc-12345678"
Truyền Biến Vào Module
Module hỗ trợ truyền biến để tùy chỉnh tài nguyên:
-
Module
modules/ec2-instance/variables.tf
:variable "ami" { type = string } variable "instance_type" { type = string } variable "environment" { type = string }
-
File
main.tf
(truyền biến vào module):module "ec2_dev" { source = "./modules/ec2-instance" ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" environment = "dev" } module "ec2_prod" { source = "./modules/ec2-instance" ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.large" environment = "prod" }
- Ý nghĩa: Module
ec2-instance
được tái sử dụng với cấu hình khác nhau chodev
vàprod
.
Ví Dụ Thực Tế: Sử Dụng Module Để Tái Sử Dụng Cấu Hình
-
Module
modules/web-app/main.tf
:resource "aws_s3_bucket" "app_bucket" { bucket = "web-app-${var.environment}-20230518" tags = { Name = "AppBucket-${var.environment}" } } resource "aws_instance" "app_server" { ami = var.ami instance_type = var.instance_type tags = { Name = "AppServer-${var.environment}" } depends_on = [aws_s3_bucket.app_bucket] }
-
Module
modules/web-app/variables.tf
:variable "ami" { type = string description = "AMI ID for the EC2 instance" } variable "instance_type" { type = string description = "EC2 instance type" } variable "environment" { type = string description = "Environment name" }
-
Module
modules/web-app/outputs.tf
:output "bucket_name" { value = aws_s3_bucket.app_bucket.bucket } output "instance_id" { value = aws_instance.app_server.id } output "instance_public_ip" { value = aws_instance.app_server.public_ip }
-
File chính
main.tf
(kết hợp workspace và module):terraform { backend "s3" { bucket = "my-terraform-state" key = "state/${terraform.workspace}/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-locks" encrypt = true } } provider "aws" { region = "us-east-1" access_key = "YOUR_ACCESS_KEY" secret_key = "YOUR_SECRET_KEY" } module "web_app" { source = "./modules/web-app" ami = "ami-0c55b159cbfafe1f0" instance_type = terraform.workspace == "prod" ? "t2.large" : "t2.micro" environment = terraform.workspace } output "bucket_name" { value = module.web_app.bucket_name } output "instance_id" { value = module.web_app.instance_id } output "instance_public_ip" { value = module.web_app.instance_public_ip }
- Quy trình:
- Khởi tạo backend:
terraform init
Output:
Initializing the backend... Successfully configured the backend "s3"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... Finding hashicorp/aws versions matching "~> 5.0"... Installing hashicorp/aws v5.17.0... Installed hashicorp/aws v5.17.0 (signed by HashiCorp) Terraform has been successfully initialized!
- Tạo workspace
dev
:terraform workspace new dev
Output:
Created and switched to workspace "dev"!
- Áp dụng cho
dev
:terraform apply -auto-approve
Output:
module.web_app.aws_s3_bucket.app_bucket: Creating... module.web_app.aws_s3_bucket.app_bucket: Creation complete after 5s [id=web-app-dev-20230518] module.web_app.aws_instance.app_server: Creating... module.web_app.aws_instance.app_server: Creation complete after 45s [id=i-0abcdef123456789] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: bucket_name = "web-app-dev-20230518" instance_id = "i-0abcdef123456789" instance_public_ip = "54.123.45.67"
- Tạo workspace
prod
:terraform workspace new prod
Output:
Created and switched to workspace "prod"!
- Áp dụng cho
prod
:terraform apply -auto-approve
Output:
module.web_app.aws_s3_bucket.app_bucket: Creating... module.web_app.aws_s3_bucket.app_bucket: Creation complete after 5s [id=web-app-prod-20230518] module.web_app.aws_instance.app_server: Creating... module.web_app.aws_instance.app_server: Creation complete after 45s [id=i-0prod123456789] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: bucket_name = "web-app-prod-20230518" instance_id = "i-0prod123456789" instance_public_ip = "54.123.45.68"
- Khởi tạo backend:
Lưu Ý Quan Trọng Khi Sử Dụng Module
- Tên module duy nhất: Đảm bảo tên module không trùng lặp trong cùng file
.tf
. - Phiên bản module: Khi dùng module từ Registry, chỉ định
version
để tránh cập nhật không mong muốn (VD:version = "5.8.1"
). - Truyền biến đầy đủ: Module yêu cầu biến bắt buộc phải được truyền giá trị, nếu không sẽ báo lỗi.
- Tổ chức thư mục: Đặt module trong thư mục
modules/
để dễ quản lý. - Kiểm tra tài liệu: Với module từ Registry, đọc tài liệu để hiểu biến đầu vào và đầu ra.
Liên Hệ Với Chứng Chỉ Terraform Associate (003)
Kỳ thi Terraform Associate (003) kiểm tra khả năng sử dụng module. Bạn cần nắm:
- Câu hỏi mẫu:
- “Module trong Terraform được khai báo như thế nào?”
Đáp án: Sử dụng blockmodule
vớisource
và các biến đầu vào. - “Lợi ích chính của việc sử dụng module là gì?”
Đáp án: Tái sử dụng mã, chuẩn hóa hạ tầng, và tổ chức mã hiệu quả. - “Lệnh nào tải module từ Terraform Registry?”
Đáp án:terraform init
.
- “Module trong Terraform được khai báo như thế nào?”
- Thực hành: Kỳ thi có thể yêu cầu nhận diện cấu hình module hoặc dự đoán output khi sử dụng module.
Kết Luận
Terraform Module là công cụ mạnh mẽ để mô-đun hóa cấu hình, giúp tái sử dụng mã và quản lý hạ tầng hiệu quả. Hiểu cách tạo, sử dụng module, và thực hành với ví dụ thực tế sẽ giúp bạn tự tin thi đỗ Terraform Associate (003). Ở bài tiếp theo, chúng ta sẽ tìm hiểu cách sử dụng Terraform Data Sources để truy vấn thông tin hạ tầng.