Using Object Storage for State Files
Store Terraform state files in OCI Object Storage by configuring an S3-compatible or HTTP backend.
Using an S3-Compatible Backend
An S3-compatible backend is the preferred method for storing state files in Object Storage.
To configure the S3-compatible backend, complete the steps in the following sections.
Task 1: Set Up Access to OCI
Task 2: Configure Authentication
Task 3: Configure the S3 Backend in Terraform
terraform_remote_state
. For more information, see Accessing Remote States.Using an HTTP Backend
Because the HTTP backend requires a pre-authenticated request (PAR) for each state file, the preferred method for storing state files in Object Storage is an S3-compatible backend.
Use the HTTP backend type to store state using a REST client, and to fetch, update, and purge state using the HTTP
GET
, POST
, and DELETE
methods.
To configure the HTTP backend, complete the steps in the following sections.
Task 1: Upload Existing State
HTTP
PUT
request to the object store URL:
curl -X PUT -H "Content-Type: text/plain" --data-binary "@path/to/local/tfstate" http://<prefix>/<my-access-uri>
Task 2: Create a Read/Write Pre-Authenticated Request
With a pre-authenticated request (PAR) in Object Storage that specifies read/write permissions, you can access the Terraform state file without providing credentials.
For instructions to create a PAR using the Console, CLI, or API, see Creating a Pre-Authenticated Request in Object Storage.
Task 3: Configure the HTTP Backend in Terraform
terraform_remote_state
. For more information, see Accessing Remote States.Accessing Remote States
Use terraform_remote_state to access properties of objects in one Terraform configuration from another configuration.
For example, you might use one configuration to define compartments and another to define VCNs. If resources are in the same Terraform configuration folder, you can refer to a compartment OCID from the VCN configuration by using something such as this: module.iam_compartment_SANDBOX.compartment_id
.
But assume that our definitions don't share a state file and we have a file structure similar to the following:
.
├── governance
│ ├── compartments.tf
│ ├── outputs.tf
│ ├── remote-backend.tf
│ └── variables.tf
├── networking
│ ├── outputs.tf
│ ├── remote-backend.tf
│ ├── remote-state-data_governance.tf
│ ├── variables.tf
│ └── vcns.tf
└── terraform-states_bucket_credentials
In this example:
- Both
governance
andnetworking
configurations store their respective state files on an OCI Object Storage bucket using theremote-backend.tf
andterraform-states_bucket_credentials
files. - The
compartments.tf
file creates a compartment at the root level using theiam-compartment
module from the Terraform Registry as follows:module "iam_compartment_SANDBOX" { source = "oracle-terraform-modules/iam/oci//modules/iam-compartment" version = "2.0.0" tenancy_ocid = var.tenancy_ocid compartment_id = var.tenancy_ocid # define the parent compartment. Creation at tenancy root if omitted compartment_name = "SANDBOX" compartment_description = "Test and evaluate OCI features here" compartment_create = true # if false, a data source with a matching name is created instead enable_delete = true # if false, on `terraform destroy`, compartment is deleted from the terraform state but not from oci }
Defining Outputs
The terraform_remote_state
data source can access output values from another Terraform configuration using the latest state file with a remote backend. For the networking
configuration to access the governance
configuration and dynamically retrieve Terraform resources properties, you must define outputs for the governance
Terraform configuration. Without a defined output, the values can't be used from outside of its configuration.
The governance/outputs.tf
file would look similar to the following:
output "iam_compartment_SANDBOX" {
description = "compartment ocid, parent ocid, name, description"
value = {
id = module.iam_compartment_SANDBOX.compartment_id
parent_id = module.iam_compartment_SANDBOX.parent_compartment_id
name = module.iam_compartment_SANDBOX.compartment_name
description = module.iam_compartment_SANDBOX.compartment_description
}
}
Referring to a Remote State
In this example, we're using the vcn
module from Terraform Registry to define a new VCN. The networking
configuration refers to the governance
configuration to define the VCN's compartment OCID:
module "vcn_hub1iad" {
source = "oracle-terraform-modules/vcn/oci"
version = "2.2.0"
# general oci parameters
compartment_id = data.terraform_remote_state.governance.outputs.iam_compartment_SANDBOX["id"]
tags = var.tags
# vcn parameters
create_drg = false
internet_gateway_enabled = true
lockdown_default_seclist = true
nat_gateway_enabled = false
service_gateway_enabled = false
vcn_cidr = "10.0.0.0/16"
vcn_dns_label = "hub1iad"
vcn_name = "hub1"
}
But, for the compartment_id = data.terraform_remote_state.governance.outputs.iam_compartment_SANDBOX["id"]
line to be correctly interpreted, you must define a data.terraform_remote_state
object.
Defining the Remote State Data Source
After the following terraform_remote_state
data source is added to the networking
configuration, you can access the governance
Terraform outputs from configurations within the networking
folder:
data "terraform_remote_state" "governance" {
backend = "s3"
config = {
bucket = "terraform-states"
key = "governance/terraform.tfstate"
region = "us-phoenix-1"
endpoint = "https://acme.compat.objectstorage.us-phoenix-1.oraclecloud.com"
shared_credentials_file = "../terraform-states_bucket_credentials"
skip_region_validation = true
skip_credentials_validation = true
skip_metadata_api_check = true
force_path_style = true
}
}
If you define the remote state data source in a separate file, such as remote-state-data_governance.tf
, you can copy and paste the file as needed. Each new configuration can then refer to the compartment in the same way.