Terraform Archive Provider - Create ZIP and TAR Files
Use the Terraform archive provider to create ZIP files for Lambda functions, Cloud Functions, and deployments. archive_file data source with source_dir and...
Terraform
Complete guide to Terraform provisioners. local-exec, remote-exec, and file provisioners with SSH connections, error handling, and best practices.
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
provisioner "remote-exec" {
inline = ["sudo apt update && sudo apt install -y nginx"]
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/id_rsa")
host = self.public_ip
}
}
}Runs commands on the machine running Terraform (your laptop or CI/CD runner):
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
# Runs after creation
provisioner "local-exec" {
command = "echo ${self.public_ip} >> inventory.txt"
}
# Runs before destruction
provisioner "local-exec" {
when = destroy
command = "sed -i '/${self.public_ip}/d' inventory.txt"
}
}provisioner "local-exec" {
command = "./deploy.sh"
working_dir = "${path.module}/scripts"
interpreter = ["/bin/bash", "-c"]
environment = {
SERVER_IP = self.public_ip
ENV = var.environment
}
}provisioner "local-exec" {
command = "deploy.ps1 -ServerIP ${self.public_ip}"
interpreter = ["PowerShell", "-Command"]
}Runs commands on the remote resource via SSH or WinRM:
resource "aws_instance" "app" {
ami = var.ami_id
instance_type = var.instance_type
key_name = aws_key_pair.deploy.key_name
connection {
type = "ssh"
user = "ubuntu"
private_key = file(var.private_key_path)
host = self.public_ip
timeout = "5m"
}
# Inline commands
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y docker.io",
"sudo usermod -aG docker ubuntu",
"sudo systemctl enable docker",
]
}
# Run a script
provisioner "remote-exec" {
script = "${path.module}/scripts/setup.sh"
}
# Run multiple scripts
provisioner "remote-exec" {
scripts = [
"${path.module}/scripts/install-deps.sh",
"${path.module}/scripts/configure-app.sh",
]
}
}connection {
type = "ssh"
user = "ubuntu"
private_key = file(var.private_key_path)
host = self.private_ip
bastion_host = aws_instance.bastion.public_ip
bastion_user = "ubuntu"
bastion_private_key = file(var.bastion_key_path)
}Copies files or directories to the remote resource:
resource "aws_instance" "app" {
# ... instance config ...
connection {
type = "ssh"
user = "ubuntu"
private_key = file(var.private_key_path)
host = self.public_ip
}
# Single file
provisioner "file" {
source = "configs/app.conf"
destination = "/tmp/app.conf"
}
# Directory
provisioner "file" {
source = "configs/"
destination = "/tmp/configs"
}
# Inline content
provisioner "file" {
content = templatefile("${path.module}/templates/config.tpl", { db_host = var.db_host })
destination = "/tmp/app-config.json"
}
provisioner "remote-exec" {
inline = [
"sudo mv /tmp/app.conf /etc/app/app.conf",
"sudo systemctl restart app",
]
}
}provisioner "local-exec" {
command = "./deploy.sh"
on_failure = continue # Don't fail the resource (default: fail)
}terraform_data instead of null_resource for standalone provisioners# Prefer cloud-init
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
user_data = templatefile("${path.module}/cloud-init.yaml", {
packages = ["nginx", "nodejs"]
})
}Use local-exec for CI/CD integration and local scripts, remote-exec and file for bootstrapping servers that can't use cloud-init, and always prefer immutable infrastructure (Packer AMIs, containers) over runtime provisioning. Provisioners are escape hatches, not primary tools.
Use the Terraform archive provider to create ZIP files for Lambda functions, Cloud Functions, and deployments. archive_file data source with source_dir and...
Automate Terraform with Azure DevOps Pipelines. YAML pipelines, service connections, environment approvals, and Azure backend state configuration.
Automate Terraform with GitHub Actions. Plan on PR, apply on merge, OIDC authentication, environment protection, and drift detection workflows.
Automate Terraform with GitLab CI/CD. Plan on merge requests, apply on main, remote state with HTTP backend, and environment-specific pipelines.