Danh sách bài viết trong series Hành Trình Làm Chủ Terraform
- Bài 1. Học Terraform Cơ Bản: Terraform Là Gì? Cài Đặt Và Viết Mã Đầu Tiên
- Bài 2. Học Terraform Với AWS: 5 Bước Tạo Máy Chủ EC2 Đầu Tiên
- Bài 3. Tạo VPC Với Terraform: Xây Dựng Hạ Tầng Mạng Trên AWS
- Bài 4. Quản Lý Tài Nguyên Với Terraform: Sử Dụng Variables Và Outputs
- Bài 5. Tự Động Hóa Triển Khai Với Terraform: Tạo Load Balancer Và Auto Scaling Group
- Bài 6. Sử Dụng Terraform Modules: Tái Sử Dụng Mã Để Quản Lý Hạ Tầng Hiệu Quả
- Bài 7. Terraform Workspaces: Quản Lý Nhiều Môi Trường Hiệu Quả Trên AWS
- Bài 8. Terraform State: Quản Lý Trạng Thái Hạ Tầng Với S3 Và DynamoDB
- Bài 9. Terraform Provisioners: Tự Động Hóa Cấu Hình Web Server Trên EC2
- Bài 10. Terraform CI/CD: Tự Động Triển Khai Hạ Tầng Với GitHub Actions
Tại Sao Cần Sử Dụng Terraform Workspaces?
Terraform workspaces là một công cụ mạnh mẽ để quản lý nhiều môi trường (như dev, staging, prod) trong cùng một mã nguồn Terraform, giúp bạn triển khai hạ tầng một cách hiệu quả và tránh lặp lại mã. Trong các bài trước, chúng ta đã làm quen với Terraform cơ bản (bài 1), tạo máy chủ EC2 (bài 2), xây dựng hạ tầng mạng VPC (bài 3), sử dụng variables/outputs (bài 4), tự động hóa triển khai với Load Balancer và Auto Scaling Group (bài 5), và sử dụng Terraform modules (bài 6).
Tuy nhiên, khi làm việc với nhiều môi trường, việc tạo các thư mục riêng hoặc sao chép mã cho từng môi trường (dev, staging, prod) có thể gây khó khăn trong việc bảo trì và dễ dẫn đến sai sót. Terraform workspaces cho phép bạn duy trì một bộ mã duy nhất nhưng triển khai hạ tầng khác nhau cho từng môi trường bằng cách quản lý trạng thái (state) riêng biệt. Trong bài này, mình sẽ hướng dẫn bạn 5 bước để sử dụng Terraform workspaces, triển khai EC2 trong các môi trường dev và prod trên AWS.
Terraform Workspaces: Hướng Dẫn Từng Bước
Bước 1: Chuẩn Bị Môi Trường Và Cấu Hình AWS CLI
- Hành động:
- Đảm bảo bạn đã cài đặt Terraform 1.11.2 và AWS CLI. Nếu chưa, tham khảo bài 1 và bài 2 để cài đặt.
- Kiểm tra cấu hình AWS CLI:
aws configureĐảm bảo bạn đã nhập đúng Access Key, Secret Key, và vùng (VD:
us-east-1).
- Kết quả thực tế:
- Nếu AWS CLI đã được cấu hình từ trước, bạn có thể kiểm tra bằng lệnh:
aws sts get-caller-identityOutput sẽ là:
{ "UserId": "AIDAXYZ1234567890", "Account": "123456789012", "Arn": "arn:aws:iam::123456789012:user/your-user-name" }(Output xác nhận AWS CLI đã được cấu hình đúng và có thể kết nối với tài khoản AWS của bạn).
- Nếu AWS CLI đã được cấu hình từ trước, bạn có thể kiểm tra bằng lệnh:
Bước 2: Tạo Thư Mục Dự Án Và Viết Mã Terraform
-
Hành động:
- Tạo một thư mục mới cho dự án:
mkdir terraform-workspaces-example cd terraform-workspaces-example -
Tạo file
variables.tfđể khai báo variables:touch variables.tfMở file
variables.tftrong VS Code và dán nội dung sau:variable "region" { description = "AWS region to deploy resources" type = string default = "us-east-1" } variable "ami" { description = "AMI ID for the EC2 instance" type = string default = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 in us-east-1 } -
Tạo file
main.tfđể viết mã Terraform:touch main.tfMở file
main.tftrong VS Code và dán nội dung sau:terraform { required_providers { aws = { source = "hashicorp/aws" version = "5.0.0" } } } provider "aws" { region = var.region } # Định nghĩa thông số dựa trên workspace locals { instance_type = terraform.workspace == "prod" ? "t3.medium" : "t2.micro" instance_count = terraform.workspace == "prod" ? 2 : 1 environment = terraform.workspace } # Tạo Security Group cho EC2 resource "aws_security_group" "workspace_sg" { name_prefix = "${local.environment}-sg-" ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${local.environment}-SG" } } # Tạo EC2 resource "aws_instance" "workspace_ec2" { count = local.instance_count ami = var.ami instance_type = local.instance_type vpc_security_group_ids = [aws_security_group.workspace_sg.id] tags = { Name = "${local.environment}-EC2-${count.index + 1}" } } # Output public IP của EC2 output "ec2_public_ips" { description = "Public IPs of the EC2 instances" value = aws_instance.workspace_ec2[*].public_ip }Giải thích:
locals: Sử dụngterraform.workspaceđể xác định môi trường hiện tại (devhoặcprod), từ đó điều chỉnhinstance_type(t2.microcho dev,t3.mediumcho prod) vàinstance_count(1 cho dev, 2 cho prod).aws_security_group: Tạo Security Group với tên và tag động dựa trên workspace.aws_instance: Tạo EC2 với số lượng và loại instance tùy thuộc vào workspace.output: Xuất public IP của các EC2 để kiểm tra sau khi triển khai.
- Tạo một thư mục mới cho dự án:
- Kết quả thực tế:
- Sau khi tạo các file, cấu trúc thư mục sẽ là:
terraform-workspaces-example/ ├── main.tf └── variables.tf(Kiểm tra bằng lệnh
ls, bạn sẽ thấy hai filemain.tfvàvariables.tf).
- Sau khi tạo các file, cấu trúc thư mục sẽ là:
- Đề xuất hình ảnh minh họa:
Đề xuất chèn hình ảnh chụp giao diện VS Code hiển thị filemain.tf, với đoạn mã sử dụngterraform.workspaceđược highlight. Văn bản thay thế (alt text): “Terraform workspaces – Viết mã Terraform sử dụng workspaces để quản lý môi trường”.
Bước 3: Tạo Và Quản Lý Workspaces
- Hành động:
- Trong thư mục
terraform-workspaces-example, khởi tạo dự án:terraform init - Tạo workspace cho môi trường
dev:terraform workspace new dev - Tạo workspace cho môi trường
prod:terraform workspace new prod - Xem danh sách workspaces:
terraform workspace list
- Trong thư mục
-
Kết quả thực tế:
-
Sau khi chạy
terraform init, terminal sẽ hiển thị:Initializing the backend... Initializing provider plugins... - Finding hashicorp/aws versions matching "5.0.0"... - Installing hashicorp/aws v5.0.0... - Installed hashicorp/aws v5.0.0 (signed by HashiCorp) Terraform has been successfully initialized!(Dòng “Terraform has been successfully initialized!” xác nhận quá trình khởi tạo thành công).
-
Sau khi chạy
terraform workspace new dev, terminal sẽ hiển thị:Created and switched to workspace "dev"! You're now on a new, empty workspace. Workspaces isolate their state, so if you run "terraform plan" Terraform will not see any existing state for this configuration. - Sau khi chạy
terraform workspace new prod, terminal sẽ hiển thị:Created and switched to workspace "prod"! - Sau khi chạy
terraform workspace list, terminal sẽ hiển thị:default dev * prod(Dấu
*cho biết bạn đang ở workspaceprod).
-
Bước 4: Triển Khai Hạ Tầng Trong Các Workspaces
- Hành động:
- Chuyển sang workspace
dev:terraform workspace select dev - Triển khai hạ tầng trong workspace
dev:terraform applyKhi được hỏi “Do you want to perform these actions?”, gõ
yesvà nhấn Enter. - Chuyển sang workspace
prod:terraform workspace select prod - Triển khai hạ tầng trong workspace
prod:terraform applyKhi được hỏi “Do you want to perform these actions?”, gõ
yesvà nhấn Enter.
- Chuyển sang workspace
-
Kết quả thực tế:
- Sau khi chạy
terraform workspace select dev, terminal sẽ hiển thị:Switched to workspace "dev". -
Sau khi chạy
terraform applytrong workspacedev, terminal sẽ hiển thị:Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_instance.workspace_ec2[0] will be created + resource "aws_instance" "workspace_ec2" { + ami = "ami-0c55b159cbfafe1f0" + instance_type = "t2.micro" + tags = { + "Name" = "dev-EC2-1" } } # aws_security_group.workspace_sg will be created + resource "aws_security_group" "workspace_sg" { + name_prefix = "dev-sg-" + tags = { + "Name" = "dev-SG" } } Plan: 2 to add, 0 to change, 0 to destroy. Do you want to perform these actions in workspace "dev"? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_security_group.workspace_sg: Creating... aws_security_group.workspace_sg: Creation complete after 2s [id=sg-0123456789abcdef0] aws_instance.workspace_ec2[0]: Creating... aws_instance.workspace_ec2[0]: Still creating... [10s elapsed] aws_instance.workspace_ec2[0]: Creation complete after 15s [id=i-0123456789abcdef0] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: ec2_public_ips = [ "54.123.45.67", ](Workspace
devtạo 1 instancet2.microvới tagName: dev-EC2-1). - Sau khi chạy
terraform workspace select prod, terminal sẽ hiển thị:Switched to workspace "prod". -
Sau khi chạy
terraform applytrong workspaceprod, terminal sẽ hiển thị:Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_instance.workspace_ec2[0] will be created + resource "aws_instance" "workspace_ec2" { + ami = "ami-0c55b159cbfafe1f0" + instance_type = "t3.medium" + tags = { + "Name" = "prod-EC2-1" } } # aws_instance.workspace_ec2[1] will be created + resource "aws_instance" "workspace_ec2" { + ami = "ami-0c55b159cbfafe1f0" + instance_type = "t3.medium" + tags = { + "Name" = "prod-EC2-2" } } # aws_security_group.workspace_sg will be created + resource "aws_security_group" "workspace_sg" { + name_prefix = "prod-sg-" + tags = { + "Name" = "prod-SG" } } Plan: 3 to add, 0 to change, 0 to destroy. Do you want to perform these actions in workspace "prod"? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_security_group.workspace_sg: Creating... aws_security_group.workspace_sg: Creation complete after 2s [id=sg-0987654321fedcba0] aws_instance.workspace_ec2[0]: Creating... aws_instance.workspace_ec2[1]: Creating... aws_instance.workspace_ec2[0]: Still creating... [10s elapsed] aws_instance.workspace_ec2[1]: Still creating... [10s elapsed] aws_instance.workspace_ec2[0]: Creation complete after 15s [id=i-0987654321fedcba0] aws_instance.workspace_ec2[1]: Creation complete after 15s [id=i-0987654321fedcba1] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: ec2_public_ips = [ "54.123.45.68", "54.123.45.69", ](Workspace
prodtạo 2 instancet3.mediumvới tagName: prod-EC2-1vàName: prod-EC2-2). - Kiểm tra trên AWS Console (EC2 Dashboard):
- Workspace
dev: 1 instance với tagName: dev-EC2-1, loạit2.micro. - Workspace
prod: 2 instance với tagName: prod-EC2-1vàName: prod-EC2-2, loạit3.medium.
- Workspace
- Sau khi chạy
Bước 5: Xóa Tài Nguyên Để Dọn Dẹp
- Hành động:
- Chuyển sang workspace
devvà xóa tài nguyên:terraform workspace select dev terraform destroyKhi được hỏi “Do you really want to destroy all resources?”, gõ
yesvà nhấn Enter. - Chuyển sang workspace
prodvà xóa tài nguyên:terraform workspace select prod terraform destroyKhi được hỏi “Do you really want to destroy all resources?”, gõ
yesvà nhấn Enter.
- Chuyển sang workspace
-
Kết quả thực tế:
-
Sau khi chạy
terraform destroytrong workspacedev, terminal sẽ hiển thị:Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # aws_instance.workspace_ec2[0] will be destroyed - resource "aws_instance" "workspace_ec2" { - ami = "ami-0c55b159cbfafe1f0" -> null - instance_type = "t2.micro" -> null - id = "i-0123456789abcdef0" -> null } # aws_security_group.workspace_sg will be destroyed - resource "aws_security_group" "workspace_sg" { - name_prefix = "dev-sg-" -> null - id = "sg-0123456789abcdef0" -> null } Plan: 0 to add, 0 to change, 2 to destroy. Do you really want to destroy all resources in workspace "dev"? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes aws_instance.workspace_ec2[0]: Destroying... [id=i-0123456789abcdef0] aws_instance.workspace_ec2[0]: Still destroying... [10s elapsed] aws_instance.workspace_ec2[0]: Destruction complete after 15s aws_security_group.workspace_sg: Destroying... [id=sg-0123456789abcdef0] aws_security_group.workspace_sg: Destruction complete after 2s Destroy complete! Resources: 2 destroyed. -
Sau khi chạy
terraform destroytrong workspaceprod, terminal sẽ hiển thị:Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # aws_instance.workspace_ec2[0] will be destroyed - resource "aws_instance" "workspace_ec2" { - ami = "ami-0c55b159cbfafe1f0" -> null - instance_type = "t3.medium" -> null - id = "i-0987654321fedcba0" -> null } # aws_instance.workspace_ec2[1] will be destroyed - resource "aws_instance" "workspace_ec2" { - ami = "ami-0c55b159cbfafe1f0" -> null - instance_type = "t3.medium" -> null - id = "i-0987654321fedcba1" -> null } # aws_security_group.workspace_sg will be destroyed - resource "aws_security_group" "workspace_sg" { - name_prefix = "prod-sg-" -> null - id = "sg-0987654321fedcba0" -> null } Plan: 0 to add, 0 to change, 3 to destroy. Do you really want to destroy all resources in workspace "prod"? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes aws_instance.workspace_ec2[0]: Destroying... [id=i-0987654321fedcba0] aws_instance.workspace_ec2[1]: Destroying... [id=i-0987654321fedcba1] aws_instance.workspace_ec2[0]: Still destroying... [10s elapsed] aws_instance.workspace_ec2[1]: Still destroying... [10s elapsed] aws_instance.workspace_ec2[0]: Destruction complete after 15s aws_instance.workspace_ec2[1]: Destruction complete after 15s aws_security_group.workspace_sg: Destroying... [id=sg-0987654321fedcba0] aws_security_group.workspace_sg: Destruction complete after 2s Destroy complete! Resources: 3 destroyed. - Kiểm tra lại trên AWS Console, tất cả instance và Security Group trong cả hai môi trường
devvàprodkhông còn tồn tại.
-
Kết Quả Đạt Được
- Bạn đã học cách sử dụng Terraform workspaces để quản lý nhiều môi trường (dev và prod) trong cùng một mã nguồn.
- Bạn đã triển khai hạ tầng khác nhau cho từng môi trường: 1 instance
t2.microchodevvà 2 instancet3.mediumchoprod. - Bạn đã kiểm tra và xác nhận hạ tầng hoạt động đúng trên AWS Console.
- Bạn đã xóa tài nguyên trong cả hai workspaces để dọn dẹp, tránh phát sinh chi phí không cần thiết.
Lưu Ý Quan Trọng
- Quản lý state: Mỗi workspace có file state riêng (VD:
terraform.tfstate.d/dev/terraform.tfstatevàterraform.tfstate.d/prod/terraform.tfstate). Đảm bảo không xóa hoặc sửa các file state này. - Chi phí AWS: Instance
t2.microtrongdevnằm trong Free Tier, nhưng instancet3.mediumtrongprodcó thể phát sinh chi phí (khoảng $0.0416/giờ mỗi instance). Luôn chạyterraform destroysau khi thử nghiệm. - Bảo mật: Security Group trong bài cho phép SSH (port 22) từ
0.0.0.0/0. Trong môi trường production, hãy giới hạn CIDR block hoặc sử dụng bastion host. - Tài liệu tham khảo: Xem thêm về Terraform workspaces trong tài liệu chính thức (Terraform Workspaces).







