OCI #7 – Terraform Setup

This recipe shows how to install and configure Terraform on your client machine.

Before you start, you must create a key pair for API Signing Key. See: API Signing Key recipe, if needed.

Oracle Cloud Infrastructure REST API

Oracle Cloud Infrastructure exposes a comprehensive REST API to manage OCI resources and configurations. Every API call request must be signed with Oracle Cloud Infrastructure API signature and sent using secure HTTPS protocol with TLS 1.2. Signing a request is a multi-step process that can be seen as non-trivial. This is why you usually use tools like CLI, Terraform or custom SDK-based programs that encapsulate API calls and sign the requests on your behalf. All these tools eventually make calls to OCI REST API, therefore OCI REST API is the ultimate gateway to the cloud management plane.


Terraform is a declarative, agentless infrastructure provisioning tool. You declare the infrastructure as code using a JSON-like HCL (HashiCorp Language) declarative language. For example, this is how you define a sample OCI virtual network:

resource "oci_core_virtual_network" "my_vcn" {
	  cidr_block = ""
	  dns_label = "corefra"
	  compartment_id = "${var.compartment_ocid}"
	  display_name = "core-fra-vcn"

Terraform calculates an execution plan and issues a series of direct API calls to the provider’s cloud management plane, every time you run terraform apply command. The tool knows what API calls the plan has to eventually produce because it tracks the as-isinfrastructure state locally in a .tfstate file. Out-of-the-box, the tool supports a number of cloud providers including Oracle Cloud Infrastructure.

Installing Terraform

Each Terraform release comes as a single binary file. You can find the binary package for your operating system under this link.

  1. Download and unpack the binary file for your operationg system from https://www.terraform.io/downloads.html.
  2. Execute the following command:
    $ terraform --version
    Terraform v0.11.10

You should notice that a new hidden directory gets created (~/.terraform.d).

Configuring Terraform for OCI

Although Terraform supports Oracle Cloud Infrastructure out-of-the-box, each infrastructure project you are working on still has to know the API connection details like tenancy OCID, user OCID, path to the private key and the fingerprint of the corresponding public key you upload and associate with the OCI user. Terraform is able to map the operating system environment variables that follow a specific naming convention to Terraform variables. We are going to leverage this approach when configuring our environment.

  1. Sign in to OCI Console
  2. Go to Identity ➟ Users and note down the OCID of the user on whose behalf Terraform OCI Provider prepares, signs and makes OCI REST API requests.
  3. If you haven’t done it already, please upload the public part of your API Signing Key and note down the fingerprint of the public key.
    See: API Signing Key recipe (“Uploading the public key”), if needed.
  4. Go to AdministrationTenancy Details and note down the OCID of the tenancy.
  5. Please add the following variables to your environment (for example in ~/.profile):
    export TF_VAR_tenancy_ocid={put-here-the-tenancy-ocid}
    export TF_VAR_user_ocid={put-here-the-user-ocid}
    export TF_VAR_fingerprint={put-here-the-public-key-fingerprint}
    export TF_VAR_region={put-here-the-region} # for example: eu-frankfurt-1
    export TF_VAR_private_key_path={put-here-the-path-to-the-private-key}
    export TF_VAR_private_key_password={put-here-the-private-key-password}
  6. Let’s read the newly added variables to the bash session:

    source ~/.profile

Now you are ready to start defining Terraform projects.

Testing the connectivity

We are going to test the Terraform configuration by preparing a sample environment project. The project won’t provision anything but just read the CentOS images currently available on OCI.

  1. Create a new directory for your project. For example: ~/projects/oci_tf_test
    mkdir  ~/projects/oci_tf_test
  2. Define the provider configuration (provider.tf) together with the variables that will be mapped from operating system environment variables we’ve defined earlier:

    # ~/projects/oci_tf_test/provider.tf
    variable "tenancy_ocid" {}
    variable "user_ocid" {}
    variable "fingerprint" {}
    variable "region" {}
    variable "private_key_path" {}
    variable "private_key_password" {}
    provider "oci" {
      tenancy_ocid = "${var.tenancy_ocid}"
      user_ocid = "${var.user_ocid}"
      fingerprint = "${var.fingerprint}"
      region = "${var.region}"
      private_key_path = "${var.private_key_path}"
      private_key_password = "${var.private_key_password}"
  3. Initialize the working directory. Terraform will download the newest version of the provider plugin.

    ~/projects/oci_tf_test> terraform init
    Initializing provider plugins...
    - Checking for available provider plugins on https://releases.hashicorp.com...
    - Downloading plugin for provider "oci" (3.5.0)...
    The following providers do not have any version constraints in configuration,
    so the latest version was installed.
    To prevent automatic upgrades to new major versions that may contain breaking
    changes, it is recommended to add version = "..." constraints to the
    corresponding provider blocks in configuration, with the constraint strings
    suggested below.
    * provider.oci: version = "~> 3.5"
    Terraform has been successfully initialized!
  4. Define another test configuration file (data.tf) that will make Terraform fetching the available CentOS images and display them in the output:

    # ~/projects/oci_tf_test/data.tf
    data "oci_core_images" "centos_images" {
      compartment_id = "${var.tenancy_ocid}"
      operating_system = "CentOS"
    output "centos_images" {
      value = "${data.oci_core_images.centos_images.images}"
  5. Run terraform by applying the configuration:

    $ terraform apply

You should see a collection of JSON objects that describe the CentOS images available on OCI.

You can filter the output to see the information you are interested in like this:

$ terraform apply | grep display_name
        display_name = CentOS-7-2018.10.12-0,
        display_name = CentOS-7-2018.09.19-0,
        display_name = CentOS-7-2018.08.15-0,
        display_name = CentOS-6.10-2018.10.12-0,
        display_name = CentOS-6.10-2018.09.19-0,
        display_name = CentOS-6.10-2018.08.15-0,

Oracle Cloud Infrastructure Provider documentation can be found here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s