Chiến lược nâng cấp Terraform và Crossplane không gián đoạn
Để nâng cấp Terraform mà không làm gián đoạn hạ tầng đang vận hành, ta thực hiện chiến lược "Blue-Green" hoặc "Canary" bằng cách sử dụng hai workspace riêng biệt hoặc hai thư mục state khác nhau cho phiên bản cũ và mới.
Trước khi nâng cấp, cần kiểm tra trạng thái hiện tại của Terraform để đảm bảo không có pending change nào đang chờ xử lý.
terraform plan -out=tfplan_upgrade_check
Kết quả mong đợi: Terraform hiển thị "No changes. Your infrastructure matches the configuration." hoặc liệt kê rõ các thay đổi đã được phê duyệt.
Tiếp theo, tạo một bản sao của file state hiện tại để làm điểm khôi phục (rollback) trong trường hợp nâng cấp thất bại.
cp terraform.tfstate terraform.tfstate.backup
Kết quả mong đợi: File backup được tạo thành công cùng thư mục cấu hình.
Nâng cấp Terraform lên phiên bản mới nhất (ví dụ từ 1.5.x lên 1.6.x) bằng cách sử dụng tool quản lý phiên bản như tfenv hoặc cài đặt trực tiếp trên server.
tfenv install 1.6.5 && tfenv use 1.6.5
Kết quả mong đợi: Command `terraform version` trả về phiên bản mới 1.6.5.
Thực hiện lệnh `terraform init` để cập nhật providers mới và đồng bộ state với phiên bản Terraform mới. Lệnh này rất quan trọng để tránh lỗi schema.
terraform init -upgrade
Kết quả mong đợi: Terraform tải xuống các providers mới nhất và xác nhận "Terraform has been successfully initialized!"
Chạy `terraform plan` một lần nữa để kiểm tra xem có thay đổi nào không mong muốn do sự khác biệt giữa các phiên bản providers.
terraform plan
Kết quả mong đợi: Nếu không có thay đổi cấu hình logic, kết quả phải là "No changes." Nếu có thay đổi, phân tích kỹ xem đó là do drift hay do thay đổi schema của provider.
Đối với Crossplane, việc nâng cấp Cluster Resource Definition (XRD) hoặc Composition cần thực hiện qua Kubernetes API. Crossplane hỗ trợ nâng cấp in-place nếu schema tương thích.
kubectl apply -f crossplane-upgrade-manifest.yaml
Kết quả mong đợi: Kubernetes cập nhật các Custom Resource Definition (CRD) và các controller mới mà không xóa resource đang chạy.
Verify trạng thái của các Managed Resource sau khi nâng cấp Crossplane.
kubectl get managed -A | grep -v "SYNCED"
Kết quả mong đợi: Không có resource nào ở trạng thái "Reconciling" hoặc "Unavailable" sau khi nâng cấp ổn định.
Xử lý thay đổi cấu hình phức tạp qua GitOps workflow
Khi cấu hình Terraform hoặc Crossplane trở nên phức tạp (ví dụ: thay đổi thuộc tính không thể thay đổi hot-fix), ta cần dùng GitOps để quản lý trạng thái mong muốn (desired state) thay vì thay đổi trực tiếp trên server.
Thiết lập cấu trúc thư mục Git để tách biệt giữa Infrastructure as Code (IaC) và Configuration Management.
mkdir -p infrastructure/terraform infrastructure/crossplane && cd infrastructure
Kết quả mong đợi: Các thư mục được tạo, sẵn sàng nhận code.
Viết file Terraform cho một thay đổi phức tạp, ví dụ: thay đổi kích thước instance từ t3.micro lên t3.small. Lưu ý rằng với EC2, việc thay đổi instance type thường yêu cầu tạo instance mới.
cat > infrastructure/terraform/main.tf
Kết quả mong đợi: File `main.tf` được tạo với cấu hình instance mới.
Commit thay đổi lên Git repository. Đây là bước kích hoạt workflow GitOps.
git add . && git commit -m "feat: upgrade app server to t3.small"
Kết quả mong đợi: Commit được đẩy lên remote branch (ví dụ: main hoặc develop).
Cấu hình ArgoCD để sync repository này vào namespace `infrastructure`. ArgoCD sẽ phát hiện thay đổi và tự động chạy `terraform plan` (nếu có hook) hoặc `terraform apply`.
cat > argocd-app.yaml
Kết quả mong đợi: File `argocd-app.yaml` được tạo để định nghĩa ứng dụng ArgoCD.
Áp dụng file ArgoCD để kích hoạt quy trình GitOps.
kubectl apply -f argocd-app.yaml
Kết quả mong đợi: Application `terraform-hybrid` xuất hiện trong namespace `argocd` và trạng thái chuyển sang `Syncing`.
Đối với Crossplane, xử lý thay đổi phức tạp bằng cách cập nhật Custom Resource (XR) trong Git. Crossplane sẽ tự động reconcile sự thay đổi.
cat > infrastructure/crossplane/postgres.yaml
Kết quả mong đợi: File YAML được tạo với thông số storage mới.
Commit và đẩy lên Git để ArgoCD tự động sync vào cluster Kubernetes.
git add . && git push origin main
Kết quả mong đợi: ArgoCD phát hiện thay đổi, thực hiện sync, và Crossplane bắt đầu quá trình resize storage mà không cần downtime (nếu engine hỗ trợ).
Verify kết quả bằng cách kiểm tra trạng thái của resource trong Kubernetes và AWS/Proxmox.
kubectl describe postgrescluster prod-db
Kết quả mong đợi: Field `storageSize` trong `status` hiện là `100Gi` và trạng thái là `Synced`.
Tự động hóa việc xóa tài nguyên khi không còn cần thiết
Để tránh "zombie resources" (tài nguyên chết) tốn phí, cần cơ chế tự động xóa tài nguyên khi chúng không còn được định nghĩa trong code Terraform hoặc Crossplane.
Trong Terraform, kích hoạt tùy chọn `prune` trong ArgoCD hoặc chạy `terraform plan` để xem các tài nguyên sẽ bị xóa.
terraform plan -detailed-exitcode
Kết quả mong đợi: Terraform hiển thị dấu `-` trước các resource sẽ bị xóa (ví dụ: `- (will be destroyed)`).
Cấu hình ArgoCD để tự động xóa resource Kubernetes khi chúng bị xóa khỏi Git. Điều này áp dụng cho cả Managed Resource của Crossplane.
cat > argocd-prune-policy.yaml
Kết quả mong đợi: Policy cho phép tự động sync và prune trong khung giờ nhất định.
Để xóa tài nguyên Crossplane, chỉ cần xóa file YAML định nghĩa resource khỏi Git repository.
rm infrastructure/crossplane/old-service.yaml && git add . && git commit -m "chore: remove old service"
Kết quả mong đợi: File bị xóa khỏi Git, ArgoCD nhận diện sự thay đổi.
ArgoCD sẽ kích hoạt lệnh `kubectl delete` tương ứng, từ đó Crossplane Controller sẽ phát hiện và gọi API của AWS/Proxmox để xóa tài nguyên thực tế.
argocd app sync terraform-hybrid --prune
Kết quả mong đợi: Terminal hiển thị "Synchronizing..." và sau đó "Synced" với số lượng resource giảm đi.
Trong Terraform, sử dụng `depends_on` hoặc `lifecycle { prevent_destroy = false }` để đảm bảo resource có thể bị xóa nếu không còn phụ thuộc.
resource "aws_instance" "temp" {
# ... config
lifecycle {
prevent_destroy = false
}
}
Kết quả mong đợi: Resource `temp` sẽ bị xóa khỏi state khi file config bị xóa.
Verify việc xóa tài nguyên thực tế trên AWS Console hoặc Proxmox Web UI.
aws ec2 describe-instances --filters "Name=tag:Name,Values=old-service" --query "Reservations[].Instances[].InstanceId"
Kết quả mong đợi: Kết quả trả về là một danh sách rỗng `[]`, chứng tỏ instance đã bị xóa.
Tích hợp CI/CD để test code Terraform trước khi áp dụng
Để đảm bảo an toàn, mọi thay đổi Terraform phải trải qua quy trình CI (Continuous Integration) trước khi được phép merge vào nhánh chính.
Thiết lập pipeline GitHub Actions (hoặc GitLab CI) để chạy `terraform fmt`, `terraform validate`, và `terraform plan` tự động trên Pull Request.
mkdir -p .github/workflows && cat > .github/workflows/terraform-checks.yml
Kết quả mong đợi: File workflow được tạo trong thư mục `.github/workflows`.
Thêm bước kiểm tra định dạng code để đảm bảo code sạch sẽ trước khi merge.
echo "terraform fmt -check" >> .github/workflows/terraform-checks.yml
Kết quả mong đợi: Bước kiểm tra định dạng được thêm vào pipeline.
Commit file workflow lên repository để kích hoạt CI.
git add .github/workflows && git commit -m "ci: add terraform checks pipeline"
Kết quả mong đợi: GitHub Actions bắt đầu chạy khi có Pull Request mới.
Tự động hóa việc tạo comment vào Pull Request để hiển thị kết quả `terraform plan` cho người review.
cat >> .github/workflows/terraform-checks.yml
Kết quả mong đợi: Pipeline được cập nhật để hiển thị kết quả plan trực tiếp trên PR.
Verify pipeline bằng cách tạo một Pull Request với một thay đổi nhỏ trong file Terraform.
echo "resource \"null_resource\" \"test\" {}" >> infrastructure/terraform/main.tf && git add . && git commit -m "test: add null resource"
Kết quả mong đợi: Khi push lên remote, GitHub Actions chạy và hiển thị kết quả validate/plan trong tab "Checks" của PR.
Để pipeline CI có thể truy cập AWS/Proxmox, cần cấu hình Secrets (Environment Variables) cho API keys.
echo "AWS_ACCESS_KEY_ID" | gh secret set AWS_ACCESS_KEY_ID --repo your-org/hybrid-infra
Kết quả mong đợi: Secret được lưu trữ an toàn trên GitHub và có thể dùng trong workflow.
Verify toàn bộ quy trình bằng cách merge PR sau khi CI thông qua (green checkmark).
git merge main
Kết quả mong đợi: Code được merge vào nhánh chính và ArgoCD tự động kích hoạt `terraform apply` (nếu cấu hình đúng) để áp dụng thay đổi.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng Multi-Cloud Hybrid với Terraform, Crossplane và GitOps trên hạ tầng Proxmox và AWS
« Phần 6: Triển khai GitOps với ArgoCD trên nền tảng Hybrid
Phần 8: Bảo mật và quản lý truy cập cho nền tảng Multi-Cloud »