OCI, Terraform & IaC: Creating Compartments for CIS Foundation Architecture

Share on:

In this third blog post series, we will be creating four main compartments

  • Security Compartment
  • Network Compartment
  • App/Dev Compartment
  • Database Compartment

The compartments above are based on the CIS Foundation Architecture, which is an architecture that starts with the compartment design for the tenancy along with groups and policies for the segregation of duties.

We will be using what we created in the past blog post, and we will just build on that. 

The first thing I did was now instead of using a set value for the compartment resource, I use the for_each Meta-Argument. Terraform will create one instance of the resource for each member of that map or set. With the exception of the var.compartment_ocid, I will be grabbing the values from var.compartments object map.

resource "oci_identity_compartment" "cmpts" {
 for_each = var.compartments
 name = each.value.name
 description = each.value.description
 enable_delete = each.value.enable_delete
 compartment_id = var.compartment_ocid
 provisioner "local-exec" {
 command = "sleep 60"
 }
}

The other change that I made, was in the variables.tf, which was to add a complex datatype variable object map called compartments.

A map is a data structure that allows you to store and manage a collection of key-value pairs. Maps are often used to define input variables, output values, and resource configurations. An object is a structural type that can hold several types of values. It is a set of named attributes, each with its own type.

I did it this way, as later on I will be setting the default values out of the object, but for now, this is just to show that we can create. I used the names and descriptions from the actual CIS Foundation Landing Zone, no need to reinvent the wheel.

variable "compartments" {
 type = map(object({
 name = string
 description = string
 enable_delete = string
 }))
 default = {
 key1 = {
 name = "network-cmp"
 description ="CIS Landing Zone compartment for all network related resources: VCNs, subnets, network gateways, security lists, NSGs, load balancers, VNICs, and others."
 enable_delete = "false"
 }
 key2 = {
 name = "security-cmp"
 description = "CIS Landing Zone compartment for all security related resources: vaults, topics, notifications, logging, scanning, and others."
 enable_delete = "false"
 }
 key3 = {
 name = "appdev-cmp"
 description= "CIS Landing Zone compartment for all security related resources: vaults, topics, notifications, logging, scanning, and others."
 enable_delete = "true"
 }
 key4 = {
 name = "database-cmp"
 description= "CIS Landing Zone compartment for all database related resources."
 enable_delete = "true"
 }
 }
}

Last, we will modify the outputs.tf so that we can show the result of each compartment resource we created. We use a for Expression, which its input can be a list, a set, a tuple, a map, or an object. It is important to note that

The type of brackets around the for expression decides what type of result it produces. The [ and ], produces a tuple. If you use { and } instead, the result is an object and you must provide two result expressions that are separated by the =>symbol, this expression produces an object whose attributes are the original elements.

output "compartments" {
 description = "The compartments, indexed by keys in var.compartments."
 value = {for k, v in var.compartments : k => oci_identity_compartment.cmpts[k]}
}

The result of the changes we have mentioned so creates 4 compartments and below is the output. 

[opc@oracle-rene-cloud-ace vol02_compartment_cis]$ terraform apply
data.oci_identity_availability_domains.ADs: Reading...
data.oci_identity_region_subscriptions.home_region_subscriptions: Reading...
data.oci_identity_availability_domains.ADs: Read complete after 0s [id=IdentityAvailabilityDomainsDataSource-2545584872]
data.oci_identity_region_subscriptions.home_region_subscriptions: Read complete after 0s [id=IdentityRegionSubscriptionsDataSource-2545584872]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
 + create
Terraform will perform the following actions:
# oci_identity_compartment.these["key1"] will be created
 + resource "oci_identity_compartment" "these" {
 + compartment_id = "ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 + defined_tags = (known after apply)
 + description = "CIS Landing Zone compartment for all network related resources: VCNs, subnets, network gateways, security lists, NSGs, load balancers, VNICs, and others."
 + enable_delete = false
 + freeform_tags = (known after apply)
 + id = (known after apply)
 + inactive_state = (known after apply)
 + is_accessible = (known after apply)
 + name = "network-cmp"
 + state = (known after apply)
 + time_created = (known after apply)
}
...
Do you want to perform these actions?
 Terraform will perform the actions described above.
 Only 'yes' will be accepted to approve.
 Enter a value: yes
oci_identity_compartment.these["key1"]: Creating...
...
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Outputs:
compartments = {
"key1" = {
"compartment_id" = "ocid1.compartment.oc1.. aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"defined_tags" = tomap({
"Oracle-Tags.CreatedBy" = "default/ra@ace.com"
"Oracle-Tags.CreatedOn" = "2024-02-15T19:33:47.798Z"
})
"description" = "CIS Landing Zone compartment for all network related resources: VCNs, subnets, network gateways, security lists, NSGs, load balancers, VNICs, and others."
"enable_delete" = false
"freeform_tags" = tomap({})
"id" = "ocid1.compartment.oc1.. aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"inactive_state" = tostring(null)
"is_accessible" = true
"name" = "network-cmp"
"state" = "ACTIVE"
"time_created" = "2024-02-15 19:33:47.863 +0000 UTC"
"timeouts" = null /* object */
}
"key2" = {
"compartment_id" = "ocid1.compartment.oc1.. aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"defined_tags" = tomap({
"Oracle-Tags.CreatedBy" = "default/ra@ace.com"
"Oracle-Tags.CreatedOn" = "2024-02-15T19:33:47.796Z"
})
"description" = "CIS Landing Zone compartment for all security related resources: vaults, topics, notifications, logging, scanning, and others."
"enable_delete" = false
"freeform_tags" = tomap({})
"id" = "ocid1.compartment.oc1.. aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"inactive_state" = tostring(null)
"is_accessible" = true
"name" = "security-cmp"
"state" = "ACTIVE"
"time_created" = "2024-02-15 19:33:48.258 +0000 UTC"
"timeouts" = null /* object */
}
"key3" = {
"compartment_id" = "ocid1.compartment.oc1.. aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"defined_tags" = tomap({
"Oracle-Tags.CreatedBy" = "default/ra@ace.com"
"Oracle-Tags.CreatedOn" = "2024-02-15T19:33:47.822Z"
})
"description" = "CIS Landing Zone compartment for all security related resources: vaults, topics, notifications, logging, scanning, and others."
"enable_delete" = true
"freeform_tags" = tomap({})
"id" = "ocid1.compartment.oc1.. aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"inactive_state" = tostring(null)
"is_accessible" = true
"name" = "appdev-cmp"
"state" = "ACTIVE"
"time_created" = "2024-02-15 19:33:49.203 +0000 UTC"
"timeouts" = null /* object */
}
"key4" = {
"compartment_id" = "ocid1.compartment.oc1.. aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"defined_tags" = tomap({
"Oracle-Tags.CreatedBy" = "default/ra@ace.com"
"Oracle-Tags.CreatedOn" = "2024-02-15T19:33:47.802Z"
})
"description" = "CIS Landing Zone compartment for all database related resources."
"enable_delete" = true
"freeform_tags" = tomap({})
"id" = "ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"inactive_state" = tostring(null)
"is_accessible" = true
"name" = "database-cmp"
"state" = "ACTIVE"
"time_created" = "2024-02-15 19:33:48.659 +0000 UTC"
"timeouts" = null /* object */
}
}

terraform1

 

Conclusion

In this blog post, we discussed the CIS Foundations Landing Zone, and how to use complex data types and Expressions. In the next series, we will delve into creating a VCN and start having more fun with Terraform.

Share on:

More from this Author

OCI, Terraform & IaC Creating a Compartment

OCI, Terraform & IaC: Creating a Compartment

In my previous post, I talked about the setup of Terraform and a primer on what it is. In this blog post, I will create a simple resource in OCI. One ... Read More

OCI, Terraform & IaC Coding Myself Out Of A Job

OCI, Terraform & IaC: Coding Myself Out Of A Job

I haven’t written a blog in a while, and I have made a couple of mistakes lately that could have easily been avoided if I had done my tasks as IaC ... Read More

Back to Top