Terraform: Create a Compute Instance

In this tutorial, you use Terraform to create a compute instance in your Oracle Cloud Infrastructure tenancy.

Key tasks include how to:

  • Create SSH keys.
  • Create a virtual cloud network in your tenancy.
  • Use Oracle Cloud Infrastructure Terraform provider to create a compute instance in the network.
  • Connect to your instance.
A diagram of the components needed to create an Oracle Cloud Infrastructure compute instance with Terraform. The compute instance is created in a public subnet of a virtual cloud network. The public subnet is connected to the insternet through an internet gateway.

For additional information, see:

Before You Begin

To successfully perform this tutorial, you must have the following:

Requirements

1. Prepare

Prepare your environment for creating a compute instance. Also, collect all the information you need to complete the tutorial.

Create SSH Encryption Keys

Create ssh encryption keys to connect to your compute instance.

  1. Open a terminal window:
    • MacOS or Linux: Open a terminal window in the directory where you want to store your keys.
    • Windows: Right-click on the directory where you want to store your keys and select Git Bash Here.
    Note

    If you are using Windows Subsystem for Linux (WSL), ensure that the directory for the keys is directly on your Linux machine and not in a /mnt folder (windows file system).
  2. Issue the following OpenSSH command:
    ssh-keygen -t rsa -N "" -b 2048 -C <your-ssh-key-name> -f <your-ssh-key-name>

    The command generates some random text art used to generate the keys. When complete, you have two files:

    • The private key file: <your-ssh-key-name>
    • The public key file: <your-ssh-key-name>.pub

    You use these files to connect to your compute instance.

You have generated the required encryption keys.

See Creating a Key Pair for more detailed information on generating ssh encryption keys.

Create a Virtual Cloud Network (VCN)

Set up a VCN to connect your Linux instance to the internet. You configure all the components needed to create your virtual network.

  1. Click the Oracle Cloud icon to go to the main landing page.
    • Scroll down to Launch Resources.
    • Select Set up a network with a wizard.
  2. In the Start VCN Wizard workflow, select VCN with Internet Connectivity and then click Start VCN Wizard .
  3. Fill in basic information:
    • VCN Name: <your-vcn-name>
    • Compartment: <your-compartment-name>
  4. In the Configure VCN and Subnets section, keep the default values for the CIDR blocks:
    • VCN CIDR BLOCK: 10.0.0.0/16
    • PUBLIC SUBNET CIDR BLOCK: 10.0.0.0/24
    • PRIVATE SUBNET CIDR BLOCK: 10.0.1.0/24
    Note

    Notice the public and private subnets have different network addresses.
  5. For DNS Resolution, uncheck Use DNS hostnames in this VCN.
  6. Click Next.

    The Create a VCN with Internet Connectivity configuration dialog is displayed (not shown here) confirming all the values you just entered.

  7. Click Create to create your VCN.

    The Creating Resources dialog is displayed (not shown here) showing all VCN components being created.

  8. Click View Virtual Cloud Network to view your new VCN.
You have successfully created a VCN to host your compute instance.
Gather Required Information

Prepare the information you need and copy them into your notepad.

  1. Compartment Name: <your-compartment-name>
    • Find your compartment name from the Create a Compartment tutorial you performed in the Before you Begin section.
  2. Collect the following information from the Oracle Cloud Infrastructure Console.
    • Compartment ID: <compartment-ocid>
      • In the Console search bar, enter <your-compartment-name>.
      • Click <your-compartment-name> in the search results.
      • Copy the OCID.
    • Subnet ID: <subnet-ocid>
      • Open the navigation menu and click Networking, and then click Virtual Cloud Networks.
      • Click <your-vcn-name> from section 2.
      • Click the public subnet and copy OCID.
  3. Find the source id for the image of the compute instance.
    • Source ID: <source-ocid>
      • In the Console's top navigation bar, find your region.
      • Go to Image Release Notes.
      • Click Ubuntu 20.04 and click the latest image: Canonical-Ubuntu-20.04-<date>.
      • Find the image for your region and copy OCID.
        Note

        Ensure that you select a commercial OCID without gov in its OCID.
  4. Choose the shape for the compute instance.
  5. Collect the following information from your environment.
    • SSH Authorized Key (public key path): <ssh-public-key-path>
      • From section 1, get the path to the SSH public key on your environment.
      • You use this path when you set up the compute instance.
    • Private SSH Key Path: <ssh-private-key-path>
      • From the Create SSH Encryption Keys section, get the path to the SSH private key.
      • You use this private key to connect to your compute instance.
Add Resource Policy

If your username is in the Administrators group, then skip this section. Otherwise, have your administrator add the following policy to your tenancy:

allow group <the-group-your-username-belongs> to manage all-resources in compartment <your-compartment-name>

With this privilege, you can manage all resources in your compartment, essentially giving you administrative rights in that compartment.

Steps to Add the Policy
  1. Open the navigation menu and click Identity & Security. Under Identity, click Policies.
  2. Select your compartment from the Compartment drop-down.
  3. Click Create Policy.
  4. Fill in the following information:
    • Name: manage-<your-compartment-name>-resources
    • Description: Allow users to list, create, update, and delete resources in <your-compartment-name>.
    • Compartment: <your-tenancy>(root)
  5. For Policy Builder, select the following choices:
    • Policy use cases: Compartment Management
    • Common policy templates: Let compartment admins manage the compartment
    • Groups: <the-group-your-username-belongs>
    • Location: <your-tenancy>(root)
  6. Click Create.

Reference: Common Policies

2. Create Scripts

Create four scripts: one for authentication, one to fetch data, one to create a compute instance, and one to print outputs.

Add Authentication

First, set up a directory for your Terraform scripts. Then add a provider script so your Oracle Cloud Infrastructure account can authenticate the scripts running from this directory.

  1. In your $HOME directory, create a directory called tf-compute and change to that directory.
    mkdir tf-compute
    cd tf-compute
  2. Copy the provider.tf file from the Set Up OCI Terraform tutorial mentioned in the Before you Begin section, into the tf-compute directory.
    cp ../tf-provider/provider.tf .
Fetch Data

Fetch the name of an availability domain from your account. An availability domain is one of the required inputs to create a compute instance.

  1. Copy the availability-domains.tf file from the Set Up OCI Terraform tutorial mentioned in the Before you Begin section, into the tf-compute directory.
    cp ../tf-provider/availability-domains.tf .

    Example code:

    # Source from https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_availability_domains
    
    data "oci_identity_availability_domains" "ads" {
      compartment_id = "<tenancy-ocid>"
    }
  2. In the tf-compute directory, create a file called outputs.tf.
    Note

    Ensure that outputs.tf, provider.tf, and availability-domains.tf are in the same directory.
  3. To output the name of the first availability domain in the list of oci_identity_availability_domains, add the following code to outputs.tf.
    
    # The "name" of the availability domain to be used for the compute instance.
    output "name-of-first-availability-domain" {
      value = data.oci_identity_availability_domains.ads.availability_domains[0].name
    }
  4. Save the outputs.tf file.
  5. Run your scripts with Terraform:
    terraform init
    terraform plan
    terraform apply

    When prompted for confirmation, enter yes for your data to be fetched and displayed in the output.

    You now have an output with the name of the availability domain to use for your instance.

    Example output:

    name-of-first-availability-domain = QnsC:US-ASHBURN-AD-1

    Congratulations! You have successfully fetched data from your Oracle Cloud Infrastructure account to use for your compute instance.

Explanation

When you set up OCI Terraform in the first tutorial, you had the following code in your output block:

value = data.oci_identity_availability_domains.ads.availability_domains

Then, you had an output similar to the following:

Outputs:

all-availability-domains-in-your-tenancy = tolist([
  {
    "compartment_id" = "ocid1.tenancy.xxx"
    "id" = "ocid1.availabilitydomain.xxx"
    "name" = "QnsC:US-ASHBURN-AD-1"
  },
  {
    "compartment_id" = "ocid1.tenancy.xxx"
    "id" = "ocid1.availabilitydomain.xxx"
    "name" = "QnsC:US-ASHBURN-AD-2"
  },
  {
    "compartment_id" = "ocid1.tenancy.xxx"
    "id" = "ocid1.availabilitydomain.xxx"
    "name" = "QnsC:US-ASHBURN-AD-3"
  },
])

Now, you want to fetch the name of the first availability domain in the list, to use for the location of your compute instance later:

"name" = "QnsC:US-ASHBURN-AD-1"
Note

  • Use square brackets to add an index to a list attribute.
  • Use the index 0 for the first item in a list.
  • Use a dot after the square brackets followed by an attribute of the list, to specify that attribute.
  • Example: First item in the list:

    value = data.oci_identity_availability_domains.ads.availability_domains[0]

  • Example: Name of first item in the list:

    value = data.oci_identity_availability_domains.ads.availability_domains[0].name

Declare a Compute Resource

Declare an Oracle Cloud Infrastructure compute resource, and then define the specifics for the instance.

  1. Create a file called compute.tf.
  2. Add the following code to compute.tf.
    
    
    resource "oci_core_instance" "ubuntu_instance" {
        # Required
        availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
        compartment_id = "<compartment-ocid>"
        shape = "VM.Standard2.1"
        source_details {
            source_id = "<source-ocid>"
            source_type = "image"
        }
    
        # Optional
        display_name = "<your-ubuntu-instance-name>"
        create_vnic_details {
            assign_public_ip = true
            subnet_id = "<subnet-ocid>"
        }
        metadata = {
            ssh_authorized_keys = file("<ssh-public-key-path>")
        } 
        preserve_boot_volume = false
    }
    Important

    • Replace <compartment-ocid>, <source-ocid>, and <subnet-ocid> with the information you gathered in the Gather Required Information section.
    • Replace <your-ubuntu-instance-name> with a name of your choice.
    • For availability domain, use the name you fetched with the data source:
      data.oci_identity_availability_domains.ads.availability_domains[0].name
    • For ssh_authorized_keys:
      • Use the file format, file("<ssh-public-key-path>").
      • You can't change its value after you create the VM.
  3. Save the compute.tf file.
Explanation

In Terraform, resources are objects such as virtual cloud networks or compute instances. You can create, update, and delete them with Terraform. To declare a compute resource:

  • Go to Oracle Cloud Infrastructure Provider.
  • In the left navigation Filter, enter core instance.

    Results are returned for both Data Sources and Resources for several services.

  • Under Core, go to Resources and click oci_core_instance.
  • Find the Resource Type from the title of the page:
    • Type: oci_core_instance
  • In the Argument Reference section, use the following arguments (inputs) labeled as (Required):
    • availability_domain
    • compartment_id
    • shape
    • source_details
      • source_id
      • source_type
  • Construct a resource block:
    • Declare a resource block with the keyword: resource
    • Add a label for resource type: "oci_core_instance"
    • Add a label for a local name (your choice):
      • The label can contain letters, digits, underscores (_), and hyphens (-). The first character must not be a digit.
      • Example: "ubuntu_instance"
    • Inside the code block, provide a value for the required arguments. They don't have a default value.
    • For optional arguments, provide values for the ones you want to override. Otherwise, their default values are used.
Add Outputs

Add output blocks to your code to get information about your compute instance after Terraform creates it.

  1. Open the outputs.tf file.
  2. Create an output block for the public IP of the instance:
    • The public IP is available after the instance is created.
    • You use the public IP to connect to the instance.
    • Add the following code to outputs.tf:
    
    # Outputs for compute instance
    
    output "public-ip-for-compute-instance" {
      value = oci_core_instance.ubuntu_instance.public_ip
    }
    
  3. Add a few more outputs to describe the compute instance:
    • display_name
    • id
    • region
    • shape
    • state
    • ocpus
    • memory_in_gbs
    • time_created
    
    output "instance-name" {
      value = oci_core_instance.ubuntu_instance.display_name
    }
    
    output "instance-OCID" {
      value = oci_core_instance.ubuntu_instance.id
    }
    
    output "instance-region" {
      value = oci_core_instance.ubuntu_instance.region
    }
    
    output "instance-shape" {
      value = oci_core_instance.ubuntu_instance.shape
    }
    
    output "instance-state" {
      value = oci_core_instance.ubuntu_instance.state
    }
    
    output "instance-OCPUs" {
      value = oci_core_instance.ubuntu_instance.shape_config[0].ocpus
    }
    
    output "instance-memory-in-GBs" {
      value = oci_core_instance.ubuntu_instance.shape_config[0].memory_in_gbs
    }
    
    output "time-created" {
      value = oci_core_instance.ubuntu_instance.time_created
    }
  4. Save the outputs.tf file.
Explanation
  • On the Resource: oci_core_instance page, go to Attributes Reference.
    Note

    Attributes are the outputs that you can return for the oci_core_instance resource.
  • Search for the attribute for public IP: public_ip.
  • Construct a resource output block for public_ip:
    • For the value expression, use the following format:
      • value = <type>.<local-name-for-resource>.<attribute>
      • Example: value = oci_core_instance.ubuntu_instance.public_ip
  • Create an output block for each of the following outputs:
    • display_name
    • id
    • region
    • shape
    • state
    • ocpus
    • memory_in_gbs
    • time_created

3. Run Scripts

Run your Terraform scripts. After, your account authenticates the scripts, Terraform creates a compute instance in a compartment in your tenancy. Use your SSH keys to connect to the instance. When you no longer need your instance, destroy it with Terraform.

Create an Instance
  1. Create your compute instance with Terraform:
    terraform init
    terraform plan
    terraform apply

    When prompted for confirmation, enter yes, for your resource to be created.

    After the instance is created, the outputs that you defined including <your-public-ip-address> are displayed in the output terminal.

  2. (Optional) Watch the instance creation from the Console.
    • Open the navigation menu and click Compute. Under Compute, click Instances.
    • Select your compartment.
    • Watch your instance appear in the list of instances.

Congratulations! You have successfully created a compute instance using Terraform, in your Oracle Cloud Infrastructure account.

References:

Connect to the Instance
  1. From your terminal, enter the outputs for your compute instance:
    terraform output
  2. Copy the public IP address from the outputs.
  3. From your Linux machine, connect to your VM with this ssh command:
    ssh -i <ssh-private-key-path> ubuntu@<your-public-ip-address>
    Note

    Ensure that your private key is located directly on your Linux (WSL) machine.
Destroy the Instance
  1. (Optional) After you no longer need your compute instance, you can terminate it with the following command:
    terraform destroy

    When prompted for confirmation, enter yes, for your compute instance to be terminated.

  2. (Optional) Watch the termination from the Console:
    • Open the navigation menu and click Compute. Under Compute, click Instances.
    • Select your compartment.
    • Watch your instance's state change to Terminating and then Terminated.