Oracle Cloud Infrastructure Documentation

Using Remote Exec

With Resource Manager, you can use Terraform's remote exec functionality to execute scripts or commands on a remote computer. You can also use this technique for other provisioners that require access to the remote resource.

Warning

Avoid entering confidential information when assigning descriptions, tags, or friendly names to your cloud resources through the Oracle Cloud Infrastructure Console, API, or CLI.

Prerequisites

  • The location where the script is remotely executed must be an Oracle Cloud Infrastructure resource that has a public IP and supports remote login.
  • On Windows, WinRM must be enabled. On Linux or Unix, SSH must be enabled.
  • A key pair used for signing API requests, with the public key uploaded to Oracle. For more information on generating and uploading keys, see Required Keys and OCIDs.

Authenticating

We recommend using one of the following approaches, depending on whether you have access to the Key Management service. For more information, see Overview of Key Management

With Key Management

First, use Key Management to encrypt your private key. For more information, see Managing Keys and Using Keys.

Next, provide the encrypted private key to Resource Manager. You can use the decrypt data source to decrypt it.

The following code sample demonstrates this process.

data "oci_kms_decrypted_data" "private_key_decrypted" {
    #Required
    ciphertext = "${file(var.encrypted_private_key_path)}"
    crypto_endpoint = "${var.decrypted_data_crypto_endpoint}"
    key_id = "${var.kms_encryption_key_id}"
}
  
  
resource "oci_core_instance" "TFInstance1" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "TFInstance"
  hostname_label      = "instance3"
  shape               = "${var.instance_shape}"
  subnet_id           = "${oci_core_subnet.ExampleSubnet.id}"
  
  source_details {
    source_type = "image"
    source_id   = "${var.instance_image_ocid[var.region]}"
  }
  
  extended_metadata {
    ssh_authorized_keys = "${var.ssh_public_key}"
  }
}
  
resource "null_resource" "remote-exec" {
      connection {
      agent       = false
      timeout     = "30m"
      host        = "${oci_core_instance.TFInstance1.public_ip}"
      user        = "${var.opc_user_name}"
      private_key = "${data.oci_kms_decrypted_data.test_decrypted_data.plaintext}"
    }
  
    inline = [
      "touch ~/IMadeAFile.Right.Here"
    ]
  
  }

Without Key Management

If you do not have access to the Key Management service, you can dynamically generate a key pair and store them in the state file.

  1. Generate a key pair using a TLS resource.
  2. When you launch the Compute instance, use the public key from the TLS resource.
  3. When you establish the SSH connection, provide the private key.

Warning

You should not save your private key in your Terraform configuration file because that is not a secure location.

The following sample demonstrates how to use the TLS private key resource to provision a compute instance, then perform a remote execution on that instance.

resource "tls_private_key" "public_private_key_pair" {
  algorithm   = "RSA"
}
  
resource "oci_core_instance" "TFInstance1" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "TFInstance"
  hostname_label      = "instance3"
  shape               = "${var.instance_shape}"
  subnet_id           = "${oci_core_subnet.ExampleSubnet.id}"
  
  source_details {
    source_type = "image"
    source_id   = "${var.instance_image_ocid[var.region]}"
  }
  
  extended_metadata {
    ssh_authorized_keys = "${tls_private_key.public_private_key_pair.public_key_openssh}"
  }
}
  
resource "null_resource" "remote-exec" {
  depends_on = ["oci_core_instance.TFInstance1"]
  
  provisioner "remote-exec" {
    connection {
      agent       = false
      timeout     = "30m"
      host        = "${oci_core_instance.TFInstance1.public_ip}"
      user        = "${var.opc_user_name}"
      private_key = "${tls_private_key.public_private_key_pair.private_key_pem}"
    }
  
    inline = [
      "touch ~/IMadeAFile.Right.Here"
    ]
  }
}

Connection Construct

This example of demonstrates how to use a connection construct for remote-exec. Terraform uses a number of defaults when connecting to a resource, but these can be overridden using a connection block in either a resource or provisioner. For more information, see Provisioner Connections.