# Automate OCI Object Storage with Terraform

Object Storage in **Oracle Cloud Infrastructure (OCI)** provides durable and scalable storage for any type of data. Using **Terraform**, we can declaratively create and manage Object Storage Buckets, including lifecycle rules for intelligent data management — such as moving old files to **Infrequent Access**, **Archiving**, or **Deleting** them after a certain time.

In this article, we’ll create:

* **Single Bucket without lifecycle**
    
* **Single Bucket with lifecycle rules**
    
* **Multiple Buckets using a Terraform loop**
    

## Prerequisites

Before you begin, make sure you have:

* An OCI tenancy with Object Storage access
    
* Compartment OCID
    
* Terraform ≥ 1.5
    
* OCI provider ≥ 7.3.0
    
* Configured OCI CLI or API keys
    

### 1\. Single Bucket Without Lifecycle

(`main.tf`)

```plaintext
provider "oci" {
  tenancy_ocid     = var.tenancy_ocid
  user_ocid        = var.user_ocid
  fingerprint      = var.fingerprint
  private_key_path = var.private_key_path
  region           = var.region
}

resource "oci_objectstorage_bucket" "bucket" {
  compartment_id = var.compartment_ocid
  name           = var.bucket_name
  namespace      = var.namespace
  storage_tier   = var.storage_tier
}
```

Define Variables ([`variables.tf`](http://variables.tf))

```plaintext
variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

variable "compartment_ocid" {}
variable "bucket_name" {}
variable "namespace" {}
variable "storage_tier" {
  default = "Standard" # Options: Standard or Archive
}
```

Provide Variable Values (`terraform.tfvars`)

```plaintext
private_key_path = "C:/Users/Pratik N Borkar/.oci/xxxx.pem"
user_ocid        = "ocid1.user.oc1..aaaaabmza"
fingerprint      = "3a:d9f:71"
tenancy_ocid     = "ocid1.tenancy.ookmjm7dq"
region           = "ap-sydney-1"


compartment_ocid  = "ocid1.compartr2vdqa"
bucket_name      = "example-bucket"
namespace        = "XXXXXXX"
```

### 2\. Multiple Bucket Without Lifecycle

(`main.tf`)

```plaintext
provider "oci" {
  tenancy_ocid     = var.tenancy_ocid
  user_ocid        = var.user_ocid
  fingerprint      = var.fingerprint
  private_key_path = var.private_key_path
  region           = var.region
}

data "oci_objectstorage_namespace" "ns" {
  compartment_id = var.compartment_ocid
}

locals {
  bucket_names = [for i in range(1, var.bucket_count + 1) : format("AIS-%03d", i)]
}

resource "oci_objectstorage_bucket" "bucket" {
  for_each = toset(local.bucket_names)

  compartment_id     = var.compartment_ocid
  name               = each.value
  namespace          = data.oci_objectstorage_namespace.ns.namespace
  storage_tier       = var.storage_tier
}
```

Define Variables ([`variables.tf`](http://variables.tf))

```plaintext
variable "tenancy_ocid" {
  type = string
}

variable "user_ocid" {
  type = string
}

variable "fingerprint" {
  type = string
}

variable "private_key_path" {
  type = string
}

variable "region" {
  type = string
}

variable "compartment_ocid" {
  type = string
}

variable "storage_tier" {
  type    = string
  default = "Standard"
}

variable "bucket_count" {
  type    = number
  default = 10
}
```

Provide Variable Values (`terraform.tfvars`)

```plaintext
private_key_path = "C:/Users/Pratik N Borkar/.oci/xxxx.pem"
user_ocid        = "ocid1.user.oc1..aaaaabmza"
fingerprint      = "3a:d9f:71"
tenancy_ocid     = "ocid1.tenancy.ookmjm7dqxxxxxx"
region           = "ap-sydney-1"


compartment_ocid  = "ocid1.compartr2vdqaxxxxx"
storage_tier     = "Standard"
bucket_count     = 10
```

### 3\. Single Bucket With Lifecycle

(`main.tf`)

```plaintext
provider "oci" {
  tenancy_ocid        = var.tenancy_ocid
  user_ocid           = var.user_ocid
  fingerprint         = var.fingerprint
  private_key_path    = var.private_key_path
  region              = var.region
}

resource "oci_objectstorage_bucket" "this" {
  count          = var.object_storage_bucket_deploy ? 1 : 0
  compartment_id = var.object_storage_bucket_compartment_ocid
  name           = var.object_storage_bucket_name
  namespace      = var.object_storage_bucket_namespace

  access_type           = "NoPublicAccess"
  auto_tiering          = var.object_storage_bucket_storage_tier == "Standard" ? "Disabled" : null
  metadata              = var.object_storage_bucket_metadata
  freeform_tags         = var.object_storage_bucket_freeform_tags
  object_events_enabled = var.object_storage_bucket_object_events_enabled
  storage_tier          = var.object_storage_bucket_storage_tier
  versioning            = var.object_storage_bucket_versioning
}

resource "oci_objectstorage_object_lifecycle_policy" "this" {
  count     = length(var.object_storage_bucket_lifecycle_policy_rules) == 0 ? 0 : 1
  bucket    = oci_objectstorage_bucket.this[0].name
  namespace = oci_objectstorage_bucket.this[0].namespace

  dynamic "rules" {
    for_each = var.object_storage_bucket_lifecycle_policy_rules
    content {
      action      = rules.value.action
      is_enabled  = rules.value.is_enabled
      name        = rules.value.name
      time_amount = rules.value.time_amount
      time_unit   = rules.value.time_unit
      target      = rules.value.target

      dynamic "object_name_filter" {
        for_each = (
          length(rules.value.object_name_filter.inclusion_patterns) > 0 ||
          length(rules.value.object_name_filter.exclusion_patterns) > 0 ||
          length(rules.value.object_name_filter.inclusion_prefixes) > 0
        ) ? [1] : []

        content {
          exclusion_patterns = toset(rules.value.object_name_filter.exclusion_patterns)
          inclusion_patterns = toset(rules.value.object_name_filter.inclusion_patterns)
          inclusion_prefixes = toset(rules.value.object_name_filter.inclusion_prefixes)
        }
      }
    }
  }
}

resource "oci_objectstorage_object_lifecycle_policy" "multipart_uploads" {
  bucket    = oci_objectstorage_bucket.this[0].name
  namespace = oci_objectstorage_bucket.this[0].namespace

  rules {
    action      = "ABORT"
    is_enabled  = true
    name        = "Delete uncommitted or failed multipart uploads Rule"
    time_amount = "7"
    time_unit   = "DAYS"
    target      = "multipart-uploads"
  }
}
```

Define Variables ([`variables.tf`](http://variables.tf))

```plaintext
variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

variable "object_storage_bucket_compartment_ocid" {}
variable "object_storage_bucket_name" {}
variable "object_storage_bucket_namespace" {}

variable "object_storage_bucket_metadata" {
  type = map(string)
  default = {}
}

variable "object_storage_bucket_freeform_tags" {
  type = map(string)
  default = {}
}

variable "object_storage_bucket_object_events_enabled" {
  type    = bool
  default = false
}

variable "object_storage_bucket_versioning" {
  default = "Enabled"
}

variable "object_storage_bucket_storage_tier" {
  default = "Standard"
}

variable "object_storage_bucket_deploy" {
  type    = bool
  default = true
}

variable "object_storage_bucket_lifecycle_policy_rules" {
  type = list(object({
    action      = string
    is_enabled  = bool
    name        = string
    time_amount = number
    time_unit   = string
    target      = string
    object_name_filter = object({
      inclusion_patterns = list(string)
      exclusion_patterns = list(string)
      inclusion_prefixes = list(string)
    })
  }))
}
```

Provide Variable Values (`terraform.tfvars`)

```plaintext
private_key_path = "C:/Users/Pratik N Borkar/.oci/xxxx.pem"
user_ocid        = "ocid1.user.oc1..aaaaabmza"
fingerprint      = "3a:d9f:71"
tenancy_ocid     = "ocid1.tenancy.ookmjm7dqxxxxxx"
region           = "ap-sydney-1"


object_storage_bucket_compartment_ocid = "ocid1.compartmei3ier2vdqa"
object_storage_bucket_name             = "my-logs-bucket"
object_storage_bucket_namespace        = "XXXXXXX"

object_storage_bucket_metadata = {}
object_storage_bucket_freeform_tags = {
  Environment = "Dev"
}
object_storage_bucket_object_events_enabled = false
object_storage_bucket_versioning            = "Enabled"
object_storage_bucket_storage_tier          = "Standard"

object_storage_bucket_lifecycle_policy_rules = [
  {
    action      = "INFREQUENT_ACCESS"
    is_enabled  = true
    name        = "Move Infrequent Access Objects Rule"
    time_amount = 45
    time_unit   = "DAYS"
    target      = "objects"
    object_name_filter = {
      inclusion_patterns = []
      exclusion_patterns = []
      inclusion_prefixes = []
    }
  },
  {
    action      = "ARCHIVE"
    is_enabled  = true
    name        = "Archive Objects Rule"
    time_amount = 90
    time_unit   = "DAYS"
    target      = "objects"
    object_name_filter = {
      inclusion_patterns = []
      exclusion_patterns = []
      inclusion_prefixes = []
    }
  },
  {
    action      = "DELETE"
    is_enabled  = true
    name        = "Delete Objects Rule"
    time_amount = 120
    time_unit   = "DAYS"
    target      = "objects"
    object_name_filter = {
      inclusion_patterns = []
      exclusion_patterns = []
      inclusion_prefixes = []
    }
  },
  {
    action      = "INFREQUENT_ACCESS"
    is_enabled  = true
    name        = "Move Infrequent Access Previous Versions Rule"
    time_amount = 45
    time_unit   = "DAYS"
    target      = "previous-object-versions"
    object_name_filter = {
      inclusion_patterns = []
      exclusion_patterns = []
      inclusion_prefixes = []
    }
  },
  {
    action      = "ARCHIVE"
    is_enabled  = true
    name        = "Archive Previous Versions Rule"
    time_amount = 90
    time_unit   = "DAYS"
    target      = "previous-object-versions"
    object_name_filter = {
      inclusion_patterns = []
      exclusion_patterns = []
      inclusion_prefixes = []
    }
  },
  {
    action      = "DELETE"
    is_enabled  = true
    name        = "Delete Previous Versions Rule"
    time_amount = 240
    time_unit   = "DAYS"
    target      = "previous-object-versions"
    object_name_filter = {
      inclusion_patterns = []
      exclusion_patterns = []
      inclusion_prefixes = []
    }
  }
]
```

## Summary

| Folder | Description |
| --- | --- |
| `Single-Without-Lifecycle` | Creates a single basic Object Storage bucket |
| `Single-With-Lifecycle` | Adds 6 lifecycle rules for object and version management |
| `Multiple Bucket` | Creates multiple buckets dynamically using Terraform loops |
