> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OCI Governance Should Have Custom Compartments Created

### More Info:

Enforce the CIS landing zone architecture by requiring custom compartments. Resources should never be deployed directly into the root tenancy compartment to ensure strict administrative boundary isolation

### Risk Level

High

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* Cloudanix Best Practice
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To meet the “OCI Governance Should Have Custom Compartments Created” requirement using the OCI Console, you just need to create at least one non-root compartment (and typically more, aligned to your governance model). Here are the steps:

        ***

        ### 1. Sign in and choose the right tenancy/root compartment

        1. Sign in to the **OCI Console**.
        2. In the top-left, open the **hamburger menu**.
        3. Make sure you are in the correct **tenancy** and **region** (top-right of the console).
        4. In the **Compartment selector** (usually above the main pane), confirm you are viewing the **root compartment** (the tenancy name).

        ***

        ### 2. Navigate to Compartments

        1. Open the **hamburger menu**.
        2. Go to **Identity & Security** → **Compartments**.

        ***

        ### 3. Create a custom compartment

        1. On the **Compartments** page, click **Create Compartment**.
        2. Fill in:
           * **Name**: e.g., `prod`, `nonprod`, `network`, `logging`, etc.
           * **Description**: brief description of its purpose.
           * **Parent Compartment**:
             * Usually the **root compartment** for top-level governance compartments, or
             * Another compartment if building a hierarchy (e.g., `prod > prod-network`).
        3. (Optional but recommended) Add **Tags** if your governance model uses tag-based organization.
        4. Click **Create Compartment**.

        Repeat this for all compartments required by your governance standards (e.g., separate compartments for environments, business units, shared services, security/logging).

        ***

        ### 4. Attach or verify IAM policies for the new compartments

        To make the compartments actually usable under your governance model:

        1. Go to **Identity & Security** → **Policies**.
        2. Create or edit policies in the **root compartment** (or appropriate parent) that:
           * Grant groups access to **use/manage resources** in the new compartments.
           * Example policy (pseudo):
             ```text theme={null}
             Allow group Network-Admins to manage virtual-network-family in compartment prod-network
             Allow group App-Admins to manage all-resources in compartment prod
             ```
        3. Click **Create** or **Save changes**.

        ***

        ### 5. (If applicable) Move resources into the new compartments

        If you already have resources in the root compartment that should be governed:

        1. Navigate to the resource type (e.g., **Compute → Instances**, **Networking → VCNs**).
        2. For each resource, open its **Details** page.
        3. Click **Move resource** (or equivalent).
        4. Choose the appropriate **target compartment** and confirm.

        ***

        ### 6. Confirm remediation for Governance Monitoring

        1. Go back to your **Governance/Compliance/Cloud Guard** or **Monitoring** page where the finding was raised.
        2. Wait for the next evaluation cycle (or trigger a rescan if supported).
        3. Verify the finding “OCI Governance Should Have Custom Compartments Created” is **Resolved/Closed**.

        If you tell me your intended structure (environments, BUs, or projects), I can give a minimal recommended compartment tree and example policies tailored to that.
      </Accordion>

      <Accordion title="Using CLI">
        To satisfy **“OCI Governance Should Have Custom Compartments Created”** using the **OCI CLI**, you need to create at least one compartment under the root tenancy (not use only the root compartment).

        Below are the minimal step-by-step CLI instructions.

        ***

        ### 1. Ensure OCI CLI is configured

        If not already done:

        ```bash theme={null}
        oci setup config
        ```

        Follow prompts (tenancy OCID, user OCID, region, etc.).

        ***

        ### 2. Get your tenancy OCID (root compartment ID)

        If you don’t know your tenancy OCID, you can fetch it via:

        ```bash theme={null}
        oci iam compartment list --compartment-id-in-subtree false --access-level ACCESSIBLE
        ```

        Look for the compartment with `"name": "tenancy"` (or your tenancy name). Its `"id"` is the root compartment OCID.\
        You can also see it in the web console under: Profile icon → Tenancy OCID.

        Assume:

        ```bash theme={null}
        TENANCY_OCID="<your-tenancy-ocid>"
        ```

        ***

        ### 3. Create a custom compartment

        Use `oci iam compartment create` with the root compartment as the parent:

        ```bash theme={null}
        COMPARTMENT_NAME="custom-governance-comp"
        COMPARTMENT_DESC="Custom compartment for governance / resource segregation"

        oci iam compartment create \
          --compartment-id "$TENANCY_OCID" \
          --name "$COMPARTMENT_NAME" \
          --description "$COMPARTMENT_DESC"
        ```

        This returns JSON including the new compartment `"id"` and `"lifecycle-state": "CREATING"` or `"ACTIVE"`.

        ***

        ### 4. (Optional) Verify the compartment exists and is ACTIVE

        ```bash theme={null}
        oci iam compartment list \
          --compartment-id "$TENANCY_OCID" \
          --access-level ANY \
          --compartment-id-in-subtree false \
          --all \
          | jq '.data[] | {name, id, "lifecycle-state"}'
        ```

        Ensure your new compartment is listed and lifecycle-state is `ACTIVE`.

        ***

        ### 5. Wait for governance monitoring to re-evaluate

        OCI governance/posture tools (Cloud Guard / Security Zones / Governance Monitoring) usually re-check on a schedule. After the compartment is created and ACTIVE, the “Custom Compartments Created” requirement should pass on the next evaluation cycle.

        If you need more than one custom compartment (e.g., by environment), repeat step 3 with different names:

        ```bash theme={null}
        for env in dev test prod; do
          oci iam compartment create \
            --compartment-id "$TENANCY_OCID" \
            --name "comp-$env" \
            --description "Compartment for $env environment"
        done
        ```

        That’s all that’s required from the CLI side to remediate this specific control.
      </Accordion>

      <Accordion title="Using Python">
        Below is a concise, stepwise way to remediate the finding “OCI Governance Should Have Custom Compartments Created” using Python and the OCI SDK.

        ## 1. Prerequisites

        1. Install OCI Python SDK:
           ```bash theme={null}
           pip install oci
           ```

        2. Configure your OCI CLI profile (used by the SDK):
           ```bash theme={null}
           oci setup config
           ```
           This creates `~/.oci/config`. Note your:
           * `tenancy`
           * `user`
           * `fingerprint`
           * `key_file`
           * `region`
           * `profile` name (e.g., `DEFAULT`)

        3. Have appropriate IAM permissions on the tenancy root to create compartments:
           * `inspect compartments in tenancy`
           * `use tenancy`
           * `manage compartments in tenancy` (or equivalent policy)

        ***

        ## 2. Decide the Compartment Structure

        Define the custom compartments you want for governance/monitoring. Common patterns:

        * `security-governance-root`
          * `security-monitoring`
          * `compliance-logs`
          * `audit-archive`

        You can represent this as a list of desired compartments with parent-child relations.

        ***

        ## 3. Python Script to Ensure Custom Compartments Exist

        This script will:

        1. Connect using your OCI config profile.
        2. Look up the tenancy OCID.
        3. Check if the target compartments already exist.
        4. Create any that are missing under the correct parent.

        ```python theme={null}
        import oci
        from oci.identity import IdentityClient

        # ------------ CONFIGURATION ------------
        OCI_CONFIG_FILE = "~/.oci/config"
        OCI_PROFILE = "DEFAULT"  # change if needed

        # Desired compartment structure
        # Each entry is: { name, description, parent_key }
        # parent_key 'TENANCY_ROOT' means direct child of tenancy
        DESIRED_COMPARTMENTS = [
            {"key": "SEC_GOV_ROOT", "name": "security-governance-root",
             "description": "Root compartment for security & governance resources",
             "parent_key": "TENANCY_ROOT"},

            {"key": "SEC_MONITORING", "name": "security-monitoring",
             "description": "Compartment for governance and security monitoring services",
             "parent_key": "SEC_GOV_ROOT"},

            {"key": "COMPLIANCE_LOGS", "name": "compliance-logs",
             "description": "Compartment for compliance-related logs and artifacts",
             "parent_key": "SEC_GOV_ROOT"},
        ]


        def get_compartment_by_name(identity_client, parent_ocid, name):
            """
            Return the first ACTIVE compartment with a given name under a parent,
            or None if not found.
            """
            comps = oci.pagination.list_call_get_all_results(
                identity_client.list_compartments,
                parent_ocid,
                compartment_id_in_subtree=False,
                access_level="ANY"
            ).data

            for c in comps:
                if c.name == name and c.lifecycle_state == "ACTIVE":
                    return c
            return None


        def main():
            # Load config
            config = oci.config.from_file(OCI_CONFIG_FILE, OCI_PROFILE)

            # Create Identity client
            identity_client = IdentityClient(config)

            tenancy_id = config["tenancy"]

            # Cache map: key -> compartment_ocid
            compartment_ids = {}

            # The tenancy root is a special "parent"
            compartment_ids["TENANCY_ROOT"] = tenancy_id

            # Process in multiple passes until all parents are resolved
            # This allows children to reference parents defined earlier in the list
            remaining = DESIRED_COMPARTMENTS.copy()

            # Continue until all compartments created or no more progress
            while remaining:
                progress_made = False
                still_remaining = []

                for item in remaining:
                    parent_key = item["parent_key"]

                    if parent_key not in compartment_ids:
                        # Parent not yet created/resolved
                        still_remaining.append(item)
                        continue

                    parent_ocid = compartment_ids[parent_key]
                    name = item["name"]
                    description = item["description"]

                    # Check if compartment already exists
                    existing = get_compartment_by_name(identity_client, parent_ocid, name)

                    if existing:
                        print(f"[INFO] Compartment '{name}' already exists: {existing.id}")
                        compartment_ids[item["key"]] = existing.id
                    else:
                        print(f"[INFO] Creating compartment '{name}' under parent {parent_ocid}...")
                        create_details = oci.identity.models.CreateCompartmentDetails(
                            compartment_id=parent_ocid,
                            name=name,
                            description=description
                        )
                        response = identity_client.create_compartment(create_details)
                        new_comp = response.data
                        print(f"[INFO] Created compartment '{name}' with OCID: {new_comp.id}")
                        compartment_ids[item["key"]] = new_comp.id

                    progress_made = True

                if not progress_made:
                    raise RuntimeError(
                        "Could not resolve parents for some compartments; "
                        "check 'parent_key' values and ordering."
                    )

                remaining = still_remaining

            print("\n[SUMMARY] Final compartment mapping:")
            for k, v in compartment_ids.items():
                print(f"  {k}: {v}")


        if __name__ == "__main__":
            main()
        ```

        ***

        ## 4. Connect These Compartments to Governance Monitoring

        After creating the custom compartments:

        1. Update your Governance/Monitoring policies so that the monitoring service (or your monitoring user/group/dynamic group) can:

           * Read from monitored compartments.
           * Write logs/metrics into the new governance compartments (e.g., `security-monitoring`, `compliance-logs`).

           Example policies (adjust OCIDs/names):

           ```text theme={null}
           allow dynamic-group governance-monitoring-dg to read all-resources in compartment security-governance-root
           allow dynamic-group governance-monitoring-dg to manage log-groups in compartment security-monitoring
           allow dynamic-group governance-monitoring-dg to manage log-content in compartment compliance-logs
           ```

        2. In your governance/monitoring code or Terraform/Resource Manager stacks, reference the new compartment OCIDs (printed by the script) when:
           * Creating log groups.
           * Creating alarms.
           * Creating notifications channels.

        ***

        ## 5. Automate Execution

        Integrate the script into your CI/CD or governance bootstrap process so it:

        * Runs on initial tenancy onboarding.
        * Optionally verifies the compartments remain present and active.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Create a custom compartment instead of using the root tenancy
        resource "oci_identity_compartment" "APP_COMPARTMENT" {
          # Replace with your tenancy OCID (root)
          compartment_id = "ocid1.tenancy.oc1..ROOT_TENANCY_OCID"

          name        = "APP_COMPARTMENT_NAME"   # e.g. "prod-apps"
          description = "Application resources compartment for PROD"
          enable_delete = false
        }

        # Example: place governed resources into the custom compartment,
        # not directly into the root tenancy.
        resource "oci_core_vcn" "APP_VCN" {
          # Previously this was set to the tenancy OCID (root); that is what
          # triggered the governance finding. It must point to a custom compartment.
          compartment_id = oci_identity_compartment.APP_COMPARTMENT.id

          cidr_block   = "10.0.0.0/16"
          display_name = "APP_VCN"
          dns_label    = "appvcn"
        }

        # Repeat the same pattern for every OCI resource that is currently
        # using the root tenancy OCID as compartment_id:
        # - Change compartment_id from "ocid1.tenancy.oc1..ROOT_TENANCY_OCID"
        #   to oci_identity_compartment.APP_COMPARTMENT.id (or other custom compartment).
        #
        # Example for an OCI Logging log group used by Governance Monitoring:
        resource "oci_logging_log_group" "GOV_MONITORING_LOG_GROUP" {
          compartment_id = oci_identity_compartment.APP_COMPARTMENT.id

          display_name = "gov-monitoring-logs"
          description  = "Log group for governance / CIS monitoring"
        }

        # NOTE: Moving existing resources between compartments is effectively a move
        # operation in OCI. When you change compartment_id in Terraform for resources
        # that already exist, OCI may treat it as a move or a replace depending on
        # the resource type; confirm impact before applying in production.
        ```

        A `terraform plan` that remediates the finding should show:

        * A new `oci_identity_compartment.APP_COMPARTMENT` to be created.
        * For each governed resource currently in the root tenancy, an update where
          `compartment_id` changes from the root tenancy OCID to the new compartment’s OCID (or, for some resources, a destroy-and-recreate reflecting the move).
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
