Create a Compute Instance

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 more 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 the directory where you want to store your keys and select Git Bash Here.
    Note

    If you're 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.

For detailed information on generating ssh encryption keys, see Creating a Key Pair.

Create a Virtual Cloud Network (VCN)
  1. Open the navigation menu , select Networking, and then select Virtual cloud networks.
  2. On the Virtual Cloud Networks list page, perform one of the following actions depending on the option that you see:

    • From Actions, select Start VCN Wizard.
    • Select Start VCN Wizard.
  3. In the Start VCN Wizard panel, select Create VCN with Internet Connectivity .
  4. Select Start VCN Wizard.

    The Create a VCN with internet connectivity window opens.

1. Configuration

Enter the following basic information:

  • VCN name: <your-vcn-name>

  • Compartment: <your-compartment-name>
Configure VCN
  • VCN IPv4 CIDR block: Keep the default value: 10.0.0.0/16

  • Use DNS hostnames in this VCN: Clear this checkbox.

Configure Public Subnet
  • IPv4 CIDR block: Keep the default value: 10.0.0.0/24

Configure Private Subnet
  • IPv4 CIDR block: Keep the default value: 10.0.1.0/24

Notice that the public and private subnets have different network addresses.

Select Next. The Review and create page opens.

2. Review and create

Review the complete VCN configuration and then select Create.

Resources are created, and then a message appears stating that VCN creation is complete.

To view the created VCN, select View VCN.

You have successfully created a VCN to host your compute instance.

Gather Required Information

Collect and copy the information you need into your notepad.

  • Compartment name
  • Compartment ID
  • Subnet ID
  • Source ID (image of compute instance)
  • Shape (compute instance)
  • SSH Authorized Key (public key path)
  • Private SSH Key Path

For steps to collect this information, see the following table.

Item Steps to collect item
Compartment name Reference the completed tutorial Create a Compartment.
Compartment ID
  1. In the Console search bar, enter <your-compartment-name>.
  2. Select <your-compartment-name> in the search results.
  3. Select Copy next to the OCID.
Instance display name Name of your choice.
Subnet ID
  1. In the Console: Open the navigation menu , select Networking, and then select Virtual cloud networks.
  2. Select <your-vcn-name> from Create a Virtual Cloud Network (VCN).
  3. Select Subnets.
  4. Select <your-compartment-name> to show subnets in your compartment.
  5. From the Actions menu (Actions Menu) for the public subnet, select Copy OCID.
Source ID (image of compute instance)
  1. In the Console navigation bar, find your region.

    See Working in Regions.

  2. Go to Image Release Notes.
  3. Select Ubuntu 24.04.

    The list of images for Ubuntu 24.04 opens.

  4. Select the latest image: Canonical-Ubuntu-24.04-<date>.

    The page lists image OCIDs.

  5. Find the image for your region and copy the image's OCID.

    Note: Ensure that you select a commercial OCID without gov in its OCID.

Shape and configuration (compute instance)
  • Shape: VM.Standard.E5.Flex
  • OCPUs: 1
  • Memory (GBs): 12

Note: The VM.Standard.E5.Flex requires values for OCPUs and memory. To select a different shape, go to Virtual Machine (VM) Shapes.

SSH Authorized Key (public key path) Reference the completed section, Create SSH Encryption Keys. Use this path when you set up the compute instance.
Private SSH Key Path Reference the completed section, Create SSH Encryption Keys. Use this private key when you connect to your compute instance.
Add Resource Policy

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

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

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

Steps to Add the Policy
  1. In the Console: Open the navigation menu  and select Identity & Security. Under Identity, select Policies.
  2. Select your compartment.
  3. Select Create Policy.
  4. On the Create Policy page, enter the following values:
    • 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, enter the following values:
    • Policy use cases: Compartment Management
    • Common policy templates: Let compartment admins manage the compartment
    • Identity domain: <identity-domain>
    • Groups: <a-group-your-username-belongs-to>
    • Location: <your-compartment-name>
  6. Select Create.

Reference: Common Policies

2. Create Scripts

Create scripts for authentication, fetching data, creating a compute instance, and printing 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 then change to that directory.
    mkdir tf-compute
    cd tf-compute
  2. Copy the provider.tf file into the tf-compute directory.
    cp ../tf-provider/provider.tf .

    Reference the completed tutorial Set Up OCI Terraform.

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 into the tf-compute directory.

    The availability-domains.tf file was created during the tutorial Set Up OCI Terraform.

    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 Terraform in the first tutorial, Set Up OCI Terraform, the output block included the following line:

value = data.oci_identity_availability_domains.ads.availability_domains

Then, the output was 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" = "xxxx: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.Standard.E5.Flex"
        shape_config {
            ocpus = "1"
            memory_in_gbs = "12"
        }
        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>, <your-ubuntu-instance-name>, and <subnet-ocid> with the information you collected at Gather Required Information.
    • 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 following 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 (VCNs) 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 Filter box on the upper left, enter core instance.

    Results include data sources and resources for several services.

  • Under Core, go to Resources and select oci_core_instance.

    The title of the page is the resource type: oci_core_instance

  • In the Argument Reference section, use the following required arguments (inputs):
    • 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 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.
    • 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
  • Go to Attributes Reference (oci_core_instance).
    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 to create the 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 select Compute. Under Compute, select 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.
  4. Disconnect from the instance:
    exit
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.

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