So sánh phương pháp: Terraform vs. OpenTofu trong Pipeline tự động hóa
Vào ngày 10 tháng 8 năm 2023, HashiCorp đã chuyển Terraform từ giấy phép mã nguồn mở MPL 2.0 sang Business Source License (BSL 1.1). Sự thay đổi giấy phép này lập tức làm dấy lên nhiều dấu hỏi cho các platform team. Liệu việc xây dựng các internal developer platform có vi phạm các điều khoản của BSL hay không?
Liệu các nhà cung cấp dịch vụ quản lý (MSP) có thể tiếp tục cung cấp giải pháp tự động hóa dựa trên Terraform cho khách hàng? Để giải quyết vấn đề này, các công ty bao gồm Gruntwork, Spacelift và Env0 đã khởi xướng OpenTofu. Hiện được quản lý bởi Linux Foundation, OpenTofu cung cấp một bản fork độc lập với giấy phép mã nguồn mở vĩnh viễn.
Các đội ngũ DevOps khi đánh giá quy trình continuous delivery hiện nay đứng trước hai lựa chọn rõ ràng:
- Ở lại với Terraform: Bạn giữ nguyên bộ công cụ hiện tại và khả năng tích hợp HashiCorp Cloud. Tuy nhiên, đội ngũ pháp chế và platform của bạn phải rà soát toàn bộ hệ thống tự động hóa thương mại, sản phẩm cạnh tranh và công cụ nội bộ để đảm bảo tuân thủ BSL.
- Chuyển sang OpenTofu: OpenTofu được fork từ Terraform 1.5.6 và tương thích hoàn toàn với các cấu hình Terraform 1.5.7. Các tệp HCL hiện có, remote state backend và các community provider đều hoạt động bình thường mà không cần sửa đổi theo giấy phép MPL 2.0.
Cả hai file nhị phân (binary) đều chia sẻ vòng lặp thực thi tương tự nhau. Chúng tải về các plugin provider, tính toán chênh lệch (diff) tài nguyên so với state, và áp dụng (apply) các thay đổi đã được phê duyệt. Việc di chuyển CI/CD pipeline chỉ cần ba bước: thay đổi CLI binary, trỏ đến OpenTofu registry và xác minh cơ chế khóa state backend.
Ưu & nhược điểm khi chuyển sang OpenTofu
Trước khi cập nhật runner trên hàng loạt repository, hãy cân nhắc giữa lợi ích vận hành đạt được và rào cản khi chuyển đổi.
Các ưu điểm
- Sự quản trị độc lập từ Foundation: OpenTofu hoạt động dưới sự bảo trợ của Linux Foundation. Lộ trình phát triển, các RFC và chu kỳ phát hành đều trung lập với nhà cung cấp. Không có bất kỳ công ty đơn lẻ nào có thể đơn phương thay đổi giấy phép trong các bản phát hành tương lai.
- Tương thích CLI 1:1 trực tiếp: Các lệnh ánh xạ 1:1. Bạn có thể chạy
tofu init,tofu planvàtofu applyvới chính xác các đối số và flag mà đội ngũ của bạn đang sử dụng với Terraform. - Khả năng tương thích State liền mạch: Nếu hạ tầng của bạn đang chạy trên Terraform 1.5.7 trở về trước, OpenTofu có thể đọc trực tiếp State Format v4 hiện tại. Bạn không cần phải chuyển đổi JSON schema phức tạp hay reset lại state.
- Mã hóa State phía Client: Bắt đầu từ phiên bản 1.7.0, OpenTofu đã giới thiệu tính năng mã hóa state nguyên bản (native). Bạn có thể mã hóa các biến nhạy cảm và secret trực tiếp trên runner bằng AWS KMS, GCP KMS hoặc AES-GCM trước khi ghi vào remote object storage.
Các hạn chế tiềm ẩn
- Sự phân nhánh tính năng: Khả năng tương thích vẫn rất tốt với cú pháp HCL cốt lõi. Tuy nhiên, các tính năng độc quyền được giới thiệu từ Terraform 1.7 trở đi (chẳng hạn như test mock hay một số provider function cụ thể) sẽ không tự động có mặt trên OpenTofu.
- Hệ sinh thái đóng gói trên CI: HashiCorp duy trì sẵn các bước thiết lập tích hợp trên một số marketplace đám mây. Việc chuyển sang OpenTofu yêu cầu cập nhật file YAML pipeline của bạn để sử dụng action chính thức
opentofu/setup-opentofuhoặc container image tương ứng.
Đối với hầu hết platform team, quá trình chuyển đổi chỉ mất chưa đầy hai giờ cho mỗi repository. Lợi ích mang lại là tức thì: hoàn toàn độc lập khỏi các ràng buộc giấy phép thương mại từ phía thượng nguồn.
Cấu hình khuyến nghị cho OpenTofu CI/CD Pipeline
Việc thực thi IaC trong CI/CD đòi hỏi sự cô lập nghiêm ngặt. Một kiến trúc an toàn phụ thuộc vào bốn nguyên tắc bảo vệ cốt lõi sau:
- Xác thực OIDC không dùng khóa (Keyless): Loại bỏ thông tin xác thực đám mây tĩnh khỏi repository secret. Sử dụng OpenID Connect (OIDC) để liên kết xác thực giữa CI runner và nhà cung cấp dịch vụ đám mây. AWS IAM, Google Cloud Workload Identity và Azure Entra ID đều hỗ trợ cấp token ngắn hạn (thường là 1 giờ) trực tiếp cho các pipeline job đã được xác minh.
- Lưu trữ State với cơ chế Khóa phân tán (Distributed Locking): Lưu trữ state trên remote storage chuyên dụng, chẳng hạn như Amazon S3 kết hợp DynamoDB hoặc Google Cloud Storage đã bật object locking. Việc khóa kịp thời sẽ ngăn chặn race condition và làm hỏng state khi các pull request chạy song song kích hoạt plan chồng chéo lên nhau.
- Tách biệt giai đoạn Plan và Apply: Tự động chạy
tofu plantrên các pull request. Xuất bản tóm tắt kết quả plan trực tiếp vào comment của PR để người review có thể kiểm tra thay đổi trước khi merge. Giới hạn nghiêm ngặt chỉ chạytofu applycho các commit đã được merge vào nhánhmain. - Ghim phiên bản nghiêm ngặt: Cố định rõ ràng cả phiên bản binary OpenTofu (ví dụ:
1.8.2) và phiên bản provider (ví dụ: AWS provider~> 5.40). Việc ghim phiên bản giúp ngăn chặn các bản build tự động bị lỗi khi registry thượng nguồn phát hành các bản cập nhật lớn (major update).
Hướng dẫn triển khai: Di chuyển từ Terraform sang OpenTofu trong GitHub Actions
Hãy làm theo các bước dưới đây để chuyển đổi một repository Terraform hiện có sang workflow GitHub Actions an toàn với OpenTofu.
Bước 1: Kiểm thử dự án cục bộ với OpenTofu CLI
Đảm bảo mã nguồn hoạt động tốt ở môi trường cục bộ trước khi commit thay đổi lên pipeline. Cài đặt OpenTofu và kiểm tra quá trình khởi tạo:
# Cài đặt OpenTofu trên Ubuntu/Debian bằng script cài đặt chính thức
curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh -o install-opentofu.sh
chmod +x install-opentofu.sh
./install-opentofu.sh --install-method deb
rm -f install-opentofu.sh
# Kiểm tra thư mục dự án của bạn
cd my-infrastructure-repo/
tofu init
tofu plan
Nếu lệnh plan hoàn tất mà không có cảnh báo về schema hay lỗi provider, codebase của bạn đã sẵn sàng để tự động hóa.
Bước 2: Cập nhật cấu hình phiên bản
Mở file versions.tf. Thiết lập ràng buộc phiên bản yêu cầu để hỗ trợ các bản phát hành OpenTofu và duy trì S3 backend được mã hóa:
terraform {
# Chấp nhận OpenTofu 1.6+ hoặc Terraform 1.5.7
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.40"
}
}
backend "s3" {
bucket = "corp-infrastructure-tfstate-prod"
key = "networking/vpc-production.tfstate"
region = "us-east-1"
dynamodb_table = "corp-tfstate-locks"
encrypt = true
}
}
Bước 3: Xây dựng GitHub Actions Pipeline
Tạo file .github/workflows/opentofu.yml. Workflow này sẽ xác thực qua AWS OIDC, kiểm tra định dạng code, đăng kết quả plan vào pull request và tự động apply thay đổi khi merge.
name: "Pipeline hạ tầng OpenTofu"
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
tofu:
name: "OpenTofu Plan & Apply"
runs-on: ubuntu-latest
steps:
- name: Checkout mã nguồn
uses: actions/checkout@v4
- name: Cấu hình thông tin xác thực AWS qua OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-opentofu
aws-region: us-east-1
- name: Cài đặt OpenTofu
uses: opentofu/setup-opentofu@v1
with:
tofu_version: 1.8.2
- name: Khởi tạo OpenTofu
run: tofu init
- name: Kiểm tra định dạng
run: tofu fmt -check
- name: Chạy Speculative Plan
id: plan
if: github.event_name == 'pull_request'
run: |
tofu plan -no-color -out=plan.tfplan
continue-on-error: false
- name: Đăng tóm tắt Plan lên Pull Request
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const body = `#### Kết quả Plan của OpenTofu: \`Thành công\`
* **Được push bởi:** @${context.actor}
* **Hành động:** \`${context.eventName}\`
* **Nhánh đích:** \`${context.payload.pull_request.base.ref}\``;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
- name: Áp dụng State đã phê duyệt
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: tofu apply -auto-approve
Bước 4: Thực hiện chuyển đổi và kiểm tra tính toàn vẹn của State
Triển khai workflow đã cập nhật lên nhánh staging trước. Kiểm tra log của GitHub Actions runner để xác nhận rằng tofu init đã lấy được khóa DynamoDB thành công và đọc S3 state bucket mà không có lỗi.
Trước khi triển khai chính thức trên môi trường production, hãy hoàn thành hai bước bảo vệ thiết yếu sau:
- Sao lưu remote state: Chạy
aws s3 cp s3://corp-infrastructure-tfstate-prod/ ./backup-state/ --recursiveđể tạo một bản snapshot chính xác trước lần chạy đầu tiên. - Chuẩn hóa môi trường làm việc của lập trình viên: Yêu cầu tất cả thành viên trong nhóm cài đặt
tofuở máy cục bộ. Nếu một lập trình viên chạy phiên bản Terraform độc quyền mới hơn (như Terraform 1.9+) tại máy cá nhân, nó có thể nâng cấp phiên bản schema của state và khiến OpenTofu pipeline của bạn bị khóa, không thể xử lý tiếp.

