7 minute read

One of the domains where automation can save a lot of time is infrastructure provisioning. In many cases, manualy provisioning infrastructure can take hours and it is prone to user error on each iteration. Here is where Terraform from HashiCorp comes handy. You can create, manage, and destroy the resources from the terraform code. Terraform has countless provider API integrations as well as modules where several resources are used toghether.

You might ask, why I have chosen Oracle Cloud for this tutorial? Well, I have done that for the following reason:

  • Oracle Cloud Free Tier offers (at the time of the article) 2 Compute virtual machines with 1/8 OCPU and 1 GB memory each. Even though AWS and Azure have always free tiers, they do not offer compute resources for free. Google offers a micro instance and I will make a tutorial covering that too.

Note: The presented tutorial here is based on the official tutorial from Oracle Terraform: Set Up OCI Terraform

You also might think, why would write this code since creating a single VM manually would probbalby be faster? But you would be wrong. This article is just an example, once you apply infrastructure as a code concept on a much broader aspect, in day to day work, then you would see the real avantages

Creating the Oracle Cloud Account

First of all you need to create an Oracle Cloud account. For this, you need to go to the Signup page of Oracle. You will be required to enter a payment card in the profile for verification purposes. If you use only Always Free resources after the free trial has ended, you shouldn’t worry about costs as they are as the name suggests, always free. In our exampe we will use the always free compute instance and the vcn network.

Once you have finished following all the steps from the signup page, you will be waiting on the activation which might take from minutes to hours. While waiting on the activation, you can proceed with the next step

Installing Terraform Locally

You can install Terraform on Windows, Mac, or Linux. You can find the instalation instructions here: Terraform Cli Instalation In my personal case, I use disposable virtual machines for these types of activities in order to keep my environment clean. For this tutorial I have used a CentOS 8 VirtualBox VM and used the following guide: Official Oracle Terraform guide

Download Terraform zip file:

https://releases.hashicorp.com/terraform/0.14.0/terraform_0.14.0_linux_amd64.zip

Unzip the file:

unzip terraform_0.14.0_linux_amd64.zip

Move the folder to /usr/local/bin

sudo mv terraform /usr/local/bin

Check the Terraform version:

terraform -v

After finishing installing Terraform, you need to wait for the activation of the Oracle account before continuing on the next step

Setting Up Terraform For Oracle

Create RSA Keys

Create RSA keys for API signing into your Oracle Cloud Infrastructure account.

Open a terminal window. Make an .oci directory.

mkdir $HOME/.oci

Generate a 2048-bit private key in a PEM format:

openssl genrsa -out $HOME/.oci/<your-rsa-key-name>.pem 2048

Change permissions, so only you can read and write to the private key file:

chmod 600 $HOME/.oci/<your-rsa-key-name>.pem

Generate the public key:

openssl rsa -pubout -in $HOME/.oci/<your-rsa-key-name>.pem -out $HOME/.oci/<your-rsa-key-name>_public.pem

Copy the public key. In the terminal, enter:

cat $HOME/.oci/<your-rsa-key-name>_public.pem

Add the public key to your Oracle user account. From your user avatar, go to User Settings. Click API Keys. Click Add Public Key. Select Paste Public Keys. Paste value from previous step, including the lines with BEGIN PUBLIC KEY and END PUBLIC KEY Click Add. You have now set up the RSA keys to connect to your Oracle Cloud Infrastructure account.

Gather Required Information

Prepare the information you need to authenticate your Terraform scripts and copy them into your notepad.

Collect the following credential information from the Oracle Cloud Infrastructure Console.

  • Tenancy OCID:<tenancy-ocid> From your user avatar, go to Tenancy:<your-tenancy> and copy OCID.
  • User OCID: <user-ocid> From your user avatar, go to User Settings and copy OCID.
  • Fingerprint: <fingerprint> From your user avatar, go to User Settings and click API Keys. Copy the fingerprint associated with the RSA public key you made in section 2. The format is: xx:xx:xx…xx.
  • Region: <region-identifier> From the top navigation bar, find your region. Find your region’s <region-identifier>from Regions and Availability Domains. Example: us-ashburn-1. Collect the following information from your environment.
  • Private Key Path: <rsa-private-key-path> Path to the RSA private key you made in section 2. Example: $HOME/.oci/<your-rsa-key-name>.pem.

Create Scripts

In this section you create three scripts: one for authentication, one to fetch data from your account, and one to print outputs.

Add Authentication

In this section, you add API key based authentication. First, you set up a directory for all your Terraform scripts. Then you add a provider script so your Oracle Cloud Infrastructure account can authenticate the scripts running from this directory.

In your $HOME directory, create a directory called terraform-tutorial and change to that directory.

mkdir terraform-tutorial
cd terraform-tutorial

Create a file called provider.tf. Add the following code to provider.tf Replace the fields with brackets, with the information you gathered in the previous step. Make sure you add quotations around string values.

provider "oci" {
  tenancy_ocid = "<tenancy-ocid>"
  user_ocid = "<user-ocid>" 
  private_key_path = "<rsa-private-key-path>"
  fingerprint = "<fingerprint>"
  region = "<region-identifier>"
}

Save the provider.tf file.

Add a Data Source

In this section, you fetch a list of the availability domains in your tenancy.

In the terraform-tutorial directory, create a file called availability-domains.tf. Add the following code to availability-domains.tf. Replace the field with brackets, with the information you gathered in previous section.

Source from https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/identity_availability_domains

<tenancy-ocid> is the compartment OCID for the root compartment. Use <tenancy-ocid> for the compartment OCID.

data "oci_identity_availability_domains" "ads" {
  compartment_id = "<tenancy-ocid>"
}

Make sure provider.tf and availability-domains.tf are located in the same directory. Terraform can process all the files in a directory in their correct order, based on their relationship. Therefore, separate the provider and your other scripts for a modular approach and future reuse.

Create a Virtual Cloud Network

In this step, we will manually create the virtual cloud network on which th VMs will reside, if you already have a default one in Networking -> Virtual Cloud Network, you can copy the ocid ID from that one, if not, please follow the following short video from oracle on how to create one, with the mention to uncheck USE DNS HOSTNAMES IN THIS VCN

Create SSH Encryption Keys

Create ssh encryption keys you can use to log into your VM.

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 should have two files:

The private key file: The public key file: .pub Make sure to change the permisions to the oracle.pub file with the following command or else ssh will tell that it's too open:

chmod 600 <your-ssh-key-name>.pub

You will use these files to connect to your Compute instance.

Add Outputs

Outputs are used to configure what information is returned back from the script once it has ran succesfully. For this case we will use the following code:

output "name-of-first-availability-domain" {
  value = data.oci_identity_availability_domains.ads.availability_domains[0].name
}

# Outputs for compute instance

output "public-ip-for-compute-instance" {
  value = oci_core_instance.oracle1.public_ip
}

output "instance-name" {
  value = oci_core_instance.oracle1.display_name
}

output "instance-OCID" {
  value = oci_core_instance.oracle1.id
}

output "instance-region" {
  value = oci_core_instance.oracle1.region
}

output "instance-shape" {
  value = oci_core_instance.oracle1.shape
}

output "instance-state" {
  value = oci_core_instance.oracle1.state
}

output "instance-OCPUs" {
  value = oci_core_instance.oracle1.shape_config[0].ocpus
}

output "instance-memory-in-GBs" {
  value = oci_core_instance.oracle1.shape_config[0].memory_in_gbs
}

output "time-created" {
  value = oci_core_instance.oracle1.time_created
}

Compute Instance code

And last but not least, the compute instance code, please replace the placeholders with the information gathered in the previous steps:

resource "oci_core_instance" "oracle1" {
    # Required
    availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
    # Replace <tenancy-ocid> with the information gathered at the Gather Required Information step
    compartment_id = <tenancy-ocid>
    #VM.Standard.E2.1.Micro is the type of VM which is free indefinitely according to Oracle offer at the time of this article
    shape = "VM.Standard.E2.1.Micro"
    # Choose a linux image from the your region from the list available here and copy the ocid to the source_id below https://docs.cloud.oracle.com/en-us/iaas/images/image/c7107f6a-5b95-400a-b8b4-1798dc11dc27/
    source_details {
        source_id = <source ocid>
        source_type = "image"
    }

    # Optional
    display_name = "oracle1"
    create_vnic_details {
        assign_public_ip = true
        #Copy the subnet ocid from the VCN network 
        subnet_id = <subnet ocid>
    }
    metadata = {
      #write the path the ssh public key that you generated in the previous steps, in this example it was on /root/terraform-tutorial/oracle.pub
        ssh_authorized_keys = file("/root/terraform-tutorial/oracle.pub") 
} 
    preserve_boot_volume = false
}

Running the Scripts

Run the following init command from the terraform-tutorial folder:

terraform init

If everything went succesfully you should see the following output: Terraform has been successfully initialized! Next command that we want to run is:

terraform plan

This will output to the console all the changes that the next command, terraform apply will make. The last command is:

terraform apply

This command will ask you to write yes for confirmation. If everything worked as planned, in a few minutes you should now see resources appearing in your Oracle Cloud web console and you should also see the output in your console with the details of the newly created resources. You can connect to the public IP specified in the output with the following command:

ssh -i /root/tf-compute/oracle opc@<public IP from terraform output>

You are now connected to your free cloud VM created with Terraform in Oracle Cloud!

Alright Alright Alright