Kubernetes
Terraform
YAML
DevOps
Infrastructure as Code

Can you define Kubernetes Services / Pods using YAML in Terraform?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Yes, you can manage Kubernetes objects from Terraform using YAML, but the answer needs a caveat. It works best when you understand the tradeoff between reusing existing manifests and letting Terraform manage those objects as first-class infrastructure resources.

Two Main Approaches

There are two common ways to do this:

  1. write native Terraform Kubernetes resources such as kubernetes_service or kubernetes_deployment
  2. load a YAML manifest and apply it through a manifest-capable resource

The first approach is more Terraform-native. The second is useful when you already have Kubernetes YAML you want to keep.

Applying YAML Through Terraform

A common pattern is to read YAML from disk, decode it, and pass it to a Kubernetes manifest resource.

hcl
1terraform {
2  required_providers {
3    kubernetes = {
4      source  = "hashicorp/kubernetes"
5      version = "~> 2.30"
6    }
7  }
8}
9
10provider "kubernetes" {
11  config_path = "~/.kube/config"
12}
13
14resource "kubernetes_manifest" "nginx_pod" {
15  manifest = yamldecode(file("${path.module}/pod.yaml"))
16}

Example pod.yaml:

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: nginx-demo
5spec:
6  containers:
7    - name: nginx
8      image: nginx:1.25
9      ports:
10        - containerPort: 80

You can do the same for a service:

hcl
resource "kubernetes_manifest" "nginx_service" {
  manifest = yamldecode(file("${path.module}/service.yaml"))
}

That means the short answer to the question is yes: Terraform can consume Kubernetes YAML and apply it.

When Native Terraform Resources Are Better

If you are building everything from scratch in Terraform, native resources are often easier to review and refactor:

hcl
1resource "kubernetes_service" "web" {
2  metadata {
3    name = "web"
4  }
5
6  spec {
7    selector = {
8      app = "web"
9    }
10
11    port {
12      port        = 80
13      target_port = 8080
14    }
15  }
16}

This gives you stronger schema validation and clearer plans. Terraform can show field-by-field changes more naturally than when it manages a large decoded YAML object.

Tradeoffs You Should Consider

Using YAML inside Terraform is attractive because it avoids rewriting existing manifests. Still, it adds some friction:

  • diffs may be noisier
  • provider support varies by resource type and API version
  • server-populated fields can create drift
  • complex YAML templating can become harder to maintain than either pure YAML or pure Terraform

For teams already invested in Kubernetes manifests, Terraform can be a coordination layer. For teams managing cloud infrastructure and cluster resources together, native Terraform resources may produce cleaner plans and state.

A Good Hybrid Pattern

A practical compromise is to let Terraform manage cluster infrastructure, namespaces, and foundational services, while an in-cluster tool such as Helm, Argo CD, or plain kubectl handles application manifests.

That split keeps Terraform focused on durable infrastructure and avoids turning every application rollout into a Terraform state change.

Still, if you have a small platform or only a few manifests, using YAML through kubernetes_manifest is completely reasonable.

Common Pitfalls

  • Assuming Terraform will behave exactly like kubectl apply. The lifecycle model is different.
  • Storing raw YAML in Terraform without considering drift from fields the API server adds automatically.
  • Choosing Pods for long-lived workloads when a Deployment would be more resilient.
  • Mixing too much string templating into YAML files, which makes plans hard to read and debug.
  • Using YAML in Terraform for everything, even when native resources or Helm would be simpler.

Summary

  • Yes, Terraform can define Kubernetes Services and Pods from YAML.
  • 'kubernetes_manifest with yamldecode(file(...)) is a common pattern.'
  • Native Terraform Kubernetes resources provide better schema-aware plans in many cases.
  • YAML reuse is useful when manifests already exist and you want Terraform to orchestrate them.
  • Pick the approach based on drift, maintainability, and how much of Kubernetes you want Terraform to own.

Course illustration
Course illustration

All Rights Reserved.