LAB 46 ‐ Create compartment using modular approach - DevWithNehaCloud/Oracle-Cloud-Infrastructure-wiki GitHub Wiki
This documentation covers the design and deployment of a multi-tier compartment structure for the Swiggy Dev Environment. The architecture consists of a main parent environment compartment containing isolated sub-compartments for core infrastructure pillars: Network and Storage.
To make the code simple and easy to manage, we used a Direct Root Module Parameter approach. The module defines the required variables in variables.tf, and the actual values for each environment are provided directly in the root module file (for example, dev/compartment.tf).
The project is hosted under the identity_service repository. Environment layers (dev, test, uat, prod) execute independently by pulling generic source logic from the centralized compartment_module.
identity_service/
│
├── compartment_module/ # Core Shared Module
│ ├── main.tf # Resource definitions
│ ├── variables.tf # Module inputs
│ └── outputs.tf # Module exports (Critical for dynamic mapping)
│
└── dev/ # Dev Environment Execution Folder
├── compartment.tf # Core topology (1 Parent + 2 Children)
├── provider.tf # OCI Authentication Config
└── privkey.pem # API Private Key (Git-ignored)
Declares the strict explicit schema required to construct any safe compartment instance on OCI.
variable "compartment_parent_id" {
type = string
description = "OCI Parent Compartment OCID"
}
variable "compartment_name" {
type = string
description = "Name of the compartment"
}
variable "compartment_description" {
type = string
description = "Description for the compartment"
}
Utilizes an explicit resource label (my_compartment). The safety lock enable_delete is configured to true to ensure agile lifecycle teardowns inside non-production tracks.
resource "oci_identity_compartment" "my_compartment" {
compartment_id = var.compartment_parent_id
name = var.compartment_name
description = var.compartment_description
enable_delete = true
}
Captures the runtime metadata from the created OCI resource. This exported ID allows cascading dependencies dynamically into child blocks.
output "compartment_id" {
value = oci_identity_compartment.my_compartment.id
description = "The OCID of the created compartment"
}
Handles regional scope boundaries and points directly to the workspace-enclosed API key asset.
provider "oci" {
auth = "APIKey"
tenancy_ocid = "ocid1.tenancy.oc1..aaaaaaaacxrxza63ajbfdhvukzuxpv4y3oksxh256migpqx6lazpbbejuuga"
user_ocid = "ocid1.user.oc1..aaaaaaaa5m4rn7uj5exypqxsz54tmkqctcuzd7o4ehy2f35flcdzznncw77a"
private_key_path = "/home/ngsoftlook/identity_service/dev/privkey.pem"
fingerprint = "4c:bb:0e:8b:6e:b1:df:51:59:bf:c6:e3:60:2c:d6:29"
region = "us-ashburn-1"
}
Builds the dynamic chain structure. Notice how the Storage and Network blocks implicitly rely on the outputs of the Parent block, eliminating hardcoded IDs or loose external variables files.
# =======================================================
# # 1. PARENT COMPARTMENT: swiggy-dev-compartment
# =======================================================
module "swiggy_dev_parent" {
source = "/home/ngsoftlook/identity_service/compartment_module"
compartment_parent_id = "ocid1.tenancy.oc1..aaaaaaaacxrxza63ajbfdhvukzuxpv4y3oksxh256migpqx6lazpbbejuuga" # OCID of the tenancy
compartment_name = "swiggy-dev-compartment"
compartment_description = "Main Parent Compartment for Dev Environment"
}
# =======================================================
# # 2. CHILD COMPARTMENT: swiggy-dev-compute-and-storage-compartment
# =======================================================
module "swiggy_dev_compute_and_storage" {
source = "/home/ngsoftlook/identity_service/compartment_module"
# It will dynamically retrieve the ID from the parent module's output.
compartment_parent_id = module.swiggy_dev_parent.compartment_id
compartment_name = "swiggy-dev-compute-and-storage-compartment"
compartment_description = "Child Compartment for swiggy Dev Storage Resources"
}
# =======================================================
# # 3. CHILD COMPARTMENT: swiggy-dev-network-compartment
# =======================================================
module "swiggy_dev_network" {
source = "../compartment_module"
# It will also dynamically retrieve the ID from the parent module's output.
compartment_parent_id = module.swiggy_dev_parent.compartment_id
compartment_name = "swiggy-dev-network-compartment"
compartment_description = "Child Compartment for swiggy Dev Network Resources"
}
When defining the source attribute inside a Terraform module block, Terraform provides two different ways to specify the location of the module folder. In our project setup, both methods work perfectly without throwing any errors, but they handle file system navigation differently.
identity_service/
├── compartment_module/ <-- (Target Module)
└── dev/
└── compartment.tf <-- (Current Working Directory)
-
Example:
source = "/home/ngsoftlook/identity_service/compartment_module" -
What it is: This is the complete and fixed path starting right from the system's root directory (
/). - How it works: No matter which folder you are currently inside when running the code, this path remains unchanged because it explicitly spells out the entire journey from the very top of the computer's file system.
-
Example:
source = "../compartment_module" - What it is: This path is calculated relative to your Current Working Directory (the folder where your executing code resides).
-
How it works:
- While working inside
compartment.tfunder thedevfolder, Terraform treats.(single dot) as the currentdevdirectory. - When we use
..(double dot), Terraform steps out of thedevfolder (moves one level up) and enters the parentidentity_servicefolder. - Following it up with
/compartment_moduleroutes Terraform straight into the intended module folder.
- While working inside
Terraform successfully accepted both pathing styles because, ultimately, both directions lead to the exact same target compartment_module folder on the machine.
In real-world Cloud Architecture projects, always prefer using Relative Paths (../).
-
Why? If you push this repository to GitHub or clone the
identity_servicedirectory onto another machine or a CI/CD runner, the absolute system path (like/home/ngsoftlook) will change, breaking the configuration. Relative paths keep the code dynamic and portable because the shared structural relationship between the folders remains identical across all systems.
Run initialization inside the target environment folder to pull specific providers and properly wire regional relative modules path links.
cd identity_service/dev/
terraform init
Add your terminal screenshot here showing successful init:

Run a speculative plan validation to confirm that the sequential execution paths evaluate correctly, showing exactly 3 resources ready to be deployed.
terraform plan
Once the speculative dry-run plan is verified, execute the active deployment to build the multi-tier compartment structure inside your live OCI tenancy.
terraform apply
Now, verifying in console
When the development environment resources are no longer needed (or during environment resets), you can securely decommission the entire hierarchical compartment tree using the destroy command.
terraform destroy
Key Architectural Benefits Realized
Implicit Dependency Graphing: Passing module.swiggy_dev_parent.compartment_id instructs Terraform's scheduler to block child creations until the core environment zone settles securely.
To avoid hardcoding and manual copy-pasting of OCI OCIDs, this architecture relies heavily on Terraform's implicit dependency mapping via outputs. Here is the exact lifecycle breakdown of how IDs flow across runtime:
Inside our core module (main.tf), we defined our resource with a local identifier: oci_identity_compartment.my_compartment.
- The
.idsuffix is a fixed, built-in system attribute of the Oracle OCI provider. - The moment Oracle Cloud successfully provisions the parent compartment, it generates a unique runtime OCID. Terraform captures this value inside
oci_identity_compartment.my_compartment.id.
Because variables inside a module are encapsulated (isolated), the root execution workspace cannot see this internal .id natively. We expose it by creating an output block:
output "compartment_id" {
value = oci_identity_compartment.my_compartment.id
}
compartment_id acts as a custom public label/envelope holding that dynamic runtime value.
- Consuming the Variable in Child Modules (compartment.tf) When provisioning the sequential downstream tracks (swiggy_dev_storage and swiggy_dev_network), we reference that specific exposed envelope:
compartment_parent_id = module.swiggy_dev_parent.compartment_id
Here is the exact data flow chain during execution:
-
🚀 OCI Cloud Infrastructure Engine └── Generates the real live OCID string as a built-in attribute:
.id -
📦 Shared Module Wrapper (outputs.tf) └── Packs that raw ID into a clean public envelope named:
compartment_id -
🛠️ Dev Workspace Caller (compartment.tf) └── Child modules catch that envelope instantly using:
module.swiggy_dev_parent.compartment_id
Without this automated chain, deploying a multi-tier infrastructure in a single execution track is impossible because child layers cannot look into the cloud or see other modules without a public output envelope.
When creating a compartment hierarchy in Terraform, there are two possible approaches.
In our implementation, we created the parent compartment (Swiggy Dev) and both child compartments (Swiggy Dev Container Storage and Swiggy Dev Network) in a single Terraform execution.
Since the child compartments require the OCID of the parent compartment, Terraform first creates the parent compartment and then uses an output value to expose the runtime-generated OCID. This OCID is then consumed by the child compartment resources during the same deployment.
Parent and child compartments are created in a single
terraform apply.No manual copying of OCIDs is required.
The entire deployment remains automated and reusable.
Ideal for Infrastructure as Code (IaC) workflows.
Parent Compartment
│
▼
Runtime OCID Generated
│
▼
output.tf Exposes OCID
│
▼
Child Compartments Consume OCID
It is also possible to create the same compartment hierarchy without using output.tf.
In this approach:
Create only the parent compartment first.
Run
terraform apply.After the parent compartment is created, copy its OCID from the OCI Console.
Paste the OCID into the Terraform configuration as the parent compartment ID.
Run
terraform applyagain to create the child compartments.
Simpler configuration for small environments.
No output values are required.
Useful when the parent compartment already exists.
Create Parent Compartment
│
▼
Copy Parent OCID From OCI Console
│
▼
Paste OCID Into Terraform Configuration
│
▼
Create Child Compartments
In our project, the parent compartment (Swiggy Dev) and its child compartments (Swiggy Dev Container Storage and Swiggy Dev Network) were created together in a single Terraform execution.
Because the parent compartment OCID did not exist until runtime, Terraform needed a way to capture that newly generated OCID and pass it to the child compartments automatically. This is why output.tf was used.
Without output.tf, we would have had to:
Create the parent compartment first.
Retrieve its OCID manually from the OCI Console.
Update the Terraform configuration with that OCID.
Run Terraform again to create the child compartments.
Key Takeaway
output.tfis not mandatory for creating parent-child compartment relationships. It becomes useful when the parent and child compartments must be created together in a single automated Terraform execution and the parent OCID is only available at runtime.
| Method | Parent & Child Created Together | Manual OCID Copy Required | Automation Level |
|---|---|---|---|
| Using output.tf | ✅ Yes | ❌ No | High |
| Without output.tf | ❌ No (Two-Step Process) | ✅ Yes | Low |
- Creates parent and child compartments in a single Terraform execution.
- Automatically passes the runtime-generated parent OCID to child compartments.
- Eliminates manual intervention.
- Recommended for fully automated Infrastructure as Code (IaC) deployments.
- Requires creating the parent compartment first.
- The parent OCID must be copied manually from the OCI Console.
- Child compartments are created in a separate Terraform execution.
- Suitable for small or one-time deployments where automation is not a priority.