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
}


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
}

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"
}

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
}

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.
Rajesh Kumar
Follow me