Configure the Terraform Execution Environment

The Terraform execution environment includes the layout of the folders and Terraform configuration files required to build the multitier network topology.

About the Terraform Execution Environment

The layout of the Terraform execution environment is designed for modularity and future growth.

The directories and files that contain your Terraform configuration constitute the execution environment. Each subdirectory represents a Terraform module. Together, the subdirectories make up a reusable library of resources.

The following directory structure represents the execution environment that you build in this solution.

Description of local_directory_structure.png follows
Description of the illustration local_directory_structure.png

The entire configuration is within a root directory that has a name of your choice. This directory must be empty when you begin.

After you create the configuration, the root directory contains the following directories and files:

  • The compartments directory contains the configuration parameters for the compartments.
  • The iam directory contains the configuration parameters for the policies and groups.
  • The vcn directory contains the configuration parameters for the virtual cloud network and the gateways.
  • The following files are in the root directory:
    • datasources.tf determines the number of availability domains in the region and gets their names.
    • provider.tf defines the parameters of the Terraform providers to be used.
    • root.tf defines the modules that Terraform should execute.
    • terraform.tvars defines the values of the variables that you pass to Terraform.
    • variables.tf declares the variables that the modules in the configuration use.

Create the Root Module

In the root module, you define the parameters that are necessary for Terraform to connect to Oracle Cloud Infrastructure. You also define the data and variables that the modules in the configuration use.

  1. On the computer where you installed Terraform, create a directory, referred to as the root directory in the remainder of this solution.
  2. Create the following subdirectories in the root directory:
    • compartments
    • iam
    • vcn
  3. Create a text file named variables.tf in the root directory, and paste the following code in the file.
    This code declares the variables that the modules in the Terraform configuration use. In the next step, you specify the values of these variables.
    variable "tenancy_ocid" {}
    variable "user_ocid" {}
    variable "fingerprint" {}
    variable "private_key_path" {}
    variable "private_key_password" {}
    variable "app_tag" {}
    variable "environment" {}
    variable "home_region" {}
    variable "region" {}
    variable "vcn_cidr" {
      default = "10.0.0.0/16"
    }
    
  4. Create a text file named terraform.tfvars in the root directory, and paste the following code in the file.
    In this code, you define the values of the variables that were declared in the previous step.
    # Parameters to authenticate with Oracle Cloud Infrastructure
    tenancy_ocid="EXAMPLE: ocid1.tenancy.oc1..aaaaaaaaf76usem7gyfrakr35anvky4tyowvdvbik7kbrcizlyjsgfxpdg2a"
    user_ocid="EXAMPLE: ocid1.user.oc1..aaaaaaaa5tds42w2zzbsdflkjwerkjghswdjfbvbts7imlb5yru2p10a"
    fingerprint="EXAMPLE: 9b:6a:ab:ab:32:0b:7f:d5:5b:6w:c0:fe:54:72:f1:pl"
    private_key_path="YOUR_HOME_DIRECTORY/.oci/oci_api_key.pem"
    
    # Leave empty if your private key does not have a password
    private_key_password=""
    
    # See https://docs.oracle.com/pls/topic/lookup?ctx=cloud&id=oci_general_regions
    home_region="EXAMPLE: us-ashburn-1"
    region="EXAMPLE: us-phoenix-1"
    
    # A short identifier for the application, used as a prefix for naming the compartments and other resources
    app_tag="myapp"
    
    # The environment that you're creating resources for: test, dev, prod, or staging
    environment="dev"
    
    # Base CIDR for the VCN
    vcn_cidr="10.0.0.0/16"
  5. Update the values of the variables in terraform.tfvars as described in the following table:
    Variable Description
    tenancy_ocid The Oracle Cloud ID (OCID) of the tenancy.

    To find your tenancy's OCID, select Administration from the services menu, and then click Tenancy Details.

    user_ocid The Oracle Cloud ID (OCID) of the user that you want Terraform to use to authenticate with Oracle Cloud Infrastructure.

    To find the user's OCID, select Identity from the services menu, and then select Users. Find your user name in the list, and copy the OCID value.

    fingerprint The fingerprint for the API signing key that you uploaded.
    private_key_path The path to the file that contains your private key.
    private_key_password The passphrase for the private key. If the key doesn't have a passphrase, then leave this variable empty.
    home_region The home region of the tenancy. Compartments, policies, and groups are created in the home region.

    To get the home region, select Administration from services menu, click Tenancy Details, and copy the value in the Home Region field.

    region The region where you want to create the networking, compute, and other resources. This region can be the home region or any other Oracle Cloud Infrastructure region.
    app_tag A prefix to be used in the names of your resources, to indicate the application that each resource is for. A best practice is to use all lowercase characters.
    environment A prefix to be used in the names of your resources, to indicate the environment that each resource is for: development, test, staging, or production. A best practice is to use all lowercase characters.
    vcn_cidr The address range of the VCN, in CIDR format. Plan this range carefully. You can't change it later.
  6. Create a text file named datasources.tf in the root directory, and paste the following code in the file.
    The code in datasources.tf determines the number of availability domains in the region and their names. This code uses the region that you specify in the region variable.
    data "oci_identity_availability_domains" "ad" {
      compartment_id = "${var.tenancy_ocid}"
    }
    
    data "template_file" "ad_names" {
      count    = "${length(data.oci_identity_availability_domains.ad.availability_domains)}"
      template = "${lookup(data.oci_identity_availability_domains.ad.availability_domains[count.index], "name")}"
    }
  7. Create a text file named provider.tf in the root directory, and paste the following code in the file.
    The code in provider.tf defines the parameters for the provider that Terraform should use. A provider translates Terraform commands into API calls specific to a cloud service provider.
    provider "oci" {
      alias                = "home"
      region               = "${var.home_region}"
      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}"
    }
    
    provider "oci" {
      region               = "${var.region}"
      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}"
    }
    This example defines two providers. Both providers are for Oracle Cloud Infrastructure. The first provider is for the home region, where you create the Oracle Cloud Infrastructure Identity and Access Management resources. The second provider is for the region where you want to create the networking, compute, and other resources.
  8. Create a text file named root.tf in the root directory, and paste the following code in the file.
    This code specifies the modules that Terraform must execute. The provider is explicitly specified for the compartments and iam modules, because the compartments, groups, and policies must be created in the home region.
    module "compartments" {
      source       = "./compartments"
      tenancy_ocid = "${var.tenancy_ocid}"
      app_tag      = "${var.app_tag}"
      environment  = "${var.environment}"
    
      providers = {
        oci = "oci.home"
      }
    }
    
    module "a_vcn" {
      source           = "./vcn"
      tenancy_ocid     = "${var.tenancy_ocid}"
      compartment_ocid = "${module.compartments.networks_id}"
      app_tag          = "${var.app_tag}"
      environment      = "${var.environment}"
      vcn_cidr         = "${var.vcn_cidr}"
    }
    
    module "iam" {
      source       = "./iam"
      tenancy_ocid = "${var.tenancy_ocid}"
      app_tag      = "${var.app_tag}"
      environment  = "${var.environment}"
    
      providers = {
        oci = "oci.home"
      }
    }
    The app_tag and environment variables enforce a naming scheme. Using a naming scheme is not required, but it is a best practice.