10 Mẹo Terraform hàng đầu để Tự động hóa Hạ tầng

Terraform đã trở thành một công cụ thiết yếu cho hạ tầng dưới dạng mã (IaC), giúp các nhóm DevOps dễ dàng cấp phát, quản lý và mở rộng hạ tầng. Khi Terraform tiếp tục trở nên phổ biến, việc khai thác toàn bộ tiềm năng của nó thông qua các mẹo và thủ thuật nâng cao là rất quan trọng, giúp bạn tối ưu hóa quy trình làm việc và cải thiện việc triển khai hạ tầng của mình.

Trong bài blog này, chúng ta sẽ đề cập đến 10 mẹo Terraform mà mọi người dùng nên biết — từ việc làm chủ các tài nguyên động đến việc tận dụng cấu hình đa nhà cung cấp cho các kịch bản phục hồi sau thảm họa. Cho dù bạn là người mới bắt đầu hay người dùng Terraform có kinh nghiệm, những mẹo này sẽ nâng cao năng suất của bạn và làm cho mã hạ tầng của bạn hiệu quả và dễ quản lý hơn. Hãy cùng tìm hiểu

Mẹo Terraform — Mẹo #1: Sử dụng depends_on Khi làm việc với Terraform, hầu hết thời gian, nó tự động tìm ra thứ tự mà các tài nguyên nên được tạo. Nhưng trong một số trường hợp, bạn biết rằng một tài nguyên phải được tạo sau một tài nguyên khác, và Terraform không tự xử lý điều đó. Đó là lúc depends_on phát huy tác dụng.

Cá nhân tôi thấy nó rất hữu ích khi tạo một cụm AWS EKS bằng Terraform. Nếu bạn đã làm việc với EKS, bạn có thể đã gặp phải các tình huống mà một số phụ thuộc không được xử lý đúng cách, gây ra sự cố trong việc thiết lập cụm. Sử dụng depends_on, tôi đã có thể đảm bảo rằng các tài nguyên được tạo đúng thứ tự. Hãy xem kho lưu trữ GitHub của tôi, nơi tôi đã sử dụng điều này trong thiết lập EKS của mình.

Mẹo Terraform — Mẹo #2: Sử dụng count count cực kỳ hữu ích khi bạn muốn tạo tài nguyên chỉ cho một số môi trường nhất định.

📌 Tại sao nên sử dụng count?

  • ✅ Tạo tài nguyên có điều kiện — Nếu một tài nguyên chỉ cần thiết cho các môi trường cụ thể, bạn có thể kiểm soát nó bằng count.
  • ✅ Sử dụng module hiệu quả — Thay vì sửa đổi một module, hãy sử dụng count để bỏ qua việc tạo tài nguyên khi không cần thiết.
  • ✅ Di chuyển & xóa liền mạch — Dễ dàng hủy hoặc di chuyển hạ tầng bằng cách điều chỉnh giá trị count.

🔥 Ví dụ về các trường hợp sử dụng

  • 📍 Nhóm bảo mật (Security Groups) — Tạo một nhóm bảo mật chỉ trong môi trường dev, không phải trong môi trường production:
  • 📍 Bỏ qua Cân bằng tải cho Dev — Kiểm soát việc thực thi module:
  • 📍 Di chuyển từ ECS sang EKS — Hủy kích hoạt ECS mà không cần xóa thủ công:
    • Đặt count = 0, và khi Terraform chạy, nó sẽ tự động hủy các tài nguyên ECS cho môi trường đó.

🚀 Thay đổi cuộc chơi cho các cuộc di chuyển! Khi di chuyển khối lượng công việc dần dần, count cho phép bạn kiểm soát môi trường nào được triển khai ở mỗi giai đoạn — không cần xóa thủ công hoặc logic phức tạp!

Mẹo Terraform — Mẹo #3: Terraform Import (Import Thủ công) Đưa Tài nguyên được Tạo thủ công vào Terraform!

Bạn đã bao giờ tạo tài nguyên AWS theo cách thủ công — chỉ để kiểm thử hoặc học hỏi — và sau đó muốn quản lý chúng bằng Terraform mà không cần tạo lại mọi thứ chưa? 🤔 Đó là lúc Terraform Import phát huy tác dụng! 🎯

📌 Trường hợp sử dụng: Import Tài nguyên được tạo thủ công

  • ✅ Nhiều tài nguyên AWS hỗ trợ Terraform import, vì vậy bạn không phải bắt đầu lại từ đầu.
  • ✅ Thay vì theo dõi tài nguyên thủ công, chỉ cần import chúng vào Terraform state.
  • ✅ Tài liệu Terraform cung cấp các lệnh chính xác cho từng loại tài nguyên.

🔥 Ví dụ: Import một EC2 Instance của AWS

terraform import aws_instance.example i-0abcd1234efgh5678

Lệnh này import EC2 instance hiện có vào Terraform state, cho phép bạn quản lý nó giống như bất kỳ tài nguyên Terraform nào khác!

🚀 Tại sao nên sử dụng Terraform Import?

  • ✔️ Không thời gian chết — Quản lý tài nguyên hiện có mà không cần tạo lại.
  • ✔️ Onboarding nhanh hơn — Chuyển từ hạ tầng thủ công sang Terraform một cách liền mạch.
  • ✔️ Kiểm toán dễ dàng hơn — Duy trì tính nhất quán trên tất cả các tài nguyên. Bạn đã bao giờ sử dụng Terraform Import trong các dự án của mình chưa? Hãy bình luận bên dưới nhé! 👇

Mẹo Terraform — Mẹo #4: Tự động hóa Terraform Import — Một sự thay đổi cuộc chơi! Trước đây, việc import tài nguyên trong Terraform yêu cầu các bước thủ công — chạy lệnh và tự cập nhật file state. Nhưng với phiên bản Terraform mới, giờ đây nó được tự động hóa và liền mạch! 🎯

📌 Có gì mới? Thay vì chạy terraform import thủ công, giờ đây bạn có thể sử dụng:

  • “import from” → Chỉ định tài nguyên hiện có để import
  • “import to” → Định nghĩa tài nguyên Terraform mới

🔥 Ví dụ: Import các CloudWatch Log Groups cho AWS Lambda AWS tự động tạo các CloudWatch log group cho các hàm Lambda, nhưng chúng thiếu cài đặt retention phù hợp, dẫn đến chi phí lưu trữ không cần thiết. Thay vì tạo một log group mới, chỉ cần import log group hiện có vào Terraform và áp dụng các cài đặt mong muốn của bạn!

🚀 Tại sao nên tự động hóa Import?

  • ✔️ Không cần lệnh CLI thủ công — Tích hợp đầy đủ các bản import vào các pipeline CI/CD.
  • ✔️ Quản lý hạ tầng dễ dàng hơn — Quản lý liền mạch các tài nguyên hiện có bằng Terraform.
  • ✔️ Hoạt động trên các dịch vụ AWS — S3, EC2, RDS, CloudWatch, và hơn thế nữa!

Mẹo Terraform — Mẹo #5: Terraform Locals — Viết mã sạch hơn, dễ bảo trì hơn! Một trong những cách tốt nhất để giữ cho mã Terraform của bạn DRY (Don’t Repeat Yourself) là sử dụng locals.

📌 Tại sao nên sử dụng Locals? Hãy tưởng tượng bạn cần bật một tài nguyên chỉ cho môi trường dev bằng cách sử dụng count. Bạn sử dụng điều kiện này ở 10 nơi khác nhau. Bây giờ, nếu ngày mai bạn thêm môi trường production, bạn sẽ phải cập nhật cả 10 nơi — một cơn ác mộng bảo trì! ✅ Giải pháp: Sử dụng Locals! Thay vì lặp lại điều kiện ở khắp mọi nơi, hãy định nghĩa một biến local một lần và sử dụng nó trong toàn bộ mã của bạn.

🔥 Ví dụ: Đơn giản hóa các cờ bật/tắt bằng Locals Bây giờ, bất cứ khi nào bạn cần thay đổi điều kiện, bạn cập nhật nó ở một nơi, và nó áp dụng ở mọi nơi! 🎯

🚀 Lợi ích của việc sử dụng Locals

  • ✔️ Logic tập trung — Không cần cập nhật nhiều nơi.
  • ✔️ Khả năng đọc được cải thiện — Mã Terraform của bạn trở nên sạch hơn & có cấu trúc.
  • ✔️ Bảo trì dễ dàng hơn — Một lần cập nhật áp dụng trên tất cả các tài nguyên.

Mẹo Terraform — #6 Các trường hợp sử dụng nâng cao của Locals Terraform Locals — Hơn cả các cờ bật/tắt!

📌 Trường hợp sử dụng: Các loại instance có điều kiện Cần các loại instance khác nhau dựa trên môi trường? Sử dụng locals thay vì viết các điều kiện ở khắp mọi nơi! 🎯 Bây giờ, bạn không cần phải lặp lại các điều kiện trong mỗi tài nguyên!

📌 Trường hợp sử dụng: Xây dựng tên tài nguyên Muốn có các quy ước đặt tên nhất quán? Locals giúp việc này dễ dàng! 🔥 Bây giờ, tên bucket của bạn tự động cập nhật dựa trên dự án và môi trường!

🚀 Tại sao Locals là một sự thay đổi cuộc chơi?

  • ✔️ Loại bỏ trùng lặp mã
  • ✔️ Xử lý logic phức tạp dễ dàng
  • ✔️ Cải thiện khả năng bảo trì Tôi đã sử dụng locals rất nhiều trong Terraform, đặc biệt khi không có cách tiêu chuẩn nào khác để xử lý các điều kiện. Đôi khi, chúng ta phải đối mặt với những hạn chế nhất định, và locals giúp giữ mọi thứ đơn giản và có cấu trúc.

Mẹo Terraform — Mẹo #7: Sử dụng Provider-Level Tagging Việc gắn thẻ (tagging) cực kỳ quan trọng trong Terraform! Trong hầu hết các tổ chức, việc gắn thẻ đúng cách là bắt buộc, dù là để phân tích chi phí, lập hóa đơn, theo dõi tài nguyên hay thậm chí là tích hợp với các công cụ quản lý dịch vụ. Nhưng việc thêm thẻ thủ công cho mọi tài nguyên? Đó không phải là một thực hành tốt. Rất dễ quên, và việc gắn thẻ không bắt buộc để tạo tài nguyên, vì vậy nó có thể bị bỏ qua.

Làm thế nào để giải quyết vấn đề này? Terraform cung cấp một giải pháp toàn cầu cho vấn đề này — các thẻ mặc định ở cấp nhà cung cấp (provider-level default tags). Thay vì thêm thẻ riêng biệt cho mỗi tài nguyên, bạn có thể định nghĩa chúng một lần ở cấp nhà cung cấp bên trong providers.tf, và Terraform sẽ tự động áp dụng chúng cho tất cả các tài nguyên.

Tại sao điều này là một sự thay đổi cuộc chơi?

  • ✅ Không cần gắn thẻ thủ công — Mọi tài nguyên tự động nhận được các thẻ yêu cầu.
  • ✅ Gắn thẻ nhất quán — Đảm bảo mọi tài nguyên tuân thủ các tiêu chuẩn gắn thẻ của tổ chức.
  • ✅ Phân tích chi phí & lập hóa đơn — Giúp dễ dàng theo dõi chi phí dựa trên thẻ.
  • ✅ Kiểm toán & theo dõi tài nguyên — Nhanh chóng tìm kiếm tài nguyên dựa trên thẻ.
  • ✅ Xác định các tài nguyên được tạo tự động — Sử dụng các thẻ như “CreatedBy = Terraform” để phân biệt giữa các tài nguyên được tạo thủ công và tự động. Đối với các kỹ sư DevOps, đây là một cách tiết kiệm thời gian rất lớn! Bất kể bạn thêm bao nhiêu tài nguyên, cấu hình thẻ toàn cầu của bạn sẽ lo liệu mọi thứ.

Mẹo Terraform #8: Thiết lập Terraform Monorepo so với Modular cho Microservices Khi triển khai microservices, việc cấu trúc mã Terraform của bạn là rất quan trọng.

Hãy lấy một kịch bản thực tế: Bạn đang triển khai một ứng dụng Java và cần hạ tầng sau:

  • ✅ VPC cho mạng
  • ✅ RDS cho cơ sở dữ liệu
  • ✅ ALB/NLB cho cân bằng tải
  • ✅ EC2, ECS, hoặc EKS để triển khai ứng dụng
  • ✅ IAM roles, security groups, WAF, Route 53 cho bảo mật & DNS Vậy, bạn nên cấu trúc mã Terraform của mình như thế nào?

Cách tiếp cận 1: Monorepo (Kho lưu trữ đơn lẻ cho mọi thứ) Với Monorepo, tất cả mã Terraform cho các thành phần khác nhau (VPC, RDS, ALB, EC2, v.v.) được lưu trữ trong một kho lưu trữ duy nhất với một file state. ✅ Ưu điểm của Monorepo:

  • ✔️ Một nơi cho mọi thứ — Dễ dàng quản lý ban đầu và triển khai trên nhiều tài khoản.
  • ✔️ Triển khai bằng một lệnh duy nhất — Chỉ cần chạy terraform apply để triển khai toàn bộ stack. ❌ Nhược điểm của Monorepo:
  • ⛔ Phụ thuộc vào file state — Cập nhật một thành phần nhỏ (ví dụ: EC2) có thể vô tình ảnh hưởng đến các thành phần khác như RDS.
  • ⛔ Khó bảo trì — Một file state duy nhất có thể tạo ra rủi ro nếu có gì đó bị hỏng.
  • ⛔ Nâng cấp có thể phức tạp — Terraform có thể phát hiện các tài nguyên lỗi thời, gây ra các cập nhật không mong muốn.

Cách tiếp cận 2: Cách tiếp cận hiện đại — Phân tách mã Terraform Trong cách tiếp cận này, bạn tách các thành phần thành các thư mục hoặc kho lưu trữ riêng biệt, với mỗi thành phần có file state riêng, làm cho chúng độc lập. ✅ Ưu điểm của Cách tiếp cận Modular:

  • ✔️ Cô lập tốt hơn — Cập nhật EC2 sẽ không ảnh hưởng đến RDS.
  • ✔️ Triển khai nhanh hơn & an toàn hơn — Chỉ áp dụng các thay đổi khi cần.
  • ✔️ Tự động hóa dễ dàng hơn — Với các công cụ CI/CD như GitHub Actions, chỉ kích hoạt chạy Terraform cho các thành phần đã thay đổi. ❌ Nhược điểm của Cách tiếp cận Modular:
  • ⛔ Yêu cầu tuần tự — Cân bằng tải phải được triển khai trước khi các EC2 instance được gắn vào.
  • ⛔ Tốn công thiết lập hơn — Bạn cần lên kế hoạch cách mỗi module tích hợp.

Nên chọn cái nào? Nó phụ thuộc vào nhu cầu dự án của bạn. Nếu bạn cần triển khai nhanh chóng và không mong đợi các thay đổi thường xuyên, Monorepo hoạt động. Tuy nhiên, để bảo trì lâu dài, Modular là một cách tiếp cận tốt hơn. Cá nhân tôi thích giữ các thành phần quan trọng (ví dụ: VPC, RDS, IAM) riêng biệt, đồng thời kết hợp các hạ tầng khác khi có thể.

Mẹo Terraform #9: Triển khai Tài nguyên trên nhiều Khu vực AWS với Provider Aliases! Một thách thức phổ biến trong hạ tầng đám mây là triển khai tài nguyên đến nhiều khu vực AWS mà không cần trùng lặp mã. Điều này đặc biệt quan trọng đối với các kịch bản Phục hồi sau thảm họa (DR), nơi chúng ta cần hạ tầng giống hệt nhau ở một khu vực thứ cấp.

Thay vì viết mã Terraform trùng lặp cho mỗi khu vực, chúng ta có thể sử dụng nhiều cấu hình nhà cung cấp với các bí danh để quản lý hiệu quả việc triển khai đa khu vực. 🔹 Nó hoạt động như thế nào? Khi gọi một module, bạn có thể chỉ định một bí danh nhà cung cấp khác để triển khai tài nguyên ở một khu vực khác.

📌 Tại sao nên sử dụng nhiều nhà cung cấp?

  • ✅ Không trùng lặp mã — Định nghĩa một lần, sử dụng nhiều lần.
  • ✅ Quản lý dễ dàng hơn — Giữ hạ tầng nhất quán trên các khu vực.
  • ✅ Sẵn sàng cho Phục hồi sau thảm họa — Triển khai liền mạch hạ tầng ở một khu vực dự phòng. Việc bí danh nhà cung cấp của Terraform giúp việc triển khai đa khu vực có thể mở rộng và dễ bảo trì!

Mẹo Terraform #10: Sử dụng các khối động (dynamic Blocks) cho các đối số có điều kiện trong Tài nguyên Khi làm việc với Terraform, chúng ta thường cần đặt các đối số có điều kiện trong một tài nguyên thay vì tạo các tài nguyên riêng biệt. Thay vì trùng lặp định nghĩa tài nguyên hoặc tạo các module không cần thiết, khối động của Terraform cho phép chúng ta có điều kiện bao gồm các đối số chỉ khi cần!

🔹 Ví dụ 1: Thêm có điều kiện Chính sách định tuyến theo trọng số (Weighted Routing Policy) trong Route 53 Giả sử chúng ta cần tạo một bản ghi Route 53 theo trọng số chỉ khi cờ weighted được đặt thành true. Thay vì luôn định nghĩa weighted_routing_policy, chúng ta sử dụng một khối động để thêm đối số chỉ khi cần.

🔹 Ví dụ 2: Bật có điều kiện Stickiness trong một ALB Target Group Trong AWS ALB Target Groups, stickiness không phải lúc nào cũng cần thiết. Thay vì duy trì hai định nghĩa nhóm mục tiêu riêng biệt, chúng ta có thể thêm có điều kiện đối số stickiness.

💡 Tại sao nên sử dụng các khối động cho các đối số?

  • ✔️ Tránh các cấu hình không cần thiết — Chỉ bao gồm các đối số khi cần.
  • ✔️ Cải thiện khả năng bảo trì — Không cần các tài nguyên hoặc module riêng biệt.
  • ✔️ Nâng cao tính linh hoạt — Chuyển đổi cấu hình động dựa trên các cờ. Chúng tôi đã sử dụng rộng rãi các khối động trong các dự án của mình để xử lý các đối số tùy chọn một cách hiệu quả mà không cần sửa đổi định nghĩa tài nguyên! Hy vọng mẹo này sẽ giúp ích trong hành trình Terraform của bạn.
Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận