Trong một số trường hợp, chỉ tạo resource thôi chưa đủ — bạn cần chạy thêm script hoặc lệnh ngay sau khi resource được tạo xong. Đó là lúc provisioner phát huy tác dụng.
1. Provisioner là gì?
Provisioner cho phép bạn chạy script hoặc command trong quá trình bootstrapping và config resource — tức là ngay sau khi Terraform tạo xong resource đó.
Terraform có hai provisioner phổ biến nhất:
| Provisioner | Chạy ở đâu |
|---|---|
remote-exec |
Trên remote machine vừa được tạo (kết nối qua SSH hoặc WinRM) |
local-exec |
Trên máy local đang chạy Terraform |
2. remote-exec
Dùng khi cần chạy command trực tiếp trên resource vừa tạo — ví dụ cài package, khởi động service ngay sau khi EC2 được tạo xong.
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
provisioner "remote-exec" {
connection {
type = "ssh"
user = "ec2-user"
private_key = file("~/.ssh/my-key.pem")
}
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx",
"sudo service nginx start"
]
}
}
Block connection khai báo cách Terraform kết nối vào máy — ở đây dùng SSH với private key. Block inline là danh sách các lệnh sẽ được chạy theo thứ tự từ trên xuống.
Lưu ý: EC2 cần có public IP và security group cho phép inbound SSH (port 22) thì
remote-execmới kết nối được.
3. local-exec
Dùng khi cần chạy lệnh trên máy đang chạy Terraform — ví dụ ghi log, gọi API, trigger một script nội bộ sau khi resource được tạo.
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
provisioner "local-exec" {
command = "echo 'S3 bucket created!' > /tmp/s3_notification.txt"
}
}
Lệnh trong command chạy trên shell của máy local — không liên quan gì đến resource vừa tạo trên cloud.
4. Một lưu ý quan trọng
HashiCorp không khuyến khích dùng provisioner nếu có cách thay thế tốt hơn. Lý do:
- Provisioner khó debug, lỗi xảy ra sau khi resource đã tạo xong
- Terraform không track được trạng thái của những gì provisioner đã làm
- Nếu provisioner fail, resource vẫn tồn tại nhưng ở trạng thái không như mong đợi
Thay thế được khuyến nghị:
- Dùng user_data (AWS) để bootstrap EC2 thay vì
remote-exec - Dùng Ansible để config sau khi Terraform tạo xong hạ tầng
- Dùng null_resource kết hợp
local-execnếu cần trigger script mà không muốn gắn vào resource cụ thể
Provisioner vẫn hữu ích trong một số trường hợp đặc thù, nhưng nên coi đây là phương án cuối cùng khi không có cách nào khác.