Using OCI Bucket for Terraform/OpenTofu remote state backend
Tags: oraclecloud, cloud, terraform
Published: 2024-07-02 20:19:03

_Store Terraform state files in Oracle Cloud Infrastructure (OCI) Object Storage by configuring an S3-compatible backend._

A Terraform backend defines where Terraform stores its state data files. Without a backend, the state file lives locally on a single machine, making it hard for others to work based on the same cloud state, as well as having to store sensitive information locally.

This page describes how to configure an S3-compatible backend on OCI Object Storage Bucket by adding the backend block to your configuration.

## A simple example

### Assumptions
- A Terraform/OpenTofu version >= 1.7

### 1. Install Terraform/OpenTofu

Follow the official installation page to install the Terraform or OpenTofu CLI on your machine:
- [Terraform](https://developer.hashicorp.com/terraform/install)
- [OpenTofu](https://opentofu.org/docs/intro/install)

All instructions in this doc will use the `terraform` CLI and otherwise refer to Terraform. Simply swap `terraform` with `tofu` if you prefer to use OpenTofu as all instructions and file contents are otherwise similar.

### 2. Configure the OCI Provider profile

To deploy OCI resources, you need access to manage the resources from your machine. This can be achieved using an API Key. To complete this step, see [Setting up the OCI Configuration File using API Keys](https://dev.to/farisdurrani/setting-up-the-oci-configuration-file-using-api-keys-96c).

### 3. Create your AWS Customer Secret Key

Create a Customer Secret Key on your OCI console. This key enables Terraform to write to the bucket.

Head to **Profile picture** > **My profile** > **Customer secret keys** > **Generate secret key**

Give any display name you desire.

![Screenshot: Getting customer secret key from OCI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fq689fo3x27h2ww8vntg.png)

### 4. Add your AWS Customer Secret Key

i) Create or go to the file `~/.aws/credentials`
ii) Add the secret **Generated key** and **Access key** in the file under a profile name.

In this example, we use `default` as the profile name.

```txt
[default]
aws_access_key_id=68ce92f58a480b5cc17205467816a53b662f167a
aws_secret_access_key=1swn+e6GIyRz4tcEO42b95im7EBVO8rM5WM9apTs+fQ=
```

![Screenshot: aws credentials file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtimcsf2zwpb60o59w52.png)

### 5. Create your Terraform files

We'll create a folder with these files to create one VCN in a specified compartment:

```txt
📦terraform-test
 ┣ 📜main.tf
 ┣ 📜provider.tf
 ┗ 📜terraform.tf
```

The `terraform.tf` file will:
- tell Terraform to use the `oci` provider
- ensure the Terraform version is >= 1.7
- use the S3-compatible OCI bucket backend to store the state

**Important**
Make sure to update:
- the `bucket` attribute to reflect the name of your bucket
- the `endpoints` attribute to use your region and object storage namespace (found in Profile > Tenancy Details)
- the `profile` attribute. We use `"default"` as set in the previous step. Optionally for better configuration, use [Partial Configuration](https://developer.hashicorp.com/terraform/language/settings/backends/configuration#partial-configuration)

```hcl
# terraform.tf
terraform {
  required_providers {
    oci = {
      source  = "oracle/oci"
      version = ">= 6.0.0"
    }
  }
  required_version = ">=1.7"

  backend "s3" {
    bucket    = "bucket01"
    key       = "terraform.tfstate"
    region    = "us-ashburn-1"
    endpoints = { s3 = "https://idjqfqrpn5uq.compat.objectstorage.us-ashburn-1.oci.customer-oci.com" }

    profile                     = "default"
    skip_region_validation      = true
    skip_credentials_validation = true
    skip_requesting_account_id  = true
    skip_metadata_api_check     = true
    skip_s3_checksum            = true
    use_path_style              = true
  }
}
```

The `provider.tf` file sets the OCI profile you are using. `DEFAULT` is the default profile

```hcl
# provider.tf
provider "oci" {
  config_file_profile = "DEFAULT"
}
```

The `main.tf` file creates one simple VCN in the compartment you specify. Make sure to edit the `compartment_id`.

```hcl
# main.tf
resource "oci_core_vcn" "test_vcn" {
  #Required
  compartment_id = "ocid1.compartment.oc1..aaaaaaaaivk7ay7yourcompartmentocidpdx3rb37g55uguzga"

  #Optional
  cidr_blocks  = ["10.5.0.0/16"]
  display_name = "vcn-test-01"
}
```

### 6. Deploy

Let us initialize and apply the plan:

```sh
terraform init
terraform apply
```

If all goes well, we see a success message:

![Terraform successful application](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsfoweucy79oxhdv3w5s.png)

And of course, the created VCN:

![Deployed VCN](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jkxzs5rm4an3giwlluzi.png)

The Terraform tfstate file in the bucket:

![tfstate file in bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9hsei92xiz188zxvqwt.png)

## References
- [Oracle: Using Object Storage for State Files](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/terraformUsingObjectStore.htm)

## Safe harbor statement
_The information provided on this channel/article/story is solely intended for informational purposes and cannot be used as a part of any contractual agreement. The content does not guarantee the delivery of any material, code, or functionality, and should not be the sole basis for making purchasing decisions. The postings on this site are my own and do not necessarily reflect the views or work of Oracle or Mythics, LLC._

_This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0)._