0
0
Lập trình
Admin Team
Admin Teamtechmely

Tối Ưu Hóa Terraform với Modules và Workspaces cho MyCoCo

Đăng vào 6 ngày trước

• 10 phút đọc

Giới thiệu

Khi các đội nhóm quản lý nhiều môi trường trong Terraform, họ thường gặp phải tình trạng sao chép toàn bộ cấu hình, dẫn đến việc bảo trì trở nên phức tạp. Việc kết hợp giữa workspaces và modules trong Terraform cung cấp một giải pháp thanh lịch—một mã nguồn duy nhất phục vụ cho tất cả các môi trường thông qua các cấu hình nhận biết workspace. Trong bài viết này, chúng ta sẽ xem MyCoCo đã biến đổi quản lý hạ tầng của họ như thế nào bằng cách sử dụng workspaces để đạt được nguyên tắc DRY (Don't Repeat Yourself) thực sự.

Tóm tắt nội dung

Vấn đề: Cấu hình Terraform bị sao chép giữa các môi trường dev/staging/production dẫn đến sự khác biệt môi trường, lỗi triển khai và 20+ giờ bảo trì hàng tuần.

Giải pháp: Sử dụng workspaces của Terraform để tách biệt môi trường kết hợp với modules để tái sử dụng mã và tệp biến cụ thể cho từng workspace.

Tác động: MyCoCo đã giảm thời gian quản lý cấu hình xuống 70%, loại bỏ sự khác biệt môi trường và triển khai các môi trường mới trong vài giờ thay vì vài ngày.

Cách thực hiện: Sử dụng terraform.workspace với các mẫu thiết kế module và tệp cấu hình terraform.workspace.tfvars cho từng môi trường.

Kết luận: Nếu bạn đang duy trì các thư mục Terraform riêng biệt cho mỗi môi trường, việc sử dụng workspaces và modules sẽ biến đổi quản lý hạ tầng của bạn.

Thách thức: Sự phân tán môi trường của MyCoCo

"Tại sao chúng ta lại có ba phiên bản khác nhau của cấu hình RDS?" Jordan đã hỏi trong tuần đầu tiên làm kỹ sư nền tảng tại MyCoCo. Câu trả lời tiết lộ một vấn đề sâu sắc hơn.

Sam, kỹ sư DevOps cấp cao, giải thích về sự phát triển của họ:

"Chúng tôi bắt đầu với một môi trường, sau đó sao chép mọi thứ cho staging, và lại sao chép cho production. Bây giờ chúng tôi duy trì ba thư mục Terraform riêng biệt."

Cấu trúc này đã kể một câu chuyện:

Copy
infrastructure/
├── dev/
│   ├── main.tf      # 500 dòng
│   ├── rds.tf       # 200 dòng
│   └── variables.tf # 150 dòng
├── staging/
│   ├── main.tf      # 497 dòng (khác một chút)
│   ├── rds.tf       # 198 dòng (sự thay đổi nhỏ)
│   └── variables.tf # 148 dòng (giá trị khác nhau)
└── production/
    ├── main.tf      # 502 dòng (nhiều sự khác biệt hơn)
    ├── rds.tf       # 205 dòng (sự thay đổi quan trọng)
    └── variables.tf # 152 dòng (giá trị production)

Alex, Phó Giám đốc Kỹ thuật, đã định lượng tác động:

"Mỗi thay đổi hạ tầng đều yêu cầu ba pull request, ba code review và ba lệnh terraform apply riêng biệt. Chúng tôi đang tiêu tốn 20 giờ mỗi tuần chỉ để giữ cho chúng đồng bộ."

Điểm bùng phát xảy ra khi một bản vá bảo mật quan trọng cần được áp dụng cho tất cả các môi trường. Điều mà đáng lẽ chỉ mất 30 phút đã biến thành một dự án kéo dài hai ngày để cập nhật từng môi trường, kiểm tra riêng biệt và hy vọng không bỏ sót điều gì.

Giải pháp: Kiến trúc Workspaces + Modules

Sự chuyển mình của MyCoCo xoay quanh hai tính năng chính của Terraform: workspaces để tách biệt môi trường và modules để tái sử dụng mã.

Trước: Thư mục trùng lặp

Copy
# production/rds.tf - Được sao chép và sửa đổi cho mỗi môi trường
resource "random_password" "db_password" {
  length  = 16
  special = true
}

# Lưu ý: Cân nhắc sử dụng password_wo thay vì password trong Terraform 1.11+
# để đảm bảo an toàn hơn (thuộc tính chỉ ghi không hiển thị trong kế hoạch)
resource "aws_db_instance" "main" {
  identifier     = "mycoco-prod"
  engine         = "postgres"
  engine_version = "15.3"
  instance_class = "db.t3.large"  # Được mã hóa cứng theo môi trường

  allocated_storage = 100
  storage_encrypted = true

  username = "dbadmin"
  password = random_password.db_password.result

  # 50+ dòng nữa cấu hình hầu như giống nhau...
}

Sau: Module nhận biết Workspace

Copy
# main.tf - Cấu hình duy nhất cho tất cả các môi trường
locals {
  workspace_config = {
    dev = {
      instance_class    = "db.t3.micro"
      allocated_storage = 20
      backup_retention  = 1
    }
    staging = {
      instance_class    = "db.t3.medium"
      allocated_storage = 50
      backup_retention  = 7
    }
    production = {
      instance_class    = "db.t3.large"
      allocated_storage = 100
      backup_retention  = 30
    }
  }

  env_config = local.workspace_config[terraform.workspace]
}

module "database" {
  source = "./modules/rds"

  environment       = terraform.workspace
  instance_class    = local.env_config.instance_class
  allocated_storage = local.env_config.allocated_storage
  backup_retention  = local.env_config.backup_retention

  # Cấu hình chung cho tất cả các môi trường
  engine         = "postgres"
  engine_version = "15.3"

  # Tên nhận biết theo workspace
  identifier = "mycoco-${terraform.workspace}"
}

Cấu trúc Module

Copy
# modules/rds/variables.tf
variable "identifier" {
  description = "Tên của phiên bản RDS"
  type        = string
}

variable "engine" {
  description = "Động cơ cơ sở dữ liệu"
  type        = string
}

variable "engine_version" {
  description = "Phiên bản động cơ để sử dụng"
  type        = string
}

variable "instance_class" {
  description = "Loại phiên bản của RDS"
  type        = string
}

variable "allocated_storage" {
  description = "Dung lượng lưu trữ được cấp phát tính bằng gigabyte"
  type        = number
}

variable "backup_retention" {
  description = "Số ngày giữ sao lưu"
  type        = number
  default     = 7
}

variable "environment" {
  description = "Môi trường triển khai"
  type        = string
}
Copy
# modules/rds/main.tf
resource "random_password" "db_password" {
  length  = 16
  special = true
}

resource "aws_db_instance" "main" {
  identifier     = var.identifier
  engine         = var.engine
  engine_version = var.engine_version
  instance_class = var.instance_class

  allocated_storage       = var.allocated_storage
  max_allocated_storage   = var.allocated_storage * 2
  storage_encrypted       = true

  db_name  = "mycoco"
  username = "dbadmin"
  password = random_password.db_password.result

  backup_retention_period = var.backup_retention
  backup_window          = "03:00-04:00"

  # Tính năng chỉ dành cho production
  deletion_protection = var.environment == "production" ? true : false
  skip_final_snapshot = var.environment != "production" ? true : false

  tags = {
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}
Copy
# modules/rds/outputs.tf
output "endpoint" {
  description = "Điểm kết nối"
  value       = aws_db_instance.main.endpoint
}

output "database_name" {
  description = "Tên cơ sở dữ liệu"
  value       = aws_db_instance.main.db_name
}

output "instance_id" {
  description = "ID của phiên bản RDS"
  value       = aws_db_instance.main.id
}

Các biến cụ thể cho từng môi trường

Copy
# envs/production.tfvars
region               = "ca-central-1"
enable_monitoring    = true
enable_backups       = true
multi_az            = true
performance_insights = true

# envs/staging.tfvars
region               = "ca-central-1"
enable_monitoring    = true
enable_backups       = true
multi_az            = false
performance_insights = false

# envs/dev.tfvars
region               = "ca-central-1"
enable_monitoring    = false
enable_backups       = false
multi_az            = false
performance_insights = false

Quy trình quản lý Workspace

Copy
# Liệt kê các workspaces có sẵn
$ terraform workspace list
  default
  dev
* staging
  production

# Chuyển sang môi trường production
$ terraform workspace select production

# Triển khai với cấu hình cụ thể cho từng workspace
$ terraform apply -var-file="envs/$(terraform workspace show).tfvars"

Kết quả: Biến đổi Workspace của MyCoCo

Tác động của việc áp dụng workspaces với modules là ngay lập tức:

Giảm 70% thời gian bảo trì: Các thay đổi trước đây yêu cầu cập nhật ba mã nguồn riêng biệt giờ chỉ cần thực hiện ở một nơi. Sam đã nói:

"Tôi thực hiện một thay đổi, kiểm tra nó trong workspace dev, chuyển nó qua staging, và áp dụng cho production—tất cả với cùng một mã."

Không còn sự khác biệt môi trường: Với tất cả các môi trường đều sử dụng cùng một modules, sự khác biệt cấu hình trở nên không thể. Những khác biệt duy nhất là có chủ ý, được định nghĩa trong các biến cụ thể cho từng workspace.

Triển khai môi trường nhanh chóng: Khi MyCoCo cần một môi trường khôi phục thảm họa, Jordan đã tạo nó trong hai giờ: terraform workspace new dr-east && terraform apply. Trước đây, điều này sẽ mất nhiều ngày để sao chép và sửa đổi các cấu hình.

Tách biệt môi trường rõ ràng: Maya, kỹ sư bảo mật, đánh giá cao sự tách biệt tự nhiên:

"Mỗi workspace có tệp trạng thái riêng. Không có rủi ro nào trong việc vô tình sửa đổi sản xuất khi làm việc trong dev."

Sự xác thực thực sự đến trong đợt kiểm tra bảo mật tiếp theo của họ. Thay vì xem xét ba bộ cấu hình, các kiểm toán viên đã xem xét một mã nguồn module rõ ràng với sự tách biệt môi trường thông qua workspaces.

Những điều cần lưu ý

  1. Bắt đầu với Workspaces: Trước khi đi sâu vào cấu trúc module phức tạp, hãy triển khai workspaces để tách biệt các môi trường trong khi sử dụng cùng một mã.

  2. Sử dụng terraform.workspace: Tham chiếu workspace hiện tại trong các cấu hình của bạn cho việc định danh tài nguyên động và logic điều kiện.

  3. Kết hợp với Modules: Workspaces xử lý tách biệt môi trường; modules xử lý tái sử dụng mã. Cùng nhau, chúng loại bỏ sự trùng lặp.

  4. Biến cụ thể cho workspace: Lưu trữ các giá trị cụ thể cho từng môi trường trong các tệp tfvars riêng biệt, được tải dựa trên workspace hiện tại.

  5. Tách biệt trạng thái: Mỗi workspace duy trì tệp trạng thái riêng, cung cấp sự tách biệt môi trường tự nhiên mà không cần cấu hình backend phức tạp.

  6. Tài liệu là rất quan trọng: Mỗi module cần tài liệu rõ ràng về các biến yêu cầu và tùy chọn, giúp việc áp dụng trở nên đơn giản. Sử dụng terraform-docs để tự động hóa quá trình này.

  7. Cân nhắc các module cộng đồng: Đối với các thiết lập RDS phức tạp, hãy xem xét việc sử dụng các module đã được thiết lập như terraform-aws-modules/rds mà cung cấp các cấu hình nhận biết workspace ngay từ đầu.

Kết luận

Đối với các đội nhóm đang chìm trong các cấu hình Terraform trùng lặp, việc kết hợp workspaces với modules cung cấp một con đường dẫn đến sự bình yên. Sự đầu tư vào việc tái cấu trúc mang lại lợi ích ngay lập tức trong việc giảm bảo trì, loại bỏ sự khác biệt và làm hài lòng các kỹ sư.

Điều quan trọng là bắt đầu một cách đơn giản: triển khai workspaces trước, sau đó từ từ rút ra các mẫu chung thành các module có thể tái sử dụng. Đừng cố gắng xây dựng một cấu trúc module hoàn hảo ngay từ đầu—hãy để các mẫu sử dụng thực tế của bạn dẫn dắt sự trừu tượng.

Sẵn sàng để biến đổi Terraform đa môi trường của bạn? Bắt đầu với workspaces, thêm modules, và xem sự phức tạp trong quản lý hạ tầng của bạn biến mất.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào