1. Infrastructure Drift là gì?
Infrastructure Drift là tình trạng khi trạng thái thực tế của hạ tầng (infrastructure) không khớp với mô tả của mã hạ tầng. Nó xảy ra khi các thay đổi được thực hiện trực tiếp trên hạ tầng mà không thông qua Terraform, làm cho trạng thái hiện tại không phù hợp với mã hạ tầng được định nghĩa bởi Terraform. Điều này có thể gây ra rủi ro cho hạ tầng và dẫn đến khó khăn trong việc quản lý và triển khai hạ tầng.
2. Cú pháp khai báo.
Cú pháp khai báo để phát hiện Infrastructure Drift trong Terraform là sử dụng lệnh terraform plan
. Lệnh này so sánh trạng thái hiện tại của hạ tầng với mô tả của mã hạ tầng được định nghĩa trong file Terraform, và tạo ra một kế hoạch cập nhật để đưa trạng thái hiện tại của hạ tầng về trạng thái đã định nghĩa. Khi sử dụng terraform plan
, Terraform sẽ phát hiện ra những sự khác biệt giữa trạng thái hiện tại và trạng thái được định nghĩa trong file Terraform, giúp phát hiện ra Infrastructure Drift.
Để sửa chữa Infrastructure Drift, ta có thể sử dụng lệnh terraform apply
để cập nhật trạng thái hiện tại của hạ tầng với trạng thái đã định nghĩa trong file Terraform. Lệnh terraform apply
thực thi kế hoạch cập nhật đã được tạo ra bởi lệnh terraform plan
, để đưa trạng thái hiện tại của hạ tầng về trạng thái đã định nghĩa.
3. Các lưu ý khi sử dụng Infrastructure Drift.
Để giải quyết vấn đề Infrastructure Drift trong Terraform, có một số lưu ý cần lưu ý như sau:
- Thực hiện regular refresh: Nên thực hiện refresh thường xuyên để cập nhật trạng thái hệ thống với tài nguyên thực tế đang hoạt động.
- Thực hiện Plan và Apply thường xuyên: Nếu phát hiện drift, cần thực hiện lại Plan và Apply để đồng bộ lại trạng thái hệ thống với mã nguồn.
- Sử dụng Terraform State: Sử dụng Terraform State để lưu trữ thông tin về trạng thái của tất cả các tài nguyên hệ thống, từ đó có thể so sánh và phát hiện drift.
- Sử dụng Monitoring tool: Sử dụng các công cụ giám sát hệ thống như Prometheus, Nagios, Zabbix, … để phát hiện drift và đưa ra cảnh báo.
- Tối ưu hóa cấu trúc mã: Cấu trúc mã của Terraform cần được tối ưu hóa để giảm thiểu các lỗi khi áp dụng thay đổi vào hệ thống.
- Thực hiện version control: Việc sử dụng version control giúp quản lý và theo dõi các thay đổi về mã nguồn, từ đó giúp phát hiện và giải quyết drift.
- Sử dụng kiểm thử tự động: Sử dụng các công cụ kiểm thử tự động để giúp phát hiện drift ngay khi các thay đổi được áp dụng.
- Thực hiện khôi phục dự phòng: Để giải quyết trường hợp xấu nhất về drift, nên thực hiện khôi phục dự phòng cho các tài nguyên hệ thống.
- Trong quá trình sử dụng Terraform, người dùng cần cẩn thận và thường xuyên kiểm tra và cập nhật các tài nguyên để tránh drift và đảm bảo tính nhất quán của hệ thống.
4. Ví dụ minh hoạ.
4.1. Ví dụ 1.
Ví dụ về Infrastructure Drift của hệ thống KVM có thể là khi chúng ta đã tạo một máy ảo trong KVM bằng Terraform, sau đó đã thực hiện thay đổi một số thuộc tính của máy ảo đó trực tiếp trên KVM mà không thông qua Terraform. Khi đó, Terraform không biết về sự thay đổi này và sẽ ghi đè lên những thay đổi đó khi chúng ta thực hiện một lệnh apply.
Ví dụ cụ thể, giả sử chúng ta có một mã Terraform để tạo máy ảo KVM như sau:
resource "libvirt_domain" "example" {
name = "example-vm"
memory = "1024"
vcpu = "1"
disk {
volume_id = "example-volume"
}
network_interface {
network_id = "example-network"
}
}
Sau khi chạy lệnh terraform apply
, Terraform sẽ tạo máy ảo KVM và lưu trạng thái của nó vào state file. Bây giờ, nếu chúng ta thay đổi một số thuộc tính của máy ảo này trực tiếp trên KVM, ví dụ như thay đổi kích thước RAM từ 1024MB thành 2048MB, Terraform sẽ không biết về sự thay đổi này.
Khi chúng ta chạy lệnh terraform plan
hoặc terraform apply
sau đó, Terraform sẽ thấy sự khác biệt giữa trạng thái hiện tại của máy ảo và trạng thái mà nó lưu trữ trong state file. Vì vậy, nó sẽ cố gắng cập nhật trạng thái của máy ảo trong KVM để phù hợp với trạng thái mà nó lưu trữ trong state file. Tuy nhiên, do sự thay đổi đã được thực hiện trực tiếp trên KVM, Terraform không thể áp dụng trạng thái mới và sẽ trả về lỗi “Infrastructure drift detected”. Để khắc phục vấn đề này, chúng ta cần phải thực hiện cập nhật trạng thái trong Terraform bằng cách thực hiện lệnh terraform state
hoặc sử dụng các công cụ quản lý hạ tầng như Ansible để đồng bộ hóa trạng thái giữa Terraform và KVM.
Công cụ quản lý cấu hình như Ansible có thể được sử dụng để giải quyết vấn đề Infrastructure Drift. Cụ thể, các playbooks Ansible có thể được sử dụng để đưa tất cả các node trong hệ thống về trạng thái mong muốn.
Các bước để giải quyết vấn đề này bằng Ansible như sau:
- Xác định trạng thái mong muốn của các node trong hệ thống và định nghĩa như một playbook Ansible.
- Chạy playbook Ansible để đưa tất cả các node về trạng thái mong muốn.
- Theo dõi hệ thống để đảm bảo rằng các node vẫn đang ở trong trạng thái mong muốn. Nếu có bất kỳ thay đổi nào được thực hiện trên node, Ansible sẽ giúp phát hiện và đưa nó về trạng thái mong muốn.
Ví dụ, nếu một số gói phần mềm bị cập nhật trên một trong các node, có thể sử dụng Ansible để thực hiện lại cài đặt các gói phần mềm này trên tất cả các node trong hệ thống.
Sử dụng Ansible cũng giúp quản lý và theo dõi các thay đổi trên các node trong hệ thống một cách hiệu quả và đồng bộ, giúp giảm thiểu khả năng xảy ra Infrastructure Drift.
Để cấu hình Ansible để sửa lỗi Infrastructure Drift của hệ thống KVM, ta có thể sử dụng một số module của Ansible như libvirt_domain
, libvirt_pool
, và libvirt_volume
để kiểm tra các resource trong hệ thống KVM và cập nhật lại các thông tin trong Terraform State.
Ví dụ, để đảm bảo rằng các máy ảo trong hệ thống KVM được định nghĩa đúng trong Terraform State, ta có thể sử dụng module libvirt_domain
để kiểm tra các thông tin của các máy ảo như tên, bộ nhớ, số CPU, disk size, v.v. và so sánh với Terraform State. Nếu có sự khác biệt, ta có thể sử dụng module này để cập nhật lại các thông tin này trong Terraform State. Ví dụ cấu hình trong file playbook.yml như sau:
- name: Check and update libvirt domains
hosts: localhost
gather_facts: false
tasks:
- name: Get list of libvirt domains
libvirt_domain:
state: running
register: running_domains
- name: Check domain properties
libvirt_domain:
name: "{{ item.name }}"
loop: "{{ running_domains.domains }}"
register: domain_info
- name: Update Terraform State with domain changes
terraform:
command: state replace-provider
args:
- "-auto-approve"
- "libvirt_domain.vm"
- "libvirt_domain.vm:{{ domain_info.name }}"
- "{{ domain_info.xml|to_json }}"
when: domain_info.changed
Tương tự, ta có thể sử dụng các module khác như libvirt_pool
và libvirt_volume
để kiểm tra và cập nhật thông tin của các storage pool và volume trong hệ thống KVM.
Sau khi cấu hình playbook, ta có thể chạy playbook này để kiểm tra và sửa lỗi Infrastructure Drift bằng cách chạy lệnh ansible-playbook playbook.yml
.
4.2. Ví dụ 2.
Infrastructure Drift trong hệ thống AWS xảy ra khi cấu hình hiện tại của hệ thống đã khác với cấu hình được định nghĩa trong mã hạ tầng của Terraform. Ví dụ, nếu một số tài nguyên đã được tạo thủ công hoặc bằng các công cụ khác, thì chúng sẽ không được quản lý bởi Terraform và có thể dẫn đến sự không nhất quán trong hạ tầng.
Để giải quyết sự không nhất quán này, ta có thể sử dụng Terraform để so sánh cấu hình hiện tại với mã hạ tầng và xác định các sự khác biệt. Các bước sau đây có thể được thực hiện để xử lý Infrastructure Drift trong hệ thống AWS:
- Chạy lệnh
terraform plan
để tạo ra kế hoạch thay đổi cho mã hạ tầng. Lệnh này sẽ so sánh trạng thái hiện tại của hệ thống với mã hạ tầng và xác định các sự khác biệt. - Sử dụng output từ lệnh
terraform plan
để đối chiếu với hệ thống hiện tại và tìm hiểu những gì đã thay đổi trong hệ thống. - Nếu có sự khác biệt, ta có thể sử dụng lệnh
terraform apply
để áp dụng các thay đổi vào hệ thống. Lệnh này sẽ thực hiện các thay đổi được xác định trong bước 1 và cập nhật trạng thái của hệ thống. - Sau khi đã áp dụng các thay đổi, chạy lại lệnh
terraform plan
để đảm bảo rằng không còn sự không nhất quán nào trong hệ thống.
Ngoài ra, để giảm thiểu sự không nhất quán trong hệ thống, ta nên sử dụng Terraform để quản lý tất cả các tài nguyên trong hệ thống và tránh tạo ra tài nguyên thủ công hoặc sử dụng các công cụ khác để tạo ra tài nguyên.
Ví dụ sau đây mô tả về việc sử dụng Terraform để tạo và quản lý một tài nguyên EC2 instance trên AWS, sau đó sử dụng công cụ driftctl để phát hiện Infrastructure Drift:
Bước 1: Khai báo tài nguyên EC2 instance trong Terraform
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
Trong ví dụ này, chúng ta khai báo một tài nguyên EC2 instance trên khu vực “us-west-2” của AWS. AMI được sử dụng là “ami-0c55b159cbfafe1f0”, loại instance được chọn là “t2.micro”, và chúng ta gán một thẻ “Name” cho instance là “example-instance”.
Bước 2: Chạy lệnh terraform apply
để triển khai tài nguyên
Sau khi khai báo tài nguyên, chúng ta chạy lệnh terraform apply
để triển khai tài nguyên trên AWS. Terraform sẽ tạo một EC2 instance mới với cấu hình được chỉ định trong file Terraform.
Bước 3: Sử dụng driftctl để phát hiện Infrastructure Drift
Sau khi tài nguyên được triển khai, chúng ta sẽ sử dụng công cụ driftctl để phát hiện Infrastructure Drift. Để làm điều này, chúng ta chạy lệnh sau:
driftctl scan --from tfstate+s3://my-bucket/path/to/state --to aws://
Trong đó my-bucket/path/to/state
là đường dẫn tới file state của Terraform được lưu trữ trên S3. --from
và --to
là các tham số để chỉ định nguồn và đích của quá trình phát hiện Drift. Trong ví dụ này, chúng ta sử dụng nguồn là file state của Terraform được lưu trữ trên S3, và đích là tài khoản AWS hiện tại.
Nếu có sự khác biệt giữa trạng thái hiện tại của tài nguyên và trạng thái đã được khai báo trong Terraform, driftctl sẽ hiển thị các thông tin chi tiết về sự khác biệt này, cho phép người dùng có thể kiểm tra và sửa chữa sự sai khác này.
4.3. Ví dụ 3.
Giả sử chúng ta đã thay đổi tên của một EC2 instance trên AWS mà không sử dụng Terraform. Sự thay đổi này sẽ gây ra việc drift giữa trạng thái hiện tại của cơ sở hạ tầng và code mô tả hạ tầng (Infrastructure as Code).
Để phát hiện drift, chúng ta có thể sử dụng công cụ driftctl và kiểm tra sự khác biệt giữa cơ sở hạ tầng và code mô tả hạ tầng.
Ví dụ sau đây cho thấy cách driftctl phát hiện ra sự khác biệt trong tên của một EC2 instance trên AWS:
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
output "drift" {
value = system("driftctl --from tfstate+remote://terraform-aws-example/state.tfstate --to aws scan iac")
}
Trong ví dụ này, chúng ta đang khai báo một EC2 instance trên AWS bằng code mô tả hạ tầng (Terraform). Tên của instance được đặt là “example-instance”.
Sau đó, chúng ta sử dụng output để chạy lệnh driftctl để phát hiện sự khác biệt giữa cơ sở hạ tầng và code mô tả hạ tầng.
Lệnh driftctl --from tfstate+remote://terraform-aws-example/state.tfstate --to aws scan iac
sẽ quét cơ sở hạ tầng AWS hiện tại và so sánh với trạng thái hiện tại của code mô tả hạ tầng được lưu trữ trong file tfstate trên remote backend.
Nếu tên của EC2 instance đã được thay đổi từ “example-instance” thành “new-instance-name” trên AWS, driftctl sẽ phát hiện ra sự khác biệt này và xuất ra thông báo drift.
Để sửa lỗi này, chúng ta có thể cập nhật code mô tả hạ tầng bằng cách thay đổi tên của EC2 instance thành “new-instance-name” trong file mã nguồn Terraform và chạy lệnh terraform apply để cập nhật cơ sở hạ tầng trên AWS. Sau đó, driftctl sẽ không phát hiện ra sự khác biệt giữa cơ sở hạ tầng và code mô tả hạ tầng.