Back
OCI Kubernetes Reserved IP Terraform course FoggyKitchen

OCI Container Engine for Kubernetes (OKE) with Reserved Public IP for LoadBalancer Service using Terraform

OCI Kubernetes Reserved IP Terraform is a powerful combination when deploying workloads in OCI Container Engine for Kubernetes (OKE). When running workloads in OCI Container Engine for Kubernetes (OKE), one of the most common production requirements is to expose your application through a stable public IP address.

By default, the OCI LoadBalancer service assigns ephemeral IPs that can change if you recreate the service. While this works fine for development or test environments, in production it can cause problems with DNS records, firewall rules, and client integrations.

To solve this, OCI allows us to provision a Reserved Public IP and attach it directly to a Kubernetes LoadBalancer service. In this article, I will show you how to automate this process with Terraform and Kubernetes manifests — using the same example I cover in Lesson 6 of my OCI Kubernetes Engine with Terraform/OpenTofu (2025 Edition) course.

Why use OCI Kubernetes Reserved IP Terraform?

Using OCI Kubernetes Reserved IP Terraform ensures stable networking for LoadBalancer services in OKE. Instead of relying on ephemeral IPs that may change when a service is recreated, you can reserve a static public IP and bind it directly to your Kubernetes LoadBalancer. This makes DNS management easier, simplifies firewall rules, and provides the consistency that production-grade environments require. In other words, it transforms a basic Kubernetes deployment into a reliable, enterprise-ready solution:

  • ✅ Stable DNS records

  • ✅ Consistent firewall rules

  • ✅ Production-ready reliability

Step 1: Provision OKE Cluster with Terraform

The first step is to spin up the OKE cluster itself. For this, I rely on my public Terraform module, which abstracts away most of the complexity.

From oke_UPDATED.tf:


module "fk_oke" {
  source  = "github.com/mlinxfeld/terraform-oci-fk-oke"
  version = ">=1.0.0"

  compartment_id = var.compartment_id
  cluster_name   = "foggykitchen-oke"
  region         = var.region
  # other required inputs...
}

This automatically provisions the OKE control plane, node pools, and all required dependencies.

Step 2: Reserve a Public IP in the Network Layer

Before deploying a service, we need to ensure we have a Reserved Public IP available. This is defined in network_NEW.tf:


resource "oci_core_public_ip" "oke_reserved_ip" {
  compartment_id = var.compartment_id
  display_name   = "oke-reserved-ip"
  lifetime       = "RESERVED"
}

This IP will remain allocated even if the LoadBalancer is deleted and recreated. Perfect for production workloads where consistency matters.

Step 3: Define Kubernetes Service with Reserved IP

Next, we prepare the Kubernetes Service manifest. This is where we tell OCI to use the reserved IP rather than creating a new one dynamically.

From service.template.yaml:


apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
  annotations:
    service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
    service.beta.kubernetes.io/oci-load-balancer-subnet1: "${subnet_ocid}"
    service.beta.kubernetes.io/oci-load-balancer-reserved-ip: "${oci_core_public_ip.oke_reserved_ip.id}"
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

The key annotation is:

service.beta.kubernetes.io/oci-load-balancer-reserved-ip

It makes the LoadBalancer service bind to the exact reserved IP we provisioned earlier.

Step 4: Automate Deployment with Terraform

Finally, we deploy the manifest using Terraform. This ensures everything stays consistent across environments.

From deploy_UPDATED.tf:

resource "local_file" "service_deployment" {
  content = templatefile("${path.module}/manifest/service.template.yaml" , {
      lb_shape                      = var.lb_shape
      flex_lb_min_shape             = var.flex_lb_min_shape 
      flex_lb_max_shape             = var.flex_lb_max_shape  
      lb_listener_port              = var.lb_listener_port
      lb_nsg                        = var.lb_nsg
      lb_nsg_id                     = var.lb_nsg ? oci_core_network_security_group.FoggyKitchenOKELBSecurityGroup[0].id : ""
      use_reserved_public_ip_for_lb = var.use_reserved_public_ip_for_lb
      reserved_public_ip_for_lb     = var.use_reserved_public_ip_for_lb ? oci_core_public_ip.FoggyKitchenReservedPublicIP[0].ip_address : ""
  })
  filename = "${path.module}/service.yaml"
}

resource "null_resource" "deploy_nginx" {
  depends_on = [
  module.fk-oke.cluster,
  module.fk-oke.node_pool, 
  local_file.service_deployment]

  provisioner "local-exec" {
    command = "oci ce cluster create-kubeconfig --region ${var.region} --cluster-id ${module.fk-oke.cluster.id}"
  }

  provisioner "local-exec" {
    command = "kubectl apply -f ${local_file.service_deployment.filename}"
  }

  ## Other steps
}

Terraform dynamically injects the reserved IP OCID into the manifest before applying it to the OKE cluster.

Why this matters

Using a Reserved Public IP with OKE has several clear benefits:

  • Stable DNS records – no need to update DNS every time the service is recreated.

  • Simplified firewall rules – consistent IP address makes it easier to configure external access.

  • Production-ready setup – predictable and reliable, ideal for enterprise-grade deployments.

This is a small change in configuration but makes a huge difference in real-world Kubernetes environments.

Full code & next steps

You can find the complete example in the GitHub repo:
📂 Lesson 6 – OKE with Reserved Public IP

And if you want to learn how to:

  • Provision OKE clusters with Terraform

  • Automate deployments with OpenTofu

  • Configure advanced networking scenarios

👉 then check out my course:
OCI Kubernetes Engine with Terraform/OpenTofu (2025 Edition)

OCI Kubernetes course

👉 Master OCI Kubernetes with Terraform/OpenTofu

Learn how to deploy OKE clusters the right way — from networking and node pools to production-grade scenarios like Reserved Public IPs for LoadBalancers, automated manifests, and advanced multicloud setups.

🔒 Lifetime • ⏱️ Self-paced • 🧪 Real labs

Check also other courses:​

Leave A Reply

🚀 Master OCI Kubernetes Terraform the Smart Way

Build and automate your OKE clusters with my step-by-step Terraform module. Join hundreds of engineers already simplifying Kubernetes on OCI with FoggyKitchen.

OCI Kubernetes course