Terraforming Power with CSV Files

It is often easier to collect resource information for Terraform through spreadsheets. In this example, I’ll build a number of object storage buckets in Oracle Cloud Infrastructure from a CSV file.

The CSV file has three columns: name (bucket name), access_type, and compartment.:

buckets.csv

name , access_type , compartment
cmr_test1 , NoPublicAccess , Sandbox
cmr_test2 , ObjectRead , TestCompartment
cmr_test3 , NoPublicAccess , Sandbox

The secret sauce in reading the CSV file is in the Terraform csvdecode function. This function reads a CSV file, and parses the columns into list of maps, from which we can create buckets. I use the function to first set a local variable contents and then loop through it to create the buckets.

contents = [
  {
    "access_type" = "NoPublicAccess"
    "compartment" = "Sandbox"
    "name" = "cmr_test1"
  },
  {
    "access_type" = "ObjectRead"
    "compartment" = "TestCopartment"
    "name" = "cmr_test2"
  },
  {
    "access_type" = "NoPublicAccess"
    "compartment" = "Sandbox"
    "name" = "cmr_test3"
  },
]

I parse the CSV file contents into a local variable, which is then referennced in the for_each loop in the bucket resource. The data component for oci_identity_compartments is filtered with the distinct set of compartments in the CSV file. It is also referenced in the for_each loop, where I look up the compartment ID by name.

provider "oci" {}

variable filename {
  default = "buckets.csv"
}

variable tenancy_ocid {}

data "oci_objectstorage_namespace" "ns" {}

data "oci_identity_compartments" "test_compartments" {
  #Required
  compartment_id = var.tenancy_ocid

  #Optional
  compartment_id_in_subtree = true

  # Only fetch the compartments from the CSV file
  filter {
    name   = "name"
    values = distinct(local.contents.*.compartment)
  }
}

locals {
  contents = csvdecode(file(var.filename))
  comps    = data.oci_identity_compartments.test_compartments.compartments
}

resource "oci_objectstorage_bucket" "bucket" {
  for_each = { for item in local.contents : item.name => item }

  compartment_id = [for comp in local.comps : 
                        comp.id 
                        if comp.name == each.value.compartment
                    ][0]

  namespace      = data.oci_objectstorage_namespace.ns.namespace
  name           = each.value.name
  access_type    = each.value.access_type
}

output "buckets" { value = oci_objectstorage_bucket.bucket }

Please give this a try and leave a comment. I’d like to hear from you to find out what you did with it.