> ## 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 OKE Clusters Should Have Network Policy Support Enabled

### More Info:

Clusters should be created with a network plugin that enforces NetworkPolicy. Without it, pod-to-pod traffic is unrestricted by default and a compromised pod can pivot freely across the cluster.

### Risk Level

High

### Address

Compliance, Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        In OCI OKE, Kubernetes Network Policy enforcement **must be enabled at cluster creation time**; it **cannot be switched on for an existing cluster**.\
        So remediation in the Console means:

        1. **Plan to replace the existing cluster**
           * Export current manifests:
             ```bash theme={null}
             kubectl get all,configmap,secret,ingress,job,cronjob -A -o yaml > backup.yaml
             ```
           * Take note of:
             * Node shapes, OCPUs, memory
             * VCN/subnets
             * Load balancers, DNS, ingress
             * Storage classes, PVCs, persistent volumes
           * Plan downtime or a blue/green migration if needed.

        2. **Create a new OKE cluster with Network Policy enabled (Console)**
           1. In the OCI Console, go to:\
              **Menu → Developer Services → Kubernetes Clusters (OKE)**
           2. Choose the compartment.
           3. Click **Create cluster**.
           4. Choose **Quick Create** or **Custom Create** (Custom gives more control).
           5. In the **Networking** or **Cluster configuration** section:
              * Ensure **Network type** is **VCN-native** (required for network policies).
              * Find the option **Network policy** or **Kubernetes Network Policy** and set it to **Enabled**.
           6. Select:
              * Kubernetes version (use a supported, current version).
              * VCN and subnets (reuse existing or create new).
              * Worker node shape, OCPUs, and node count.
           7. Complete the wizard and click **Create**.
           8. Wait until the cluster status is **Active** and worker nodes are **Ready**.

        3. **Point kubectl to the new cluster**
           1. In the OKE cluster details page, click **Access Cluster**.
           2. Follow the instructions to:
              * Install/ensure `kubectl` and `oci` CLI are set up.
              * Run the provided `oci ce cluster create-kubeconfig …` command to get kubeconfig for the new cluster.
           3. Verify:
              ```bash theme={null}
              kubectl get nodes
              ```

        4. **Recreate workloads on the new cluster**
           * Adjust the exported manifests if needed (storage classes, load balancer annotations, namespaces).
           * Apply them to the new cluster:
             ```bash theme={null}
             kubectl apply -f backup.yaml
             ```
           * Recreate any external integrations (e.g., OCI Load Balancers, DNS records, external secrets) if they are not managed via manifests.

        5. **Define and test NetworkPolicies**
           * Create minimal NetworkPolicies first (e.g., allow-all within namespace) to avoid breaking traffic, then tighten:
             ```yaml theme={null}
             apiVersion: networking.k8s.io/v1
             kind: NetworkPolicy
             metadata:
               name: allow-namespace
               namespace: my-namespace
             spec:
               podSelector: {}
               policyTypes:
               - Ingress
               - Egress
               ingress:
               - {}
               egress:
               - {}
             ```
           * Apply and test app connectivity:
             ```bash theme={null}
             kubectl apply -f networkpolicy.yaml
             ```

        6. **Cut over and decommission old cluster**
           * Update DNS / ingress / external endpoints to point to the new cluster’s load balancers.
           * Validate workloads and traffic flows.
           * When satisfied, in the Console:
             1. Go to **Kubernetes Clusters (OKE)**.
             2. Select the old cluster.
             3. Drain & cordon nodes if you want a clean shutdown:
                ```bash theme={null}
                kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
                ```
             4. Click **Delete** to remove the old cluster and node pools.

        This results in OKE clusters with **Network Policy support enabled**, satisfying the requirement.
      </Accordion>

      <Accordion title="Using CLI">
        Below are the concrete OCI CLI steps to enable Network Policy on an OKE cluster.

        ### 1. Prerequisites

        * OCI CLI installed and configured (`oci setup config`)
        * You have permission to manage the target OKE cluster
        * You know the **OCID** of the cluster you want to update

        ***

        ### 2. Verify current Network Policy setting

        ```bash theme={null}
        CLUSTER_OCID="<your_cluster_ocid>"

        oci ce cluster get \
          --cluster-id "$CLUSTER_OCID" \
          --query 'data."options"."kubernetes-network-config"."is-network-policy-enabled"' \
          --raw-output
        ```

        If this returns `false` or `null`, Network Policy is not enabled.

        ***

        ### 3. Get the full existing options payload

        You must preserve the existing cluster options and only flip the network policy flag.

        ```bash theme={null}
        oci ce cluster get \
          --cluster-id "$CLUSTER_OCID" \
          --query 'data.options' > options.json
        ```

        Open `options.json` and locate/ensure this structure exists:

        ```json theme={null}
        {
          "kubernetes-network-config": {
            "is-network-policy-enabled": true
          }
        }
        ```

        * If `"kubernetes-network-config"` exists, just set `"is-network-policy-enabled": true`.
        * If it doesn’t exist, add it under `options`:

        ```json theme={null}
        {
          "admission-controller-options": { ... },     // keep existing values
          "persistent-volume-config": { ... },        // keep existing values
          ...
          "kubernetes-network-config": {
            "is-network-policy-enabled": true
          }
        }
        ```

        Do not remove any existing keys in `options.json`.

        ***

        ### 4. Update the cluster to enable Network Policy

        ```bash theme={null}
        oci ce cluster update \
          --cluster-id "$CLUSTER_OCID" \
          --options file://options.json \
          --force \
          --wait-for-state SUCCEEDED
        ```

        This will enable network policy support (Calico) on the cluster.

        ***

        ### 5. Confirm Network Policy is enabled

        ```bash theme={null}
        oci ce cluster get \
          --cluster-id "$CLUSTER_OCID" \
          --query 'data."options"."kubernetes-network-config"."is-network-policy-enabled"' \
          --raw-output
        ```

        You should now see:

        ```text theme={null}
        true
        ```

        ***

        ### 6. (Kubernetes side) Start using NetworkPolicies

        Once enabled on the cluster, apply Kubernetes `NetworkPolicy` resources as usual:

        ```bash theme={null}
        kubectl apply -f my-network-policy.yaml
        ```

        This completes the remediation using OCI CLI.
      </Accordion>

      <Accordion title="Using Python">
        In OKE, Kubernetes Network Policy can only be enabled at **cluster creation time**. You cannot turn it on for an existing cluster; you must create a new OKE cluster with network policy support enabled, then migrate workloads.

        Below are the steps and an example using the OCI Python SDK.

        ***

        ### 1. Prerequisites

        * OCI Python SDK installed:

        ```bash theme={null}
        pip install oci
        ```

        * A configured OCI profile in `~/.oci/config` (or use instance principal / resource principal).
        * Existing:
          * Compartment OCID
          * VCN OCID
          * Subnet OCIDs for worker nodes and pods (for VCN-native pod networking)
          * KMS key etc. if you use encryption (optional)

        ***

        ### 2. Enable Network Policy on a New OKE Cluster (Python)

        Network policy is enabled by:

        * Using **VCN-native pod networking**
        * Setting the network policy flag in the cluster’s network configuration

        The structure may evolve with SDK versions, so adapt the exact class/field names based on your installed SDK (refer to `oci.container_engine.models`).

        ```python theme={null}
        import oci
        from oci.container_engine import ContainerEngineClient
        from oci.container_engine.models import (
            CreateClusterDetails,
            ClusterCreateOptions,
            KubernetesNetworkConfig,
            VcnIpNativePodNetworkOption
        )

        # Configuration & client
        config = oci.config.from_file("~/.oci/config", "DEFAULT")  # or use oci.config.from_file() defaults
        ce_client = ContainerEngineClient(config)

        # Required IDs
        compartment_id = "<COMPARTMENT_OCID>"
        vcn_id = "<VCN_OCID>"
        # Subnets – adapt to your design
        endpoint_subnet_id = "<CONTROL_PLANE_SUBNET_OCID>"
        node_subnet_id = "<NODE_SUBNET_OCID>"
        pod_subnet_id = "<POD_SUBNET_OCID>"  # for VCN-native pod networking

        # 1. Define Kubernetes network config with network policy enabled
        k8s_network_config = KubernetesNetworkConfig(
            # Example CIDRs; adapt as needed
            pods_cidr="10.244.0.0/16",
            services_cidr="10.96.0.0/16"
        )

        # 2. VCN-native pod networking and network policy
        pod_network_option = VcnIpNativePodNetworkOption(
            # This tells OKE to use VCN-native pod networking
            cni_type="VCN_IP_NATIVE",
            pod_subnet_ids=[pod_subnet_id],
            # Enable network policies – field name can vary by SDK version;
            # check your SDK docs / dir(oci.container_engine.models.VcnIpNativePodNetworkOption)
            is_network_policy_enabled=True
        )

        create_options = ClusterCreateOptions(
            service_lb_subnet_ids=[node_subnet_id],
            kubernetes_network_config=k8s_network_config,
            # Plug in pod networking options
            pod_network_option_details=pod_network_option
        )

        # 3. Create the cluster
        create_cluster_details = CreateClusterDetails(
            name="oke-with-network-policy",
            compartment_id=compartment_id,
            vcn_id=vcn_id,
            kubernetes_version="v1.28.2",  # use a supported version
            endpoint_config={
                "subnet_id": endpoint_subnet_id,
                "is_public_ip_enabled": False
            },
            options=create_options
        )

        response = ce_client.create_cluster(create_cluster_details)
        work_request_id = response.headers["opc-work-request-id"]
        print("Cluster creation work request:", work_request_id)
        ```

        **Important notes:**

        * Field names like `is_network_policy_enabled`, `cni_type`, `pod_network_option_details` can differ slightly depending on SDK release.
          * Run in Python REPL:
            ```python theme={null}
            import oci, inspect
            from oci.container_engine.models import VcnIpNativePodNetworkOption
            print(inspect.getsource(VcnIpNativePodNetworkOption))
            ```
            and confirm the exact property names for:
            * CNI type / pod networking
            * Network policy flag
        * If your SDK has a different model name for pod networking (e.g., `ClusterPodNetworkOptionDetails` or similar), use that instead and set its `is_network_policy_enabled` or equivalent.

        ***

        ### 3. Verify Network Policy Support in the New Cluster

        After the cluster is active and node pools are created:

        ```bash theme={null}
        # Configure kubeconfig for the new cluster
        oci ce cluster create-kubeconfig \
          --cluster-id <NEW_CLUSTER_OCID> \
          --file $HOME/.kube/config-new \
          --region <REGION> --token-version 2.0.0

        KUBECONFIG=$HOME/.kube/config-new kubectl get nodes
        ```

        Then create a simple `NetworkPolicy` and validate it is enforced:

        ```bash theme={null}
        KUBECONFIG=$HOME/.kube/config-new kubectl apply -f - <<'EOF'
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: deny-all
          namespace: default
        spec:
          podSelector: {}
          policyTypes:
          - Ingress
          - Egress
        EOF
        ```

        If the policy works (pods lose connectivity as expected), network policy is enabled.

        ***

        ### 4. Migrate Workloads

        * Deploy your workloads to the new cluster.
        * Migrate services, ingresses, secrets, and PVCs as needed.
        * Decommission the old cluster once migration is complete.

        If you share the output of `inspect.getsource` for `VcnIpNativePodNetworkOption` / `ClusterCreateOptions` from your environment, I can give you an exact, version-accurate Python snippet.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "oci_containerengine_cluster" "OKE_CLUSTER" {
          # Substitute these with your actual values
          name           = "OKE_CLUSTER_NAME"
          compartment_id = "COMPARTMENT_OCID"
          vcn_id         = "VCN_OCID"
          kubernetes_version = "K8S_VERSION"

          # This must use a CNI that supports NetworkPolicy, i.e. OCI_VCN_NATIVE
          # Changing cni_type on an existing cluster forces replacement of the cluster.
          cluster_pod_network_options {
            cni_type = "OCI_VCN_NATIVE"
          }

          # ...keep your existing endpoint_config, options, etc. here...
        }
        ```

        Enabling network policy enforcement on OKE is done by creating the cluster with a CNI that supports it (`OCI_VCN_NATIVE`); Terraform cannot switch an existing cluster’s CNI in place, so this change will destroy and recreate the `oci_containerengine_cluster` resource (cluster outage and node/pod replacement).

        After updating the Terraform, `terraform plan` should show the `oci_containerengine_cluster` resource being replaced with the `cluster_pod_network_options[0].cni_type` changing from its current value (for example `"FLANNEL_OVERLAY"`) to `"OCI_VCN_NATIVE"`.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
