Find the Best Cosmetic Hospitals

Explore trusted cosmetic hospitals and make a confident choice for your transformation.

“Invest in yourself — your confidence is always worth it.”

Explore Cosmetic Hospitals

Start your journey today — compare options in one place.

Terraform provisioners Tutorials and Complete Guide

Terraform provisioners are used to execute scripts or shell commands on a local or remote machine as part of resource creation/deletion. They are similar to “EC2 instance user data” scripts that only run once on the creation and if it fails terraform marks it tainted.

Terraform includes a number of built-in provisioners, such as:

  • file: Copies files or directories from the machine running Terraform to the newly created resource.
  • remote-exec: Executes a command on the newly created resource.
  • local-exec: Executes a command on the machine running Terraform.

Provisioners can also be used to implement custom logic, such as:

  • Installing and configuring software
  • Creating and configuring user accounts
  • Starting and stopping services
  • Performing health checks

Provisioners should be used as a last resort. There are better alternatives for most situations, such as using Terraform modules or a configuration management tool like Ansible or Chef. However, provisioners can be useful for certain tasks, such as configuring resources that are not supported by Terraform modules or for integrating Terraform with other tools.


resource "aws_instance" "web" {
  ami           = "ami-053b0d53c279acc90"
  instance_type = "t3.micro"
  key_name 		= "aws-hl-training"

  tags = {
    Name = "HelloWorld-rajesh"
  }
  
  connection {
      type     = "ssh"
      user     = "ubuntu"
      private_key = file("aws-hl-training.pem")
      #host = aws_instance.web.public_ip
      host = self.public_ip
  } 
  
  provisioner "local-exec" {
    command = "mkdir devopsschool-local"
  }
  
 provisioner "remote-exec" {
    inline = [
	  "sudo apt-get update",
      "sudo apt-get install apache2 -y",
	  "sudo systemctl start apache2",
    ]
  }
  
  provisioner "file" {
    source      = "terraform.tfstate.backup"
    destination = "/tmp/"
  } 
  
  
}

output "instance_public_ip" {
  value = aws_instance.web.public_ip
}

output "instance_public_sg" {
  value = aws_instance.web.security_groups
}

Code language: PHP (php)

LOCAL-EXEC — Real Production Use Cases (10)

#Real Use CaseReal Project ScenarioTypical Tool/Command Used
1Register DNS entriesAfter creating VM/EC2, register hostname/IP into enterprise DNS (Infoblox/Bind)Python or curl API call to DNS system
2Trigger CI/CD post-deployment stepNotify Jenkins/GitLab that infrastructure provisioning completedcurl webhook to CI/CD
3Generate dynamic inventoryBuild Ansible inventory after VM creationBash script writing inventory file
4Update CMDB recordsSend newly created resource details into ServiceNow/CMDBREST API call
5Notify Slack/TeamsSend success/failure notifications to operations channelSlack webhook curl
6Run security scan locallyScan Terraform resources using Checkov/tfseccheckov / tfsec CLI
7Generate TLS certificatesCreate certificates locally before pushing to remote systemsopenssl commands
8Register monitoring targetsAdd new servers into Datadog/Zabbix monitoringPython/REST script
9Trigger smoke testingValidate deployed services externally after creationcurl / custom test scripts
10Export Terraform outputs to external toolsSave infrastructure metadata for external automation toolsBash export or file write

FILE — Real Production Use Cases (10)

#Real Use CaseReal Project ScenarioTypical File Transferred
1Upload application configDeploy application configuration to VMapp.conf
2Upload SSH authorized keysAdd public keys to server for accessauthorized_keys
3Upload SSL certificatesInstall TLS certificates on web serverscert.pem / key.pem
4Upload database initialization scriptInitialize DB schemas on new database serverinit.sql
5Upload Docker Compose filesDeploy microservices stackdocker-compose.yml
6Upload monitoring configurationConfigure Datadog/Prometheus agentdatadog.yaml
7Upload OS hardening scriptsApply CIS hardening policieshardening.sh
8Upload Kubernetes kubeconfigEnable cluster administration accesskubeconfig
9Upload custom application binariesDeploy compiled services to serverbinary executable
10Upload logging configurationsConfigure centralized logging agentsrsyslog.conf

REMOTE-EXEC — Real Production Use Cases (10)

#Real Use CaseReal Project ScenarioTypical Command Executed
1Install required packagesInstall NGINX, Docker, or dependencies on new VMapt/yum install
2Configure web serverEnable and start NGINX/Apache servicessystemctl start nginx
3Initialize databaseExecute DB schema initializationmysql < init.sql
4Install monitoring agentInstall Datadog/NewRelic agentscurl install script
5Configure firewall rulesOpen required service portsfirewall-cmd / iptables
6Join Kubernetes clusterAdd worker nodes to clusterkubeadm join
7Deploy containerized applicationLaunch containers after setupdocker-compose up
8Apply OS hardeningRun security scripts on remote systembash hardening.sh
9Configure logging agentsSetup centralized log forwardingsystemctl restart rsyslog
10Validate system readinessPerform system health checksdf -h, free -m

These tables reflect actual real-world Terraform usage patterns seen in:

  • AWS EC2 deployments
  • Kubernetes/EKS provisioning
  • DevOps CI/CD pipelines
  • Security hardening workflows
  • Enterprise infrastructure automation
  • Monitoring and logging setups

List of connection types in Terraform remote-exec provisioner?


SSH (Secure Shell):

  • Type: "ssh"
  • Description: Used for connecting to Unix-based operating systems, including Linux and macOS.
  • Commonly Used With: Linux and Unix-based cloud instances.
  • Example:

connection {
  type        = "ssh"
  user        = "your_username"
  private_key = file("~/.ssh/your_private_key.pem")
  host        = aws_instance.example.public_ip
}
Code language: JavaScript (javascript)

WinRM (Windows Remote Management):

  • Type: "winrm"
  • Description: Used for connecting to Windows-based operating systems.
  • Commonly Used With: Windows cloud instances.
  • Example:

connection {
  type     = "winrm"
  host     = aws_instance.example.private_ip
  user     = "Administrator"
  password = "your_password"
}
Code language: JavaScript (javascript)

To establish a WinRM connection over HTTPS with SSL and ignore certificate validation, you can modify the connection block as follows:


connection {
  type        = "winrm"
  host        = aws_instance.example.private_ip
  user        = "Administrator"
  password    = "your_password"
  https       = true  # Enable HTTPS
  insecure    = true  # Ignore SSL certificate validation (for testing purposes, not recommended in production)
  port        = 5986  # Use the default HTTPS port for WinRM
  cacert      = "/path/to/ca.crt"  # Optional path to a CA certificate file (if required)
  cert        = "/path/to/client.crt"  # Optional path to a client certificate file (if required)
  key         = "/path/to/client.key"  # Optional path to the client certificate's private key file (if required)
  timeout     = "5m"  # Set a timeout for the WinRM connection
  max_retries = 3     # Maximum number of connection retries
}
Code language: PHP (php)

Explanation of the options:

  • https: Set to true to enable HTTPS for the WinRM connection.
  • insecure: Set to true to ignore SSL certificate validation. This option is typically used for testing and debugging but is not recommended for production due to security concerns.
  • port: Use 5986 as the default port for HTTPS WinRM connections.
  • cacert: Optional path to a CA certificate file. Use this if your WinRM server’s certificate is signed by a custom CA.
  • cert: Optional path to a client certificate file. Use this if client certificate authentication is required.
  • key: Optional path to the private key file corresponding to the client certificate.
  • timeout: Set a timeout for the WinRM connection (e.g., "5m" for 5 minutes).
  • max_retries: Maximum number of connection retries in case of failures.

Basic Terraform Code — Local Exec Provisioner Demo

terraform {
  required_version = ">= 1.0"
}

# Dummy resource just to trigger local-exec
resource "null_resource" "local_exec_demo" {

  provisioner "local-exec" {

    command = <<EOT

echo "Creating directory..."
mkdir -p terraform_localexec_demo

echo "Checking system memory..."

# Linux memory check
if command -v free >/dev/null 2>&1; then
  free -h > terraform_localexec_demo/memory.txt
fi

# macOS memory check (for MacBook users)
if command -v vm_stat >/dev/null 2>&1; then
  vm_stat > terraform_localexec_demo/memory.txt
fi

echo "Memory details saved to terraform_localexec_demo/memory.txt"

EOT

    interpreter = ["/bin/bash", "-c"]
  }
}Code language: PHP (php)

Below are real, production-grade use cases for Terraform provisioners based on how they are actually used in enterprise/cloud/DevOps projects (not toy examples).
You’ll recognize many patterns from AWS, EKS, CI/CD, security hardening, and migration projects like the ones you typically work on.

I’ll give:

  • 10 REAL Local-Exec use cases
  • 10 REAL File provisioner use cases
  • 10 REAL Remote-Exec use cases

All based on real infrastructure workflows, not hypothetical lab-only scenarios.


LOCAL-EXEC — 10 Real Production Use Cases

Runs commands on the Terraform runner machine (CI/CD or laptop).


1. Register DNS Records After Infrastructure Creation

Real scenario:
After creating an EC2 instance, register its IP into an external DNS system (Infoblox / Route53 script / corporate DNS).

provisioner "local-exec" {
  command = "python register_dns.py ${aws_instance.app.private_ip}"
}
Code language: JavaScript (javascript)

Used in:

  • Enterprise data center automation
  • Hybrid cloud onboarding
  • Internal DNS automation

2. Notify Slack or Teams After Deployment

Real scenario:
Send deployment notifications to Slack after Terraform apply.

provisioner "local-exec" {
  command = <<EOT
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Infrastructure deployed successfully"}' \
$SLACK_WEBHOOK
EOT
}
Code language: PHP (php)

Used in:

  • CI/CD pipelines
  • DevOps release workflows

3. Generate Inventory for Ansible

Real scenario:
After VM creation, generate dynamic inventory.

provisioner "local-exec" {
  command = <<EOT
echo "[web]" > inventory.ini
echo "${aws_instance.web.private_ip}" >> inventory.ini
EOT
}
Code language: PHP (php)

Used in:

  • Terraform → Ansible workflows
  • Hybrid provisioning models

4. Trigger External Configuration Tool

Real scenario:
Trigger Ansible playbook after infra creation.

provisioner "local-exec" {
  command = "ansible-playbook site.yml -i inventory.ini"
}
Code language: JavaScript (javascript)

Used in:

  • Enterprise Linux automation
  • VM configuration

5. Validate Security Compliance

Real scenario:
Run security validation tools like:

  • terraform-compliance
  • checkov
provisioner "local-exec" {
  command = "checkov -d ."
}
Code language: JavaScript (javascript)

Used in:

  • Security pipelines
  • DevSecOps workflows

6. Store Outputs to External Systems

Real scenario:
Send resource metadata to CMDB.

provisioner "local-exec" {
  command = <<EOT
curl -X POST https://cmdb.company.com/api \
-d "ip=${aws_instance.app.private_ip}"
EOT
}
Code language: JavaScript (javascript)

Used in:

  • Enterprise asset tracking

7. Generate TLS Certificates

Real scenario:
Generate certificates locally.

provisioner "local-exec" {
  command = <<EOT
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem \
-out cert.pem -days 365 -nodes
EOT
}
Code language: JavaScript (javascript)

Used in:

  • Private cluster deployments
  • Internal services

8. Backup Terraform State Metadata

Real scenario:
Backup state metadata after apply.

provisioner "local-exec" {
  command = "cp terraform.tfstate backup/"
}
Code language: JavaScript (javascript)

Used in:

  • Disaster recovery

9. Trigger Monitoring Registration

Real scenario:
Register instances in monitoring system.

provisioner "local-exec" {
  command = "python register_datadog.py"
}
Code language: JavaScript (javascript)

Used in:

  • Datadog
  • Zabbix
  • Prometheus automation

10. Run Smoke Tests After Deployment

Real scenario:
Test deployed services.

provisioner "local-exec" {
  command = "curl http://${aws_instance.web.public_ip}"
}
Code language: JavaScript (javascript)

Used in:

  • Production release validation

FILE PROVISIONER — 10 Real Production Use Cases

Copies files from local machine → remote machine.


1. Upload SSH Keys

provisioner "file" {
  source      = "~/.ssh/id_rsa.pub"
  destination = "/home/ec2-user/.ssh/authorized_keys"
}
Code language: JavaScript (javascript)

Used in:

  • Secure server access

2. Upload Application Configuration Files

provisioner "file" {
  source      = "app.conf"
  destination = "/etc/myapp/app.conf"
}
Code language: JavaScript (javascript)

Used in:

  • App deployments

3. Upload Kubernetes kubeconfig

provisioner "file" {
  source      = "kubeconfig"
  destination = "/home/ubuntu/.kube/config"
}
Code language: JavaScript (javascript)

Used in:

  • Cluster management

4. Upload SSL Certificates

provisioner "file" {
  source      = "cert.pem"
  destination = "/etc/ssl/certs/cert.pem"
}
Code language: JavaScript (javascript)

Used in:

  • TLS-enabled services

5. Upload Docker Compose Files

provisioner "file" {
  source      = "docker-compose.yml"
  destination = "/home/ubuntu/docker-compose.yml"
}
Code language: JavaScript (javascript)

Used in:

  • Microservices deployment

6. Upload Monitoring Agent Config

provisioner "file" {
  source      = "datadog.yaml"
  destination = "/etc/datadog-agent/datadog.yaml"
}
Code language: JavaScript (javascript)

Used in:

  • Observability setups

7. Upload Application Binaries

provisioner "file" {
  source      = "myapp"
  destination = "/usr/local/bin/myapp"
}
Code language: JavaScript (javascript)

Used in:

  • Custom application deployment

8. Upload Database Initialization Scripts

provisioner "file" {
  source      = "init.sql"
  destination = "/tmp/init.sql"
}
Code language: JavaScript (javascript)

Used in:

  • DB bootstrapping

9. Upload Cloud-init Overrides

provisioner "file" {
  source      = "user-data.sh"
  destination = "/tmp/user-data.sh"
}
Code language: JavaScript (javascript)

Used in:

  • Custom provisioning

10. Upload Security Hardening Scripts

provisioner "file" {
  source      = "hardening.sh"
  destination = "/tmp/hardening.sh"
}
Code language: JavaScript (javascript)

Used in:

  • CIS hardening workflows

REMOTE-EXEC — 10 Real Production Use Cases

Runs commands directly on remote machines.


1. Install Required Packages

provisioner "remote-exec" {
  inline = [
    "sudo yum update -y",
    "sudo yum install nginx -y"
  ]
}
Code language: JavaScript (javascript)

Used in:

  • Server bootstrapping

2. Configure Web Server

inline = [
  "sudo systemctl enable nginx",
  "sudo systemctl start nginx"
]
Code language: JavaScript (javascript)

Used in:

  • Production web setup

3. Initialize Database

inline = [
  "mysql < /tmp/init.sql"
]
Code language: JavaScript (javascript)

Used in:

  • DB provisioning

4. Install Monitoring Agents

inline = [
  "curl -O https://agent.install.sh",
  "sudo bash agent.install.sh"
]
Code language: JavaScript (javascript)

Used in:

  • Observability setup

5. Configure Firewall Rules

inline = [
  "sudo firewall-cmd --add-port=80/tcp"
]
Code language: JavaScript (javascript)

Used in:

  • Security configuration

6. Join Node to Kubernetes Cluster

inline = [
  "sudo kubeadm join ..."
]
Code language: JavaScript (javascript)

Used in:

  • Kubernetes cluster scaling

7. Deploy Application Using Docker

inline = [
  "docker-compose up -d"
]
Code language: JavaScript (javascript)

Used in:

  • Container deployment

8. Apply OS Hardening

inline = [
  "bash /tmp/hardening.sh"
]
Code language: JavaScript (javascript)

Used in:

  • Security compliance

9. Configure Logging Agent

inline = [
  "sudo systemctl restart rsyslog"
]
Code language: JavaScript (javascript)

Used in:

  • Centralized logging

10. Run System Validation Checks

inline = [
  "df -h",
  "free -m"
]
Code language: JavaScript (javascript)

Used in:

  • Post-provision validation

REAL-WORLD SUMMARY (Industry Practice)

ProvisionerReal Purpose
local-execIntegration with external systems
fileTransfer configs/scripts
remote-execConfigure servers

Important Reality (Production Best Practice)

Most mature Terraform projects avoid heavy use of provisioners.

Instead they prefer:

  • cloud-init
  • userdata
  • configuration management tools
  • immutable infrastructure

Provisioners are mainly used for:

  • Bootstrapping
  • Integration hooks
  • Transitional automation

If You Want Enterprise-Level Understanding

Next useful topics would be:

  • Provisioner lifecycle (create, destroy)
  • Connection blocks (SSH, WinRM)
  • null_resource orchestration patterns
  • When NOT to use provisioners
  • Enterprise alternatives (cloud-init vs Ansible vs Packer)

Find Trusted Cardiac Hospitals

Compare heart hospitals by city and services — all in one place.

Explore Hospitals
I’m a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at <a href="https://www.cotocus.com/">Cotocus</a>. I share tech blog at <a href="https://www.devopsschool.com/">DevOps School</a>, travel stories at <a href="https://www.holidaylandmark.com/">Holiday Landmark</a>, stock market tips at <a href="https://www.stocksmantra.in/">Stocks Mantra</a>, health and fitness guidance at <a href="https://www.mymedicplus.com/">My Medic Plus</a>, product reviews at <a href="https://www.truereviewnow.com/">TrueReviewNow</a> , and SEO strategies at <a href="https://www.wizbrand.com/">Wizbrand.</a> Do you want to learn <a href="https://www.quantumuting.com/">Quantum Computing</a>? <strong>Please find my social handles as below;</strong> <a href="https://www.rajeshkumar.xyz/">Rajesh Kumar Personal Website</a> <a href="https://www.youtube.com/TheDevOpsSchool">Rajesh Kumar at YOUTUBE</a> <a href="https://www.instagram.com/rajeshkumarin">Rajesh Kumar at INSTAGRAM</a> <a href="https://x.com/RajeshKumarIn">Rajesh Kumar at X</a> <a href="https://www.facebook.com/RajeshKumarLog">Rajesh Kumar at FACEBOOK</a> <a href="https://www.linkedin.com/in/rajeshkumarin/">Rajesh Kumar at LINKEDIN</a> <a href="https://www.wizbrand.com/rajeshkumar">Rajesh Kumar at WIZBRAND</a> <a href="https://www.rajeshkumar.xyz/dailylogs">Rajesh Kumar DailyLogs</a>

Related Posts

Terraform workspace explained!!!

What is Terraform workspace? Have you worked with terraform workflow? such as terraform init/plan/apply/destroy with terraform configuration file? If Yes, you already have worked with Terraform workspace….

Read More

Terraform Tutorials: Templating in Terraform

Top 10 Templating Engines Across Major Programming Languages # Templating Engine Programming Language Common Framework / Ecosystem Typical Real Use 1 Jinja2 Python Flask, Ansible HTML generation,…

Read More

Terraform Tutorials: Local Values using Local Block

What is local value in terraform? In Terraform, a locals block is used to define local variables within a module, allowing you to create reusable expressions and…

Read More

Terraform Tutorials: Module Complete Guide

A Terraform module is a collection of configuration files that encapsulate resources used together to achieve a specific outcome. Modules promote reusability, organization, and maintainability in infrastructure…

Read More

What is Terrafile?

Terrafile is a tool used to manage Terraform modules as dependencies. It simplifies the process of downloading and managing Terraform modules by automating the fetching of modules…

Read More

What is Terraform and use cases of Terraform?

What is Terraform? Terraform is a infrastructure as code (IaC) tool and open-source from HashiCorp. It empowers users to define and manage cloud infrastructure and on-premises resources…

Read More