Terraform: Set Up OCI Terraform

In this tutorial, you set up Oracle Cloud Infrastructure Terraform provider scripts, documented in the Terraform Registry, to connect to an OCI account. To confirm the setup, you fetch information from the tenancy.

Key tasks include how to:

  • Create RSA keys.
  • Set up Oracle Cloud Infrastructure Terraform provider scripts:
    • Authenticate your Terraform scripts.
    • Get information about the availability domains in your tenancy.
A diagram of a user connected from a local environment to an Oracle Cloud Infrastructure tenancy. The local environment is Linux and has Terraform installed. There is an arrow from Terraform in the local environment connected to Terraform Registry in the cloud. There is a second arrow from the local environment sending a message to the user's Oracle Cloud Infrastructure tenancy labeled Authenticate?. The third arrow is from the tenancy to the local environment labeled Fetch Data. These arrows suggest that the user has set up their Terraform scripts to be authenticated by their tenancy. The user can then fetch information from the tenancy, by using Terraform and Terraform Registry. The tenancy displays three availability domains and that is the information that the user is fetching.

For additional information, see:

Before You Begin

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

MacOS or Linux
Note

This tutorial uses an Oracle Linux VM environment with an AMD shape for its examples, but you can use any environment mentioned in this section.

1. Prepare

Prepare your environment for authenticating and running Terraform scripts. Also, gather the information your account needs to authenticate the scripts.

Install Terraform

This tutorial suggests that you install the latest version of Terraform that's supported for OCI Resource Manager. Resource Manager is a service for creating Terraform templates for OCI resources. In case you want to use Resource Manager with your Terraform scripts later, then your Terraform version is supported.

  1. In your environment, check the Terraform version.
    terraform -v
    If you don't have the latest supported Terraform version, then install the latest supported version using the following steps.
  2. From a browser, go to Terraform Releases.
  3. Click the folder with the latest supported version.

    Example: terraform_1.2.9

  4. Copy the name of the zip file that matches your environment into a notepad.

    terraform_<version>_<your_environment>.zip

    Example for an Oracle 64-bit Linux AMD environment: terraform_1.2.9_linux_amd64.zip

  5. In your environment, create a temp directory and change to that directory:
    mkdir temp
    cd temp
  6. Download the Terraform zip file:
    wget https://releases.hashicorp.com/terraform/<version>/terraform_<version>_<your_environment>.zip
    Tip

    • You can construct the URL by copying the address from the browser. Note that <version> doesn't include the word terraform.

    Example:

    wget https://releases.hashicorp.com/terraform/1.2.9/terraform_1.2.9_linux_amd64.zip
  7. Unzip the file. Example:
    unzip terraform_1.2.9_linux_amd64.zip
  8. Move the unzipped folder to a folder that contains the binaries of the third-party apps that you install. For example, for Oracle Linux, move the unzupped folder to /usr/local/bin:
    sudo mv terraform /usr/local/bin
  9. Go back to your home directory:
    cd
  10. Check the Terraform version:
    terraform -v

    Example: Terraform v1.2.9 on linux_amd64

You have now successfully installed Terraform.
Create RSA Keys

If you created RSA keys for the Terraform Set Up Resource Discovery tutorial, then skip this step.

You create RSA keys for API signing in to your Oracle Cloud Infrastructure account.

Note

If you're using Cloud Shell, skip creating the RSA keys. You're already authenticated when you log in to the OCI Console.
  1. Open a terminal window.
  2. Under your home directory, make an .oci directory.
    mkdir <your-home-directory>/.oci

    Example for Oracle Linux:

    mkdir /home/opc/.oci
    Note

    If you're using Windows Subsystem for Linux (WSL), create the /.oci directory directly in the Linux environment. If you create the /.oci directory in a /mnt folder (Windows file system), you're required to use the chmod command to change permissions for the WSL configuration files.
  3. Generate a 2048-bit private key in a PEM format:
    openssl genrsa -out <your-home-directory>/.oci/<your-rsa-key-name>.pem 2048
  4. Change permissions, so only you can read and write to the private key file:
    chmod 600 <your-home-directory>/.oci/<your-rsa-key-name>.pem
  5. Generate the public key:
    openssl rsa -pubout -in <your-home-directory>/.oci/<your-rsa-key-name>.pem -out $HOME/.oci/<your-rsa-key-name>_public.pem
  6. Copy the public key.
    In the terminal, enter:
    cat <your-home-directory>/.oci/<your-rsa-key-name>_public.pem
  7. Add the public key to your user account.
    • In the OCI Console's top navigation bar, click the Profile menu, and then go to User settings.
    • Click API Keys.
    • Click Add API 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 OCI account.

Reference

Generating RSA Keys

Add List 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 <the-group-your-username-belongs> to read all-resources in tenancy

With this privilege, you can list all the resources in your tenancy.

Steps to Add the Policy
  1. In the top navigation bar, open the Profile menu.
  2. Click your username.
  3. In the left pane, click Groups.
  4. In a notepad, copy the Group Name that your username belongs.
  5. Open the navigation menu and click Identity & Security. Under Identity, click Policies.
  6. Select <your-tenancy>(root) from the Compartment dropdown.
  7. Click Create Policy.
  8. Fill in the following information:
    • Name: list-resources
    • Description: Allow the group <the-group-your-username-belongs> to list the resources in this tenancy.
    • Compartment: <your-tenancy>(root)
  9. For Policy Builder, click Show manual editor.
  10. Paste in the following policy:
    allow group <the-group-your-username-belongs> to read all-resources in tenancy
  11. Click Create.

Reference: Common Policies

Gather Required Information

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

  1. Collect the following credential information from the OCI Console.
    • Tenancy OCID: <tenancy-ocid>
      • In the top navigation bar, click the Profile menu, go to Tenancy: <your-tenancy> and copy OCID.
    • User OCID: <user-ocid>
      • From the Profile menu, go to User settings and copy OCID.
    • Fingerprint: <fingerprint>
      • From the Profile menu, 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.
      • From the table in Regions and Availability Domains, Find your region's <region-identifier>. Example: us-ashburn-1.
  2. Collect the following information from your environment.
    • Private Key Path: <rsa-private-key-path>
      • Path to the RSA private key you made in the Create RSA Keys section.

        Example for Oracle Linux: /home/opc/.oci/<your-rsa-key-name>.pem

2. Create Scripts

Create three scripts: one for authentication, one to fetch data from your account, and one to print outputs.

Add API Key-Based Authentication

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

  1. In <your-home-directory>, create a directory called tf-provider and change to that directory.
    mkdir tf-provider
    cd tf-provider
  2. Create a file called provider.tf.
  3. Add the following code to provider.tf:
    • Replace the fields with brackets, with information from the Gather Required Information section.
    • 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>"
    }
  4. Save the provider.tf file.
Explanation

Use the following variables for API Key based authentication:

  • tenancy_ocid
  • user_ocid
  • private_key_path
  • fingerprint
  • region
For details about OCI Terraform provider, see
Tip

You don't need to install the provider. The provider is downloaded when you run the scripts in this tutorial.
Add a Data Source

In this section, you fetch a list of the availability domains in your tenancy. By fetching data, you confirm that your OCI account authenticates your provider.tf script and you get information from your account.

  1. In the tf-provider directory, create a file called availability-domains.tf.
  2. Add the following code to availability-domains.tf, replacing the field with brackets, with information from the Gather Required Information section.
    # Source from https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_availability_domains
    
    # Tenancy is the root or parent to all compartments.
    # For this tutorial, use the value of <tenancy-ocid> for the compartment OCID.
    
    data "oci_identity_availability_domains" "ads" {
      compartment_id = "<tenancy-ocid>"
    }
    Note

    The data source gets a list of availability domains in your entire tenancy. The tenancy is the compartment OCID for the root compartment. Providing a specific "<compartment-ocid>" or the "<tenancy-ocid>" outputs the same list.
    Important

    Ensure provider.tf and availability-domains.tf are in the same directory. Terraform processes all the files in a directory in the correct order, based on their relationship. For a modular approach and future reuse, separate the provider file from other scripts.
Explanation

In Terraform, to fetch data, you use a data source. Fetching data from a data source is similar to the GET method in REST APIs.

  • Go to Oracle Cloud Infrastructure Provider.
  • In the left navigation Filter, enter availability domains.
  • Under Identity, go to Data Sources and click oci_identity_availability_domains.
  • Find the Data Source name from the title of the page:
    • Data Source: oci_identity_availability_domains
  • In the Argument Reference section, find all arguments (inputs) labeled as (Required):
    • compartment_id
  • Construct a data source block:
    • Declare a data source with the keyword: data.
    • Add a label for the data source name: "oci_identity_availability_domains"
    • Add a label of your choice for the local name:
      • The label can contain letters, digits, underscores (_), and hyphens (-). The first character must not be a digit.
      • This tutorial uses the local name, "ads" to construct data "oci_identity_availability_domains" "ads".
    • Inside the code block, provide values for all required arguments.
      • Example: compartment_id = "<some-compartment-ocid>"
    • For optional arguments, provide values to narrow down the fetch results. Only some data sources have optional arguments.
Add Outputs

The data source oci_identity_availability_domains, fetches a list of availability domains. In this section, you declare an output block to print the fetched information.

  1. In the tf-provider directory, create a file called outputs.tf.
  2. Add the following code to outputs.tf.
    # Output the "list" of all availability domains.
    output "all-availability-domains-in-your-tenancy" {
      value = data.oci_identity_availability_domains.ads.availability_domains
    }
  3. Save the outputs.tf file.
    Important

    Ensure outputs.tf, provider.tf, and availability-domains.tf are in the same directory.
Explanation
  • On the Data Source: oci_identity_availability_domains page, go to Attribute Reference.
    Note

    Attributes are the outputs you can return for the oci_identity_availability_domains data source.
  • Find the attributes:
    • Attribute: availability_domains:
      • The list of availability domains
      • If you output availability_domains, you get three attributes for each availability domain in the list:
        • compartment_id
        • id
        • name
  • Construct a data source output block:
    • Declare an output block with the keyword: output
    • Add a label to be printed with the output results:
      • The label can contain letters, digits, underscores (_), and hyphens (-). The first character must not be a digit.
      • Example: "all-availability-domains-in-your-tenancy"
    • Inside the code block, enter a value for the data source output with the expression:
      • value = data.<data-source-name>.<local-name-for-data-source>.<attribute>
      • Example: value = data.oci_identity_availability_domains.ads.availability_domains

3. Run Scripts

Run your Terraform scripts. After your account authenticates the scripts, Terraform fetches your tenancy's availability domains.

Initialize

Initialize a working directory in the tf-provider directory.

  1. Run the Terraform init command.
    terraform init

    Example output:

    Initializing the backend...
    
    Initializing provider plugins...
    - Finding latest version of hashicorp/oci...
    - Installing hashicorp/oci vx.x.x...
    - Installed hashicorp/oci vx.x.x (signed by HashiCorp)
    
    Terraform has been successfully initialized!
  2. Check the contents of the tf-provider directory.
    ls -a

    You now have a folder called .terraform that includes the plugins for the oci provider.

    Note

    Troubleshooting:
    • After running terraform init
    • error message: Failed to query available provider packages:
      • If you are on a VPN, check your proxy settings.
Plan

Create an execution plan to check whether the changes shown in the execution plan match your expectations, without changing the real resources.

  1. Run the Terraform plan command.
    terraform plan
  2. Confirm that you have Plan: 0 to add, 0 to change, 0 to destroy.

    Example output:

    Changes to Outputs:
      + all-availability-domains-in-your-tenancy = [
          + {
              + compartment_id = "ocid1.tenancy.oc1..xxx"
              + id             = "ocid1.availabilitydomain.xxx"
              + name           = "QnsC:US-ASHBURN-AD-1"
            },
          + {
              + compartment_id = "ocid1.tenancy.oc1..xxx"
              + id             = "ocid1.availabilitydomain.xxx"
              + name           = "QnsC:US-ASHBURN-AD-2"
            },
          + {
              + compartment_id = "ocid1.tenancy.oc1..xxx"
              + id             = "ocid1.availabilitydomain.xxx"
              + name           = "QnsC:US-ASHBURN-AD-3"
            },
        ]
    
    You can apply this plan to save these new output values to the Terraform state, without changing any real
    infrastructure.
    
    Note

    • You're fetching data, so the plan shows that you are only adding outputs. You're not adding, changing, or destroying any resources.
    • You're using the output.tffile instead of the -out option, so you can ignore the following message:
      Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform
      apply" now.
Apply
  1. Run your Terraform scripts and get your outputs:
    terraform apply
  2. When prompted for confirmation, enter yes, for your resource to be created.

    After you run the apply command, the output is displayed in the terminal.

    Example output:
    Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
    
    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"
      },
    ])

Congratulations! Your Oracle Cloud Infrastructure account can now authenticate your Oracle Cloud Infrastructure Terraform provider scripts.

References:

Troubleshooting

You might encounter the following error messages while running your Terraform scripts.

401 Errors - (Service error:NotAuthenticated)

One of the following variables has an incorrect value:

  • Tenancy OCID
  • User OCID
  • Fingerprint
  • RSA private key (the path or the key)
  1. In the provider.tf file, double-check the variable names and their values.
    provider "oci" {
      tenancy_ocid = "<tenancy-ocid>"
      user_ocid = "<user-ocid>" 
      private_key_path = "<rsa-private-key-path>"
      fingerprint = "<fingerprint>"
      region = "<region-identifier>"
    }
  2. Update the variables or their values as needed.
  3. Ensure that you added quotations around string values.
  4. Run the scripts.

Can not create client, bad configuration: did not find a proper configuration for private key

The Terraform scripts can't find the RSA private key.

  1. Repeat the steps for creating RSA keys and use the updated key.
  2. Ensure that in the provider.tf file, the variable describing the RSA is called private_key_path.
    private_key_path = "<rsa-private-key-path>"
  3. Ensure the path to the RSA private key in the provider.tf file is correct. For example, ensure that the path starts with a slash and has the correct name for the private key, <your-rsa-key-name>.pem
  4. Remove environment variables from the <rsa-private-key-path>.

    For example, in the provider.tf file, instead of $HOME/.oci/<rsa-private-key-path>, use /home/opc/<rsa-private-key-path>.

    Note

    If you're using Windows Subsystem for Linux (WSL), create the /.oci directory directly in the Linux environment. If you create the /.oci directory in a /mnt folder (Windows file system), you're required to use the chmod command to change permissions for the WSL configuration files.

No such host

The region identifier has an incorrect value.

  1. In the Console's top navigation bar, find your region.
  2. In the table listed in Regions and Availability Domains, find your region's <region-identifier>. Example: us-ashburn-1.
  3. In the provider.tf file, update the value for <region-identifier> and try again.

Failed to query available provider packages

If you are on a VPN, check the proxy settings.

  1. Disconnect from VPN.
  2. Connect to your VM or your environment without the VPN and run the following Terraform scripts.
    terraform init
    terraform plan
    terraform apply
    If you don't get an error message, then the VPN proxy settings are causing the error.
  3. Consult with your administrator, update the proxy settings, and try again.