Skip to main content
  1. Docs
  2. Infrastructure as Code
  3. Comparisons
  4. Kubernetes YAML Manifests

Pulumi vs. Kubernetes YAML Manifests

    Pulumi and Kubernetes YAML manifests are both declarative ways to define the desired state of infrastructure. Pulumi lets you define infrastructure in general-purpose languages (Python, TypeScript, JavaScript, Go, C#, Java, or YAML) across any cloud or SaaS provider; Kubernetes YAML manifests are the native configuration format of the Kubernetes API and describe Kubernetes objects only.

    This page covers what each tool is, a feature-by-feature comparison, the most important differences in detail, and the available paths for adopting Pulumi alongside or instead of Kubernetes YAML manifests.

    What is Pulumi?

    Pulumi is an infrastructure as code platform for provisioning and managing resources across any cloud or SaaS platform. Pulumi programs are written in general-purpose programming languages — Python, TypeScript, JavaScript, Go, .NET, and Java — as well as YAML. The Pulumi Registry covers all major clouds, including first-party native providers that are generated from upstream API schemas for same-day coverage of new platform features. The Pulumi CLI and SDKs are open source under the Apache 2.0 license. Pulumi Cloud is the commercial product that adds managed state, secrets, RBAC, audit logs, policy management, and other features for running Pulumi at organizational scale.

    For users coming from Kubernetes YAML, Pulumi maintains a first-party Kubernetes provider generated from the Kubernetes OpenAPI spec, so every Kubernetes API object is available with the same fidelity as a hand-written manifest. The same Pulumi program can also provision the cluster itself and any non-Kubernetes cloud resources it depends on.

    What are Kubernetes YAML manifests?

    Kubernetes YAML manifests are the native declarative configuration format of the Kubernetes API. Each manifest is a YAML (or JSON) document describing the desired state of a Kubernetes API object — a Deployment, Service, ConfigMap, Namespace, and so on. Manifests are applied to a cluster with kubectl apply or by a GitOps controller such as Argo CD or Flux, and the Kubernetes control plane reconciles the cluster toward the state they describe.

    Kubernetes is an open-source project governed by the Cloud Native Computing Foundation and licensed under Apache 2.0. Manifests target any conformant Kubernetes cluster — Amazon EKS, Azure AKS, Google GKE, or self-managed — but can only describe Kubernetes resources; cloud resources outside the cluster require separate tooling or an in-cluster operator. There is no separate state file: the live cluster, backed by etcd, is the source of truth, and kubectl apply tracks managed fields directly on each object. Manifests have no commercial product of their own — they are simply the input format of the Kubernetes API — and Kustomize is the common native tool for layering and patching them.

    Detailed comparison

    FeaturePulumiKubernetes YAML Manifests
    Language supportPython, TypeScript, JavaScript, Go, C#, Java, and YAML — general-purpose languages with familiar syntax for loops, conditionals, and abstractionsYAML or JSON documents describing Kubernetes API objects; no loops, conditionals, or variables. Kustomize adds bases and overlays but remains declarative YAML
    Cloud and service supportPulumi Registry of packages, including bridged, native, parameterized, and dynamic providers; first-party native providers for Kubernetes and Azure Native generated from upstream API schemas; any Terraform provider can be adapted into a Pulumi providerKubernetes API objects only, on any conformant cluster (EKS, AKS, GKE, or self-managed); non-Kubernetes cloud resources require separate tooling or an in-cluster operator such as AWS Controllers for Kubernetes or Crossplane
    Transpiled to another format?No — programs run directly in their host languageNo — manifests are sent directly to the Kubernetes API server
    State managementManaged by Pulumi Cloud by default; self-managed backends include Amazon S3, Azure Blob Storage, Google Cloud Storage, local files, and othersNo separate state file; the live cluster (etcd) is the source of truth, and kubectl apply records managed fields via server-side apply
    Secrets managementEncrypted in transit and at rest in the state file by default, with per-stack encryption keys; pluggable KMS providers (AWS KMS, Azure Key Vault, Google Cloud KMS, HashiCorp Vault)Kubernetes Secret objects are base64-encoded, not encrypted, in the manifest; encryption at rest in etcd is configured separately at the cluster level
    Execution modelLocal CLI, programmatic via Automation API, or remote runs in Pulumi DeploymentsLocal kubectl CLI against a cluster, or a GitOps controller (Argo CD, Flux) running inside the cluster; no centralized service ships with Kubernetes itself
    Rollback on failed operationFailed updates leave the stack in a partially updated state; subsequent pulumi up runs reconcile toward the desired state, and you can roll forward by reverting program codekubectl apply has no transactional rollback; workload controllers support kubectl rollout undo for revision history, and re-applying a previous manifest reconciles back
    Programmatic API for tools and platformsAutomation API — a programmatic SDK for building custom CLIs, internal developer platforms, and services that drive up, preview, and destroy without shelling out to the Pulumi CLIThe Kubernetes API and client libraries operate on individual objects, but there is no orchestration SDK for driving a full apply/preview/destroy lifecycle
    Modularity and reuseComponent Resources authored in any supported language; Pulumi Packages let a component written in one language be consumed from any Pulumi language; language-native package managers (npm, PyPI, NuGet, Maven, Go modules); and the Pulumi Registry for publicly available packagesReuse is by copying manifests or by Kustomize bases and overlays; there is no package manager or typed interface for sharing manifest libraries
    Import existing resourcespulumi import and the import resource option, both of which generate code in your languageThe cluster is itself the source of truth; kubectl get -o yaml exports an object’s current state as a manifest
    Policy as codePulumi Policies — open source, with rules written in Python, TypeScript, or Open Policy Agent Rego; Pulumi Cloud commercial plans add centralized policy management plus Pulumi-maintained policy packs for compliance frameworks like CIS and PCI DSSNo built-in policy-as-code; admission controllers such as OPA Gatekeeper or Kyverno enforce policy inside the cluster as a separate component
    Open sourceYes — Apache License 2.0Yes — Kubernetes and kubectl are Apache License 2.0
    Commercial optionPulumi CloudNone — manifests are the input format of the Kubernetes API; managed Kubernetes is sold by cloud providers, but the manifest format itself has no commercial tier

    Key differences

    Language support and the authoring experience

    Kubernetes YAML manifests are static documents: each one describes a single object’s desired state with no loops, conditionals, or variables. Generating many similar objects, or parameterizing them per environment, means copying YAML or layering Kustomize overlays on top of base manifests. Pulumi programs are written in general-purpose languages, so authors get loops, conditionals, functions, classes, package management, IDE features (autocomplete, type checking, refactoring, go-to-definition), and the testing frameworks that already exist in those ecosystems — while still producing the same Kubernetes API objects. Pulumi also supports YAML for users who prefer a markup format.

    Cloud and service coverage

    Kubernetes YAML manifests describe Kubernetes API objects and nothing else. Provisioning the cluster they run on, or the cloud resources an application depends on — a managed database, an object store, a DNS record — requires separate tooling, or an in-cluster operator such as AWS Controllers for Kubernetes or Crossplane that maps cloud resources onto Kubernetes objects. Pulumi pulls from the Pulumi Registry, which covers all major clouds and SaaS platforms, and includes a first-party Kubernetes provider generated from the Kubernetes OpenAPI spec. A single Pulumi program can provision an EKS, AKS, or GKE cluster, deploy workloads to it, and create the cloud resources those workloads use — without switching tools.

    Execution and rollbacks

    Manifests are applied with the local kubectl CLI or by an in-cluster GitOps controller such as Argo CD or Flux; Kubernetes itself ships no centralized orchestration service. Pulumi runs through the local CLI, programmatically through the Automation API, or remotely through Pulumi Deployments. Neither approach performs a transactional rollback on failure: kubectl apply leaves successfully applied objects in place, and workload controllers offer kubectl rollout undo against revision history, while Pulumi leaves the stack partially updated and reconciles on the next run. The difference is in surface area — Pulumi adds a preview step, an embeddable SDK, and a first-party managed runner on top of the same declarative reconciliation model.

    Secrets handling

    A Kubernetes Secret object stores values base64-encoded, not encrypted, so a secret committed in a manifest is effectively plaintext; protecting it requires encryption at rest in etcd configured at the cluster level, plus an external tool such as Sealed Secrets or an external secrets operator to keep cleartext out of source control. Pulumi treats secrets as a first-class primitive: values marked as secrets are encrypted in transit and at rest in the state file, anything derived from a secret is also encrypted, and each stack has its own encryption key. The default encryption provider can be replaced with AWS KMS, Azure Key Vault, Google Cloud KMS, or HashiCorp Vault.

    Policy as code

    Kubernetes manifests have no built-in policy-as-code mechanism; enforcement is done inside the cluster by an admission controller such as OPA Gatekeeper or Kyverno, installed and managed as a separate component. Pulumi Policies is open source and free, with rules written in Python, TypeScript, or Open Policy Agent Rego that run during pulumi preview and pulumi up — before resources are created. Pulumi Cloud adds centralized management, policy groups, and enforcement across stacks, and commercial plans include Pulumi-maintained policy packs for common compliance frameworks (CIS, PCI DSS, HITRUST, NIST).

    Modularity and reuse

    Sharing Kubernetes YAML means copying manifests or building Kustomize bases and overlays — there is no package manager and no typed interface for distributing reusable manifest libraries. Pulumi’s Component Resources are runtime objects with explicit parent/child relationships, so a component and the resources inside it form a coherent unit in plan output, deletion, and state. Components can be authored in one language and consumed from any other supported language by publishing them as a Pulumi Package, and they distribute through language-native package managers (npm, PyPI, NuGet, Maven, Go modules) and the Pulumi Registry.

    Automation API

    The Automation API lets a host application drive Pulumi without shelling out to the CLI. Practical uses include embedding stack creation in a SaaS product, building an internal developer platform that provisions a namespace or a whole cluster per team or per branch, generating ephemeral preview environments from CI, and orchestrating multi-step deployments where each step runs as part of a larger workflow. The Kubernetes API and its client libraries can create and update individual objects, but there is no equivalent SDK for driving a full apply, preview, and destroy lifecycle.

    When to choose Pulumi vs. Kubernetes YAML manifests

    Choose Pulumi when you:

    1. Want to write Kubernetes configuration in a general-purpose language with the loops, conditionals, testing frameworks, package managers, and IDE tooling that already exist in that ecosystem.
    2. Need to provision the cluster and the surrounding cloud resources (databases, object stores, DNS) in the same program that deploys your workloads.
    3. Want a preview step, first-class encrypted secrets, and policy-as-code that runs before resources are created.
    4. Need an embeddable SDK (Automation API) to drive deployments from a host application — internal developer platforms, SaaS products, or per-branch preview environments.

    Choose Kubernetes YAML manifests when you:

    1. Want the native, dependency-free input format of the Kubernetes API, with no additional tooling to install or learn.
    2. Have an existing GitOps workflow (Argo CD, Flux) and tooling built around raw manifests that you don’t want to change.
    3. Are managing Kubernetes resources only, and provisioning the cluster and cloud resources is handled by a separate team or tool.

    The two can also coexist — see Adoption below.

    Adoption: coexistence, conversion, and import

    There are several common paths for adopting Pulumi alongside or in place of Kubernetes YAML manifests, and they can be combined:

    1. Consume existing YAML in a Pulumi program. The Kubernetes provider can deploy your existing manifests unchanged through its ConfigFile and ConfigGroup resources, so you can adopt Pulumi for orchestration without rewriting any YAML. See Migrating from Kubernetes YAML or Helm Charts.
    2. Coexist via rendered YAML. Pulumi can render a program to Kubernetes YAML instead of applying it directly, so you can author configuration in a general-purpose language while still deploying with kubectl or an existing GitOps pipeline.
    3. Convert manifests with pulumi convert. pulumi convert --from kubernetes translates existing manifests into a Pulumi program in the language of your choice.
    4. Import existing resources. pulumi import and the import resource option bring already-running cluster resources under Pulumi management and generate the corresponding code in your chosen language.

    For a complete walkthrough including coexistence patterns, conversion, and rendering, see Migrating from Kubernetes YAML or Helm Charts to Pulumi.

    Frequently asked questions

    Can Pulumi deploy my existing Kubernetes YAML unchanged?

    Yes. The Kubernetes provider includes ConfigFile and ConfigGroup resources that read existing manifests and register every object in them with Pulumi, so you can adopt Pulumi for orchestration without rewriting any YAML. See the migration guide.

    How do I migrate from Kubernetes YAML to Pulumi?

    You have options that can be combined: deploy your existing manifests as-is through ConfigFile/ConfigGroup, convert them to program code with pulumi convert --from kubernetes, or bring already-running resources under management with pulumi import. The migration guide walks through each path.

    Does Pulumi replace kubectl?

    For provisioning, yes — pulumi up applies your desired state to the cluster the same way kubectl apply does, with an added preview step. kubectl remains useful for ad-hoc inspection and debugging (kubectl get, kubectl logs, kubectl describe), and Pulumi can also render to YAML if you want to keep applying with kubectl or a GitOps controller.

    Can Pulumi manage non-Kubernetes cloud resources too?

    Yes. Unlike raw manifests, which describe Kubernetes objects only, a single Pulumi program can provision the cluster itself and any cloud resources your workloads depend on — managed databases, object stores, DNS records — using the Pulumi Registry of providers for AWS, Azure, Google Cloud, and SaaS platforms.

    Is Pulumi free like Kubernetes manifests?

    The Pulumi CLI and SDKs are open source under Apache 2.0 and free to use, as are Kubernetes and kubectl. Pulumi Cloud has a free Individual tier and paid plans that add managed state, RBAC, audit logs, policy management, and other features for running Pulumi at organizational scale.

    Can Pulumi and raw YAML or GitOps coexist during migration?

    Yes — and this is a common adoption pattern. Pulumi can deploy existing manifests through ConfigFile/ConfigGroup and can render programs back to YAML for an existing kubectl or GitOps pipeline, so teams typically keep some resources on raw manifests while moving others to Pulumi, converting or importing incrementally as the project allows.

    Next steps