Example of how to use Oracle Cloud Infrastructure (OCI) Gen 2 with Terraform – MacBook Pro OS – part 1

Terraform is becoming more and more relevant in DBA’s activities. Therefore, I decided to start a series of articles where I will be covering the use of Terraform with Oracle Cloud Infrastructure from the scratch. It is important to mention that both Oracle Infrastructure and Terraform has been evolving daily and modifications on the steps can arise after a while. The steps here are from October 2020 and may be accurate for the next nearest months.

Before we start let’s learn new concepts. What is Terraform?

To answer this question that it is also at the Terraform’s documentation , let’s use the answer from their documentation .

Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.

Configuration files describe to Terraform the components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.

The infrastructure Terraform can manage includes low-level components such as compute instances, storage, and networking, as well as high-level components such as DNS entries, SaaS features, etc.

For a matter of fact, terraform belongs to HashiCorp which is a Software company that started in 2012.

Now that we have a glimpse of Terraform, lets follow up on the pre-requisite to start building an Oracle Infrastructure, we will need you to have your account created at the Oracle Cloud. An interesting fact comparing Oracle Cloud with the cloud from other providers is that Oracle Cloud is the only one that at this date (18 Oct 2020) that has a native support from Terraform announced in March 2018 https://blogs.oracle.com/developers/announcing-terraform-support-for-oracle-cloud-platform-services.

When it comes to Oracle Cloud you can create a free-tier account that comes with the following services

  • Autonomous Data Warehouse
  • Autonomous Transaction Processing
  • Compute
  • Block Volume
  • Object Storage
  • Archive Storage
  • Load Balancing
  • Monitoring
  • Notifications
  • Outbound Data Transfer

You can create your free account here: https://signup.oraclecloud.com/?language=en&sourceType=:ow:o:p:feb:0916FreePageBannerButton&intcmp=:ow:o:p:feb:0916FreePageBannerButton

Getting started with Oracle Cloud Infrastructure

After you have created your account the next step is login into Oracle Cloud using the tenancy name you chose while creating your account:

  • Go to https://www.oracle.com/cloud/sign-in.html and choose the method of login. On the example below I will choose to connect using a Cloud Account Name. Therefore, after your see the screen as below click in “Sign In using a Cloud Account Name”:

Then you will be redirected to the screen where you can use the tenancy name of your Oracle Cloud to login. In this article, the cloud to be used as an example will be called “brunoreistechdatabasket”. However, use your tenancy name and credentials for a successful login. In the following screens you will see the login using this cloud:

After you perform the login you will be able to see the Oracle Cloud console as below:

Just to add more information: Oracle has Oracle Cloud Infrastructure Classic also known as OCI-C. OCI-C was announced at Oracle Open World (OOW) 2014 as OPC and was renamed to OCI-C at OOW 2017- Also at OOW 2017 was announced the Oracle Cloud Infrastructure (OCI) Gen 2. The differences between the two types of instances build in infrastructure can be found here : https://docs.oracle.com/en/cloud/paas/event-hub-cloud/admin-guide/ociversusocic.html

Image taken from Oracle documentation

You can see differences already on the console once you login:

As the difference between OCI and OCI-C has been shown, login to your OCI console as below:

Once one of the pre-requisites which was created an account is done, the next step is to get started with Terraform. For that we will go to the Terraform’s provider website tab https://registry.terraform.io/providers/hashicorp/oci/latest/docs at their website, copy the example to configure  Oracle Cloud Infrastructure provider with an API Key and using this example will guide the next steps. So, this is the script:

provider "oci" {
  tenancy_ocid = var.tenancy_ocid
  user_ocid = var.user_ocid
  fingerprint = var.fingerprint
  private_key_path = var.private_key_path
  private_key_password=var.private_key_password
  region = var.region
}

Some considerations regarding this script can be done already. Although it has been using variables to replace them with values defined directly. Other information such as the tenancy and user ocid, fingerprint, path to the private key and region which are information needed at this script can be found at the OCI console. Therefore, this will be the next steps:

Tenancy information- OCID: To be able to get the OCID of your tenancy, you go to your profile (located at the right top side of your screen) and then click in “tenancy”. Once on the tenancy tab you will be able to see the OCID. Therefore, get this information and take a note of it to use in the future.

User information- OCID: By default, Oracle creates two users for you once your account is created. To be able to see this click on the button located at the upper left side of your screen, after in “Identity” and “Users” tab. You can either create a new user if you would like to or use the created user based on your e-mail. In case you create a new user just make sure that this new user has all the necessary permissions. You can check it under “Policies” tab of your identity. Regardless of your choice regarding the creation of the user, click on the user tab and take a note of the OCID of this user as below:

Fingerprints: It is necessary to create a private key and after providing the public key in order to use as a value on the fingerprints field on the script. To do that Oracle has a to-do procedure in its own documentation according to your operating systems as below: https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#two

Each step will have my own execution afterwards:

1- If you haven't already, create a .oci directory to store the credentials:
mkdir ~/.oci     

Example:
brunotechdatabasket@Brunos-MacBook-Pro ~ % pwd
/Users/brunotechdatabasket
brunotechdatabasket@Brunos-MacBook-Pro ~ % mkdir ~/.oci  

brunotechdatabasket@Brunos-MacBook-Pro ~ % cd .oci

2- Generate the private key with one of the following commands.
	•	To generate the key, encrypted with a passphrase you provide when prompted:

openssl genrsa -out ~/.oci/oci_api_key.pem -aes128 2048                    

brunotechdatabasket@Brunos-MacBook-Pro .oci % openssl genrsa -out ~/.oci/oci_api_key.pem -aes128 2048                    
Generating RSA private key, 2048 bit long modulus
............................+++
..................................................................................+++
e is 65537 (0x10001)
Enter pass phrase for /Users/brunotechdatabasket/.oci/oci_api_key.pem:
Verifying - Enter pass phrase for /Users/brunotechdatabasket/.oci/oci_api_key.pem:
brunotechdatabasket@Brunos-MacBook-Pro .oci % 

3-Change the file permission to ensure that only you can read the private key file:

Copy
chmod go-rwx ~/.oci/oci_api_key.pem     

4-Generate the public key from your new private key:

openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.p

brunotechdatabasket@Brunos-MacBook-Pro .oci % openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.pem             
Enter pass phrase for /Users/brunotechdatabasket/.oci/oci_api_key.pem:
writing RSA key
brunotechdatabasket@Brunos-MacBook-Pro .oci % ls -ltr
total 16
-rw-------  1 brunotechdatabasket  staff  1766 Oct 15 10:29 oci_api_key.pem
-rw-r--r--  1 brunotechdatabasket  staff   451 Oct 15 10:31 oci_api_key_public.pem
brunotechdatabasket@Brunos-MacBook-Pro .oci % 


5-Copy the contents of the public key to the clipboard using pbcopy, xclip or a similar tool (you'll need to paste the value into the Console later). For example:

cat ~/.oci/oci_api_key_public.pem | pbcopy           

brunotechdatabasket@Brunos-MacBook-Pro .oci %  cat ~/.oci/oci_api_key_public.pem
-----BEGIN PUBLIC KEY-----

After you need to place the value of your public key on your OCI. To be able to do that you should go to “Identity” tab and after “Users”, choose the user that you have chosen to be part of this setup, e.g. at this example I created a new user called ADMIN :

At the user screen, right below the “Groups” tab click in “API Keys” and after at the button “ADD public key” where you will have to copy and paste the value of your public key created previously:

After you write the value of your public key and click on the button “Add” a new fingerprint will be created and shown to you. Copy this value and save it once it will be used within the Terraform script.

Region: This value is simple to get. Just click at “Manage regions” below the region that you are logged in and then you will be moved to a screen where you can see the region id of all regions. (Choose the id of the region that you are using.)

Now that we have collected all the information for the terraform script, replace each field with their respective values as below:


# Configure the Oracle Cloud Infrastructure provider with an API Key
provider "oci" {
  tenancy_ocid ="ocid1.tenancy.oc1..aaaaaaaaflrtum2h76ryycq3l3bfiwkqfekinzvji6k4kdqc3wpqp7wzofpq"
  user_ocid ="ocid1.user.oc1..aaaaaaaaeqy5pjiqa6tqyifj37vg7x2x6jy3e7ruoaywxbcdy4zmf5grjcpa" 
  fingerprint =“some fingerprint value here” 
  private_key_path ="/Users/brunotechdatabasket/.oci/oci_api_key.pem" 
  region ="uk-london-1" 
}

Note that as the use of variables were replaced by values with quotation marks. Feel free to use it as you would like to.

To proceed with the configuration, it will be needed to describe the concept of Data Source in Terraform. The following code lines is an example of Data Source:

# Get a list of Availability Domains
data "oci_identity_availability_domains" "ads" {
  compartment_id = var.tenancy_ocid
}

What is Data Source while using Terraform?

The answer is found here: https://www.terraform.io/docs/configuration/data-sources.html

Data sources allow data to be fetched or computed for use elsewhere in Terraform configuration. Use of data sources allows a Terraform configuration to make use of information defined outside of Terraform, or defined by another separate Terraform configuration.

At this example we will keep using the example showed at Terraform’s documentation which is “oci_identity_availability_domains” (https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/identity_availability_domain) but if you would like to know more about the different types of Data Source while using OCI and Terraform, you can dig the “Data Source” section within “Identity”. You can also use resources but this will be a subject to other article.

Therefore, to be able to fulfil the value of the script above it is needed to pick up the compartment id.

What is compartment in OCI? According to the OCI’s documentation

Compartments are tenancy-wide, across regions. When you create a compartment, it is available in every region that your tenancy is subscribed to. You can get a cross-region view of your resources in a specific compartment with the compartment explorer.

When you create your OCI account you have a default root compartment. I would suggest you create a compartment rather than place your services directly under the root compartment. Therefore, at this example I created a compartment called “OCIochTerraform”.

Thus we are able to fulfil the values for the Data Source previously. Therefore the script at this stage can be seen as below:

# Configure the Oracle Cloud Infrastructure provider with an API Key
provider "oci" {
  tenancy_ocid ="ocid1.tenancy.oc1..aaaaaaaaflrtum2h76ryycq3l3bfiwkqfekinzvji6k4kdqc3wpqp7wzofpq"
  user_ocid ="ocid1.user.oc1..aaaaaaaaeqy5pjiqa6tqyifj37vg7x2x6jy3e7ruoaywxbcdy4zmf5grjcpa" 
  fingerprint =“some fingerprint value here” 
  private_key_path ="/Users/brunotechdatabasket/.oci/oci_api_key.pem" 
  region ="uk-london-1" 
}


# Get a list of Availability Domains
data "oci_identity_availability_domains" "ads" {
  compartment_id ="ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" 
}

At this step all the values necessary within the script is already in place and the complete viewing as it is now:

# Configure the Oracle Cloud Infrastructure provider with an API Key
provider "oci" {
  tenancy_ocid ="ocid1.tenancy.oc1..aaaaaaaaflrtum2h76ryycq3l3bfiwkqfekinzvji6k4kdqc3wpqp7wzofpq"
  user_ocid ="ocid1.user.oc1..aaaaaaaaeqy5pjiqa6tqyifj37vg7x2x6jy3e7ruoaywxbcdy4zmf5grjcpa" 
  fingerprint =“some fingerprint value here” 
  private_key_path ="/Users/brunotechdatabasket/.oci/oci_api_key.pem" 
  region ="uk-london-1" 
}


# Get a list of Availability Domains
data "oci_identity_availability_domains" "ads" {
  compartment_id ="ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" 
}

# Output the result
output "show-ads" {
  value = data.oci_identity_availability_domains.ads.availability_domains
}

Nevertheless, even though all the script is already configured, we will need to install the Terraform tool: (to more information see Terraform documentation : https://packagecontrol.io/packages/Terraform )

You can either download Terraform directly from its website :https://www.terraform.io/downloads.html or using the Sublime Text tool which can be downloaded here https://www.sublimetext.com/3.

Whichever installation method you prefer, after the installation, configure the Path to be able to start the Terraform anytime :

Last login: Thu Oct 15 10:25:49 on ttys000
brunotechdatabasket@Brunos-MacBook-Pro ~ % /Users/brunotechdatabasket/Downloads/terraform\ 2 ; exit;
Usage: terraform [-version] [-help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
    destroy            Destroy Terraform-managed infrastructure
    env                Workspace management
    fmt                Rewrites config files to canonical format
    get                Download and install modules for the configuration
    graph              Create a visual graph of Terraform resources
    import             Import existing infrastructure into Terraform
    init               Initialize a Terraform working directory
    login              Obtain and save credentials for a remote host
    logout             Remove locally-stored credentials for a remote host
    output             Read an output from a state file
    plan               Generate and show an execution plan
    providers          Prints a tree of the providers used in the configuration
    refresh            Update local state file against real resources
    show               Inspect Terraform state or plan
    taint              Manually mark a resource for recreation
    untaint            Manually unmark a resource as tainted
    validate           Validates the Terraform files
    version            Prints the Terraform version
    workspace          Workspace management

All other commands:
    0.12upgrade        Rewrites pre-0.12 module source code for v0.12
    0.13upgrade        Rewrites pre-0.13 module source code for v0.13
    debug              Debug output management (experimental)
    force-unlock       Manually unlock the terraform state
    push               Obsolete command for Terraform Enterprise legacy (v1)
    state              Advanced state management

[Process completed]


Brunos-MacBook-Pro:/ root# mv /Users/brunotechdatabasket/Downloads/terraform /usr/local/bin
Brunos-MacBook-Pro:/ root# 

Initialise the Terraform using the command “terraform init”:


brunotechdatabasket@Brunos-MacBook-Pro Terraform % terraform init                        

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/oci...
- Installing hashicorp/oci v3.97.0...
- Installed hashicorp/oci v3.97.0 (signed by HashiCorp)

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, we recommend adding version constraints in a required_providers block
in your configuration, with the constraint strings suggested below.

* hashicorp/oci: version = "~> 3.97.0"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

This first article on this series has already gotten us using both OCI and a glimpse about Terraform tool. It also described some important concepts such as Data Sources and Compartments. On the upcoming articles more information will be showed to provide a better understanding about how to use OCI among Terraform.

Related posts

Leave a Comment