Home / OCI

OCIRunbookAdvanced

Transformation: from a flat 'everything in root' OCI tenancy to a structured landing zone

Restructure a tenancy where resources live in the root compartment or a couple of catch-all compartments. Design the target compartment tree, move resources safely, rebuild policies, and add tagging, quotas, budgets and Cloud Guard.

Deepak Bhardwaj3 min read

Applies toOCI compartments, IAM policies, tag namespaces, quotas, budgets, Cloud Guard, OCI Core Landing Zone (Terraform)

Why bother

A flat tenancy makes least privilege impossible (policies at root grant everything), costs can't be split, and one mistake can affect everything. A landing zone gives each team and environment its own boundary.

1. Target design

Start from the OCI Core Landing Zone (formerly CIS Landing Zone) Terraform as a reference:

root
└── <org>-top
    ├── network        (VCNs, DRG, firewall — network admins)
    ├── security       (Vault, Cloud Guard targets, logging — security admins)
    ├── shared-services(OKE platform, bastions — platform team)
    ├── app-a
    │   ├── prod
    │   └── nonprod
    └── app-b ...

Compartment depth is limited; keep it to a few levels.

2. Inventory current resources

oci search resource structured-search --query-text "query all resources where compartmentId = '$TENANCY'" \
  --query 'data.items[].{type:"resource-type", name:"display-name", id:identifier}' --output table

Map each resource to its target compartment and owner.

3. Create compartments, groups and policies first

oci iam compartment create --compartment-id $TOP --name app-a --description "Application A"
oci iam compartment create --compartment-id <app-a-ocid> --name prod --description "App A production"

Write policies for the target structure before moving anything, and keep the old broad policies in place until the move is complete — otherwise people lose access mid-migration.

4. Move resources

oci compute instance change-compartment --instance-id <ocid> --compartment-id <target-ocid>
oci network vcn change-compartment --vcn-id <ocid> --compartment-id <network-ocid>
oci os bucket update --bucket-name app-a-data --compartment-id <target-ocid>    # buckets move via update
oci db autonomous-database change-compartment --autonomous-database-id <ocid> --compartment-id <target-ocid>

Things to know:

  • Most resources move without downtime, but policies that reference the old compartment stop applying to moved resources. That's the main risk.
  • Dynamic group rules using instance.compartment.id stop matching moved instances — update them first.
  • Some resource types can't be moved or have conditions; check each service's documentation.
  • Associated resources (boot volumes, backups, VNICs) may stay behind — move them too for clean cost reports.

Warning

Move one application at a time and test its access paths (instance principals, user groups, automation) immediately after.

5. Governance

  • Tags: defined tag namespace with CostCenter, Owner, Environment; tag defaults per compartment.
  • Quotas: limit shapes and counts per compartment (zero compute-core quota ... for non-prod GPUs, for example).
  • Budgets per top-level compartment with alerts.
  • Cloud Guard targets on the top compartment with detector and responder recipes.
  • Security Zones for production compartments where the restrictions fit.

6. Remove root-level access

Once everything is moved, remove broad policies granted at the tenancy root (other than Administrators), and keep the root compartment empty of workloads.

Checklist

  • Target compartment tree agreed
  • Inventory mapped to targets and owners
  • New policies and dynamic groups in place before moves
  • Resources moved app by app; access tested
  • Tags, quotas, budgets, Cloud Guard enabled; root policies tightened