Automate OCI Object Storage with Terraform

I’m Pratik Borkar, a Technical Architecture specializing in Oracle Cloud Infrastructure (OCI) and Kubernetes. I have extensive experience designing, automating, and optimizing cloud environments using Terraform, CI/CD pipelines, and container orchestration tools. I enjoy sharing hands-on guides and real-world implementations that help engineers simplify cloud operations, improve scalability, and adopt Infrastructure as Code best practices. When I’m not automating infrastructure, I explore new DevOps tools, contribute to open-source projects, and write about cloud-native technologies.
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)
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)
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)
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)
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)
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)
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)
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)
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)
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 |






