search

13-Terraform Provisioners – remote-exec và local-exec

calendar_today Đăng ngày: 29/04/2026

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 bootstrappingconfig 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-exec mớ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-exec nế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.