Using Object Storage for State Files
Store Terraform state files in Oracle Cloud Infrastructure Object Storage by configuring a backend.
When you update the terraform
block within the Terraform configuration to define a backend type, run terraform init
, and then run terraform apply
, the generated state file is uploaded to Object Storage.
This page addresses the following backend approaches:
Because variables and locals aren't accepted in the
terraform
block, you must hard-code backend configuration values.Using an HTTP Backend
Using the HTTP backend type allows you to store state using a simple REST client. With the HTTP backend type, you can easily fetch, update, and purge state using the HTTP
GET
, POST
, and DELETE
methods.
To configure the HTTP backend to store your OCI Terraform state files, do the following:
Create a Pre-Authenticated Request
Creating a pre-authenticated request in Oracle Object Storage enables accessing a bucket or object in the OCI without needing to provide credentials. To do so, you must create a pre-authenticated request that has read/write permissions to the object store where you intend to save the Terraform state file. You can do so in any of three ways: by using the Console UI, by using the command line interface (CLI), or by using the REST APIs.
A state file must exist in the bucket before you create the pre-authenticated request. This file can be an existing state file, or an empty file for the initial state.
For guidance, see Using Pre-Authenticated Requests.
Upload Existing State
If you have an existing state file, you can upload it using Curl to make an
HTTP
PUT
request to the object store URL, as shown here:
curl -X PUT -H "Content-Type: text/plain" --data-binary "@path/to/local/tfstate" http://<prefix>/<my-access-uri>
Configure HTTP as a Terraform Backend
The HTTP backend type stores state using a
simple REST client and allows you to easily fetch, update, and purge state using the
HTTP
GET
, POST
, and DELETE
methods.
The access URI for addressing OCI
Terraform configurations must be of the form :
https://objectstorage.us-phoenix-1.oraclecloud.com/my-access-uri
(where region and access URI are specific to you).
For more example configuration and state files that reference code, and a summary of configuration variables, see Standard Backends: HTTP.
Following is an example Terraform configuration. The region in the URL can be something other than the Phoenix region.
terraform {
backend "http" {
address = "https://objectstorage.us-phoenix-1.oraclecloud.com/<my-access-uri>"
update_method = "PUT"
}
}
Reinitialize Terraform
Finally, you must reinitialize Terraform and then run the apply
command:
terraform init
terraform apply
After completing these steps, you are able to use Oracle Cloud Infrastructure as the backend for storing Terraform state files.
Using an S3-Compatible Backend
To configure the S3-compatible backend, complete the steps in the following sections.
For more information about S3 compatibility, see Amazon S3 Compatibility API Prerequisites. For information about permissions for Object Lifecycle Management, see Required IAM Policies.
Setting Up Access to Oracle Cloud Infrastructure
Configuring Authentication
Configuring the Terraform Backend
Accessing Remote States
You can use the terraform_remote_state
data
source 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 your resources were in the same Terraform configuration folder, you could refer
to a compartment OCID from the VCN configuration by using something like this:
module.iam_compartment_SANDBOX.compartment_id
.
But assume that our definitions do not 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
Both governance
and networking
configurations store
their respective state files on an OCI
Object Storage bucket using the
remote-backend.tf
and
terraform-states_bucket_credentials
files.
In this example, the compartments.tf
file creates a compartment at
the root level using the iam-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 your 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 cannot be used from outside of its configuration.
Your governance/outputs.tf
file would look like 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 are 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 your 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 your compartment in the
same way.