Bird
Raised Fist0
Terraformcloud~5 mins

Remote-exec provisioner in Terraform - Commands & Configuration

Choose your learning style10 modes available
Introduction
Sometimes after creating a server, you want to run commands on it to set it up. The remote-exec provisioner in Terraform lets you do this by connecting to the server and running commands automatically.
When you want to install software on a new virtual machine right after it is created.
When you need to configure settings on a server that Terraform created without logging in manually.
When you want to run a script on a remote server to prepare it for your application.
When you want to automate server setup steps like updating packages or starting services.
When you want to run commands on a server in a cloud environment right after deployment.
Config File - main.tf
main.tf
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y nginx"
    ]

    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = file("~/.ssh/id_rsa")
      host        = self.public_ip
    }
  }
}

This Terraform file creates an AWS EC2 instance using a specific Ubuntu AMI.

The remote-exec provisioner runs commands on the instance after it is created.

The inline block lists commands to update the package list and install nginx.

The connection block tells Terraform how to connect to the instance using SSH with a private key and the instance's public IP.

Commands
This command sets up Terraform in the current folder by downloading the AWS provider plugin. It prepares Terraform to work with AWS resources.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v4.0.0... - Installed hashicorp/aws v4.0.0 (signed by HashiCorp) Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure.
This command creates the AWS EC2 instance and runs the remote-exec provisioner commands automatically without asking for confirmation.
Terminal
terraform apply -auto-approve
Expected OutputExpected
aws_instance.example: Creating... aws_instance.example: Still creating... [10s elapsed] aws_instance.example: Creation complete after 20s [id=i-0abcd1234efgh5678] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
→
-auto-approve - Skip manual approval to apply changes immediately
This command shows the current state of the infrastructure Terraform manages, including the instance details and provisioner status.
Terminal
terraform show
Expected OutputExpected
aws_instance.example: id = i-0abcd1234efgh5678 ami = ami-0c55b159cbfafe1f0 instance_type = t2.micro public_ip = 54.210.123.45 provisioner "remote-exec" executed successfully
Key Concept

If you remember nothing else from this pattern, remember: remote-exec runs commands on a new server by connecting over SSH right after Terraform creates it.

Common Mistakes
Not setting up the SSH connection block correctly with the right user, private key, or host.
Terraform cannot connect to the server to run commands, so the provisioner fails.
Always specify the correct SSH user, provide the private key file path, and use the server's public IP or hostname.
Running remote-exec on an instance that is not yet ready to accept SSH connections.
Commands fail because the server is still booting or SSH service is not ready.
Use Terraform resource dependencies or wait for the instance to be fully ready before running remote-exec.
Using remote-exec for complex or long-running setup tasks.
Provisioners are not reliable for complex setups and can cause Terraform runs to fail or hang.
Use configuration management tools or baked AMIs for complex setups; use remote-exec only for simple commands.
Summary
Use terraform init to prepare Terraform with the AWS provider.
Use terraform apply to create the instance and run remote commands automatically.
Check the infrastructure state with terraform show to confirm the instance and provisioner ran.

Practice

(1/5)
1. What is the main purpose of the remote-exec provisioner in Terraform?
easy
A. To run commands on a remote machine after it is created
B. To create a new virtual machine in the cloud
C. To store Terraform state files remotely
D. To manage user permissions on the local machine

Solution

  1. Step 1: Understand the role of provisioners

    Provisioners in Terraform run scripts or commands on resources after creation.
  2. Step 2: Identify what remote-exec does

    The remote-exec provisioner connects to the remote machine and runs commands there.
  3. Final Answer:

    To run commands on a remote machine after it is created -> Option A
  4. Quick Check:

    remote-exec runs remote commands = D [OK]
Hint: remote-exec runs commands remotely after resource creation [OK]
Common Mistakes:
  • Confusing remote-exec with resource creation
  • Thinking remote-exec manages local files
  • Mixing remote-exec with state management
2. Which of the following is the correct syntax to define a remote-exec provisioner inside a Terraform resource?
easy
A. remote_exec { commands = ["echo Hello"] }
B. provisioner remote-exec { script = "hello.sh" }
C. provisioner "remote-exec" { inline = ["echo Hello"] }
D. exec_remote { inline = ["echo Hello"] }

Solution

  1. Step 1: Recall Terraform provisioner syntax

    Provisioners are defined with the keyword provisioner followed by the provisioner type in quotes.
  2. Step 2: Check the correct block structure for remote-exec

    The remote-exec provisioner uses inline to run commands directly.
  3. Final Answer:

    provisioner "remote-exec" { inline = ["echo Hello"] } -> Option C
  4. Quick Check:

    Correct provisioner block syntax = B [OK]
Hint: Use provisioner "remote-exec" with inline commands [OK]
Common Mistakes:
  • Using underscores instead of hyphens in provisioner name
  • Omitting quotes around provisioner type
  • Using wrong block names like exec_remote
3. Given this Terraform snippet inside an AWS EC2 resource:
provisioner "remote-exec" {
  inline = ["sudo apt-get update", "sudo apt-get install -y nginx"]
  connection {
    type        = "ssh"
    user        = "ubuntu"
    private_key = file("~/.ssh/id_rsa")
    host        = self.public_ip
  }
}

What will happen when this runs successfully?
medium
A. The commands will run locally on the Terraform machine
B. The EC2 instance will update packages and install nginx via SSH
C. Terraform will fail because private_key cannot be a file
D. The EC2 instance will reboot automatically after installation

Solution

  1. Step 1: Understand remote-exec with connection block

    The provisioner connects via SSH using the given user, key, and host to run commands remotely.
  2. Step 2: Analyze the inline commands

    The commands update package lists and install nginx on the remote EC2 instance.
  3. Final Answer:

    The EC2 instance will update packages and install nginx via SSH -> Option B
  4. Quick Check:

    remote-exec runs commands remotely = C [OK]
Hint: remote-exec runs inline commands on remote host via SSH [OK]
Common Mistakes:
  • Thinking commands run locally
  • Assuming private_key cannot be a file
  • Expecting automatic reboot after install
4. You have this Terraform snippet:
provisioner "remote-exec" {
  inline = ["sudo apt-get update", "sudo apt-get install -y nginx"]
  connection {
    type     = "ssh"
    user     = "ubuntu"
    password = "mypassword"
    host     = self.public_ip
  }
}

After running Terraform apply, you get a connection timeout error. What is the most likely cause?
medium
A. The EC2 instance's security group does not allow SSH (port 22) inbound
B. The password authentication is not supported by SSH
C. The inline commands have syntax errors
D. The host attribute should be a private IP, not public IP

Solution

  1. Step 1: Understand connection timeout causes

    Timeout usually means network connection to SSH port 22 is blocked or unreachable.
  2. Step 2: Check common network issues

    If the EC2 security group lacks inbound SSH rules, connection fails despite correct credentials.
  3. Final Answer:

    The EC2 instance's security group does not allow SSH (port 22) inbound -> Option A
  4. Quick Check:

    Timeout = network block on SSH port 22 [OK]
Hint: Timeout usually means SSH port 22 blocked in firewall/security group [OK]
Common Mistakes:
  • Blaming inline command syntax for connection errors
  • Assuming password auth is always unsupported
  • Confusing public and private IP for SSH host
5. You want to use remote-exec to run a script on multiple newly created instances in a loop. Which approach is best to ensure commands run on each instance correctly?
hard
A. Use local-exec provisioner to SSH manually to each instance
B. Define one resource and run remote-exec with a list of all instance IPs in one provisioner
C. Run remote-exec provisioner only once after all instances are created using a null_resource
D. Use a for_each on the resource and include a remote-exec provisioner inside each resource block

Solution

  1. Step 1: Understand resource loops with provisioners

    Using for_each creates multiple resource instances, each with its own provisioner execution.
  2. Step 2: Why per-resource provisioner is best

    Provisioners inside each resource run commands on that specific instance, ensuring correct targeting.
  3. Final Answer:

    Use a for_each on the resource and include a remote-exec provisioner inside each resource block -> Option D
  4. Quick Check:

    Provisioner per resource instance = A [OK]
Hint: Use for_each with provisioner inside resource for multiple instances [OK]
Common Mistakes:
  • Trying to run remote-exec on all IPs in one provisioner
  • Using null_resource without proper triggers
  • Using local-exec instead of remote-exec for remote commands
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard