Rủi ro tiềm ẩn từ Infrastructure Drift
Bất kỳ ai từng quản lý hạ tầng đám mây đều hiểu cảm giác lo lắng vào lúc 3 giờ sáng. Bạn đã dành nhiều tuần để hoàn thiện các module Terraform, đảm bảo mọi security group và S3 bucket đều được định nghĩa trong mã nguồn. Thế rồi, một sự cố production xảy ra. Một đồng nghiệp đăng nhập vào AWS Console, thêm thủ công một inbound rule vào security group để khôi phục dịch vụ, và rồi quên cập nhật lại mã nguồn vào sáng hôm sau.
Đây chính là Infrastructure Drift (Sự sai lệch hạ tầng). Nó là nỗi đau đầu triền miên đối với các đội ngũ DevOps. Theo thời gian, môi trường thực tế và kho lưu trữ Git của bạn không còn khớp nhau nữa. Khi bạn chạy terraform apply vào hai tuần sau đó, bạn có thể vô tình ghi đè lên một bản sửa lỗi thủ công quan trọng. Tệ hơn nữa, bạn có thể không nhận ra rằng một lập trình viên nào đó đã khởi chạy một instance p3.16xlarge đắt đỏ đang tiêu tốn 24 USD mỗi giờ.
Tôi đã triển khai phát hiện drift trong nhiều môi trường production khác nhau. Kết quả mang lại là tức thì. Bằng cách sử dụng Driftctl, chúng tôi đã chuyển từ việc chữa cháy thụ động sang quản trị chủ động.
Tại sao Terraform Plan thường không mang lại bức tranh toàn cảnh
Một sai lầm phổ biến là giả định rằng terraform plan sẽ bắt được mọi thứ. Thực tế không phải vậy. Terraform chỉ theo dõi các tài nguyên được liệt kê trong tệp state của nó. Nếu một người dùng tạo thủ công một cơ sở dữ liệu RDS mới hoặc một IAM user thông qua console, terraform plan sẽ hoàn toàn bỏ qua nó. Công cụ này đơn giản là thiếu khả năng hiển thị đối với các tài nguyên mà nó không trực tiếp tạo ra.
Driftctl lấp đầy khoảng trống hiển thị này. Nó quét nhà cung cấp đám mây của bạn (AWS, Azure hoặc GCP) và so sánh mọi tài nguyên tìm thấy với state của Terraform. Nó phân loại các phát hiện thành ba nhóm:
- Managed (Được quản lý): Các tài nguyên trong mã nguồn khớp chính xác với thực tế trên cloud.
- Drifted (Bị lệch): Các tài nguyên trong mã nguồn đã bị ai đó chỉnh sửa thủ công.
- Unmanaged (Không được quản lý): Các tài nguyên tồn tại trên cloud nhưng thiếu trong mã nguồn của bạn. Đây thường là nơi ẩn náu của các lỗ hổng bảo mật.
Cài đặt Driftctl
Việc cài đặt rất đơn giản vì Driftctl là một tệp thực thi (binary) viết bằng Go. Nếu bạn đang dùng macOS hoặc Linux với Homebrew, hãy chạy lệnh sau:
brew install driftctl
Đối với các pipeline CI/CD, hãy tải trực tiếp tệp binary từ GitHub releases của Snyk/Driftctl. Công cụ này sử dụng thông tin xác thực cloud hiện có của bạn. Nếu AWS CLI của bạn đã được cấu hình profile, Driftctl sẽ tự động sử dụng nó mà không cần thiết lập thêm.
Quét hạ tầng của bạn
Lệnh driftctl scan là công cụ chính của bạn. Để có kết quả chính xác, hãy trỏ công cụ đến tệp remote state của bạn, thường được lưu trữ trong một S3 bucket.
# Quét AWS và so sánh với tệp state từ xa trên S3
driftctl scan --from tfstate+s3://my-terraform-state-bucket/project/terraform.tfstate
Lần quét đầu tiên thường là một hồi chuông cảnh tỉnh. Trong một dự án, báo cáo ban đầu của chúng tôi đã tiết lộ 42 tài nguyên không được quản lý. Chúng bao gồm các VPC mặc định bị lãng quên, các IAM role cũ từ một đợt di chuyển năm 2021 và các Lambda function thử nghiệm vẫn còn đang hoạt động.
Lọc nhiễu với .driftignore
Không phải mọi tài nguyên không được quản lý đều cần bạn bận tâm. Bạn có thể có các hệ thống cũ (legacy) hoặc các tài nguyên được quản lý bởi các công cụ khác như Kubernetes. Để giữ cho báo cáo sạch sẽ, hãy tạo một tệp .driftignore trong thư mục gốc của dự án.
# .driftignore
# Bỏ qua tất cả các tài nguyên AWS mặc định mà chúng tôi không quản lý
aws_default_vpc.*
aws_default_security_group.*
# Bỏ qua một bucket cũ cụ thể được sử dụng bởi đội ngũ dữ liệu
aws_s3_bucket.legacy-archive-2020
# Bỏ qua các tài nguyên có tag cụ thể
*::tags.Environment: development
Các cảnh báo có ý nghĩa là chìa khóa của thành công. Nếu công cụ của bạn báo cáo 100 cảnh báo giả mỗi ngày, đội ngũ của bạn cuối cùng sẽ ngừng kiểm tra các bản nhật ký (logs).
Tự động hóa phát hiện trong CI/CD
Quét thủ công thì tốt hơn là không làm gì, nhưng tự động hóa mới mang lại sự bảo mật thực sự. Tôi khuyên bạn nên lên lịch quét drift bốn giờ một lần. Tần suất này đảm bảo bạn bắt được các thay đổi trên console nhanh chóng, ngay cả khi không có ai chạm vào mã Terraform trong nhiều ngày.
Dưới đây là một workflow GitHub Actions tinh gọn để quét tự động:
name: Phát hiện Infrastructure Drift
on:
schedule:
- cron: '0 */4 * * *'
workflow_dispatch:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Kiểm tra mã nguồn (Checkout code)
uses: actions/checkout@v3
- name: Cài đặt Driftctl
run: |
curl -L https://github.com/snyk/driftctl/releases/latest/download/driftctl_linux_amd64 -o driftctl
chmod +x driftctl
sudo mv driftctl /usr/local/bin/
- name: Chạy Driftctl Scan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: "us-east-1"
run: |
driftctl scan --from tfstate+s3://my-prod-bucket/terraform.tfstate --output json://drift-report.json
- name: Cảnh báo khi có Drift
if: failure()
run: |
echo "Phát hiện Drift trên môi trường production! Đang gửi tóm tắt tới Slack..."
# Chèn logic cho Slack webhook hoặc thông báo SNS tại đây
Driftctl trả về một mã thoát (exit code) khác không khi nó tìm thấy sự sai lệch. Hành vi này giúp dễ dàng kích hoạt điều kiện if: failure() và thông báo cho đội ngũ của bạn ngay lập tức.
Bài học kinh nghiệm thực tế
Sau khi chạy Driftctl trên nhiều tài khoản AWS, tôi đã xác định được một số phương pháp giúp cải thiện trải nghiệm:
- Bắt đầu nhỏ: Tránh quét toàn bộ AWS Organization của bạn ngay ngày đầu tiên. Hãy tập trung vào một tệp state duy nhất hoặc một region cụ thể trước. Dọn sạch các cảnh báo nhiễu đó trước khi mở rộng phạm vi.
- Tiêu chuẩn hóa Tagging: Sử dụng các tag nhất quán trên tất cả tài nguyên. Driftctl có thể lọc theo tag, điều này giúp loại trừ các tài nguyên dùng chung hoặc các tài sản được quản lý bởi bên thứ ba.
- Ưu tiên khả năng hiển thị: Một báo cáo bị chôn vùi trong log CI/CD là vô dụng. Hãy sử dụng đầu ra JSON để đẩy bản tóm tắt lên Slack hoặc PagerDuty. Biết chính xác những gì đã thay đổi chỉ trong vài giờ sau khi chỉnh sửa thủ công là một lợi thế rất lớn.
- Thực thi chính sách “Sửa Drift”: Khi drift xuất hiện, bạn có hai lựa chọn. Bạn có thể cập nhật mã Terraform để khớp với thực tế mới, hoặc bạn có thể hoàn tác thay đổi thủ công đó. Đừng để drift tồn tại quá 24 giờ.
Đảm bảo Source of Truth
Infrastructure as Code chỉ mang lại giá trị nếu mã nguồn phản ánh chính xác môi trường production. Không có một công cụ như Driftctl, các bản khai báo Terraform của bạn chỉ là một lời gợi ý thay vì là một hồ sơ xác thực duy nhất. Quét tự động giúp thực thi văn hóa “Code First”, nơi các thay đổi thủ công luôn bị phát hiện và không được khuyến khích.
Việc dọn dẹp các phát hiện ban đầu cần nỗ lực, nhưng sự an tâm mà nó mang lại là hoàn toàn xứng đáng. Bạn sẽ ngăn chặn được các tài nguyên “ma” làm tăng hóa đơn của mình. Quan trọng hơn, bạn đảm bảo rằng các kế hoạch khắc phục thảm họa—vốn phụ thuộc hoàn toàn vào mã nguồn của bạn—sẽ thực sự hoạt động khi bạn cần chúng nhất.

