Managing Kubernetes Resources with Pulumi: A Hands-on Guide

Introduction

Infrastructure as Code (IaC) is revolutionizing how we manage cloud-native applications, and Pulumi brings a unique advantage by allowing developers to define and deploy Kubernetes resources using familiar programming languages. Unlike YAML-heavy configurations, Pulumi enables us to programmatically create, manage, and version Kubernetes resources with Python, TypeScript, Go, and more.

In this guide, we’ll walk through deploying an Nginx application on Minikube using Pulumi with Python, ensuring a scalable, maintainable, and declarative approach to Kubernetes management.

Step 1: Installing Pulumi & Setting Up the Environment

Before we start, install Pulumi and its dependencies:

Install Pulumi

curl -fsSL https://get.pulumi.com | sh

Install Kubernetes CLI (kubectl) & Minikube

sudo apt install -y kubectl
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

Start Minikube

minikube start

Step 2: Initialize a Pulumi Project

pulumi new kubernetes-python

During setup:

  • Project name: pulumi-k8s
  • Stack name: dev
  • Dependencies: Pulumi will install pulumi_kubernetes

Verify installation:

pulumi version
kubectl version --client

Step 3: Defining Kubernetes Resources in Python

Now, modify __main__.py to define an Nginx deployment and service using Pulumi:

Corrected __main__.py

import pulumi
import pulumi_kubernetes as k8s

# Define labels for the application
app_labels = {"app": "nginx"}

# Define the Deployment
deployment = k8s.apps.v1.Deployment(
    "nginx-deployment",
    metadata=k8s.meta.v1.ObjectMetaArgs(
        namespace="default",
        name="nginx-deployment",
        labels=app_labels,
    ),
    spec=k8s.apps.v1.DeploymentSpecArgs(
        replicas=2,
        selector=k8s.meta.v1.LabelSelectorArgs(
            match_labels=app_labels,
        ),
        template=k8s.core.v1.PodTemplateSpecArgs(
            metadata=k8s.meta.v1.ObjectMetaArgs(
                labels=app_labels,
            ),
            spec=k8s.core.v1.PodSpecArgs(
                containers=[
                    k8s.core.v1.ContainerArgs(
                        name="nginx",
                        image="nginx:latest",
                        ports=[k8s.core.v1.ContainerPortArgs(container_port=80)],
                    )
                ]
            ),
        ),
    ),
)

# Define a ClusterIP Service
service = k8s.core.v1.Service(
    "nginx-service",
    metadata=k8s.meta.v1.ObjectMetaArgs(
        namespace="default",
        name="nginx-service",
    ),
    spec=k8s.core.v1.ServiceSpecArgs(
        selector=app_labels,
        ports=[k8s.core.v1.ServicePortArgs(port=80, target_port=80)],
        type="ClusterIP",  # Ensures it is NOT a LoadBalancer
    ),
)

# Export the service name
pulumi.export("service_name", service.metadata.name)
Click Here to Copy Python

Step 4: Deploying the Kubernetes Resources

After defining the resources, apply them using:

pulumi up

This will:
✅ Create an Nginx Deployment with 2 replicas
✅ Create a ClusterIP Service
✅ Deploy everything to Minikube

To verify the deployment:

kubectl get all -n default

Step 5: Accessing the Application

Since we’re using ClusterIP, we need to port-forward to access the application:

kubectl port-forward svc/nginx-service 8080:80 -n default

Now, open http://localhost:8080 in your browser, and you should see the Nginx welcome page! 

Why Choose Pulumi Over YAML?

  • Programmatic Infrastructure – Use Python, TypeScript, Go, etc., instead of complex YAML.
  • Reusability & Automation – Write functions, use loops, and manage dependencies efficiently.
  • Version Control & CI/CD – Easily integrate with Git, Terraform, and GitHub Actions.

Conclusion

With Pulumi, managing Kubernetes infrastructure becomes developer-friendly and scalable. Unlike traditional YAML-based approaches, Pulumi enables real programming constructs, making it easier to define, update, and manage Kubernetes workloads efficiently.

What do you think? Have you used Pulumi before for Kubernetes? Let’s discuss in the comments!👇

Leave a comment