Terraform Kubernetes Provider: Gestiona Recursos K8s con IaC 2025

terraform kubernetes provider - Gestión de recursos K8s con infraestructura como código

Terraform Kubernetes Provider es la solución definitiva para gestionar recursos de Kubernetes mediante infraestructura como código. En esta guía completa, aprenderás a desplegar aplicaciones en clusters K8s de manera declarativa, automatizar la gestión de deployments y services, y mantener un control versionado de tu infraestructura cloud-native. Combinar Terraform con Kubernetes te permite unificar tu workflow de IaC y aprovechar el ciclo de vida completo de recursos.

¿Qué es Terraform Kubernetes Provider?

El Terraform Kubernetes Provider es un plugin oficial de HashiCorp que permite gestionar recursos de Kubernetes directamente desde código Terraform. En lugar de escribir manifiestos YAML y aplicarlos con kubectl, puedes definir deployments, services, configmaps, secrets y cualquier otro recurso K8s usando la sintaxis HCL de Terraform.

Este provider se conecta a tu cluster de Kubernetes (ya sea EKS, AKS, GKE o cualquier distribución on-premise) y ejecuta operaciones CRUD sobre los recursos que defines en tus archivos .tf. HashiCorp mantiene activamente este provider, con más de 100 recursos soportados y actualizaciones regulares que siguen la evolución de la API de Kubernetes.

Características principales del provider

  • Gestión declarativa completa: Define el estado deseado de tus recursos K8s en código Terraform
  • Ciclo de vida automatizado: Terraform maneja creación, actualización y eliminación de recursos automáticamente
  • Comprensión de dependencias: El grafo de dependencias de Terraform previene errores al crear recursos en el orden correcto
  • Soporte multi-cluster: Gestiona múltiples clusters desde una misma configuración usando alias de providers
  • Integración con ecosistema Terraform: Combina recursos K8s con infraestructura cloud (VPCs, load balancers, bases de datos)
  • Custom Resource Definitions: Soporte completo para CRDs mediante el recurso kubernetes_manifest

Casos de uso principales

El provider es ideal para equipos DevOps que necesitan:

  • Desplegar aplicaciones microservicios con múltiples deployments y services coordinados
  • Gestionar configuración de aplicaciones mediante ConfigMaps y Secrets versionados
  • Automatizar infraestructura K8s completa desde la creación del cluster hasta la aplicación final
  • Mantener consistencia multi-entorno (dev, staging, production) con código reutilizable
  • Integrar Kubernetes con servicios cloud como RDS, S3, Azure Storage en un único workflow

Terraform Kubernetes Provider vs Alternativas

Al gestionar aplicaciones en Kubernetes, existen varias herramientas disponibles. Comparemos el Terraform Kubernetes Provider con las alternativas más populares:

Terraform Kubernetes Provider vs kubectl + YAML

Usar kubectl con manifiestos YAML es el enfoque tradicional. Sin embargo, Terraform ofrece ventajas significativas:

  • State management: Terraform mantiene un state file que rastrea qué recursos existen, evitando configuración drift
  • Plan antes de apply: Puedes previsualizar cambios antes de aplicarlos con terraform plan
  • Infraestructura unificada: Gestiona tanto el cluster K8s como las aplicaciones que corren en él
  • Módulos reutilizables: Encapsula configuraciones complejas en módulos Terraform compartibles

Terraform Kubernetes Provider vs Helm

Helm es el package manager de Kubernetes, enfocado en desplegar aplicaciones empaquetadas. La diferencia clave:

  • Nivel de abstracción: Helm trabaja con charts (paquetes de aplicaciones), mientras que el provider gestiona recursos individuales
  • Propósito: Helm es para deployment de aplicaciones, Terraform es para provisioning de infraestructura
  • Rollbacks: Helm tiene rollback nativo (helm rollback), Terraform requiere gestión de state
  • Complementarios: Puedes usar Terraform Helm Provider para desplegar charts desde Terraform

Muchos equipos usan ambos: Terraform para infraestructura base y Helm para aplicaciones complejas. Para gestionar configuraciones de Docker Compose en entornos locales, consulta nuestros tutoriales de Docker Compose.

Requisitos Previos

Antes de comenzar con el Terraform Kubernetes Provider, necesitas tener configurado lo siguiente:

Software necesario

  • Terraform: Versión 1.0 o superior (recomendado 1.5+)
  • kubectl: Cliente de línea de comandos de Kubernetes
  • Cluster Kubernetes: Puede ser minikube, kind, k3s, EKS, AKS, GKE o cualquier distribución
  • Kubeconfig válido: Archivo ~/.kube/config con credenciales del cluster

Verificar acceso al cluster

# Verificar que kubectl puede conectarse
kubectl cluster-info

# Listar nodos del cluster
kubectl get nodes

# Verificar contexto actual
kubectl config current-context

Si no tienes un cluster disponible, puedes crear uno localmente con minikube o kind para practicar. Para entornos de producción, te recomendamos usar servicios gestionados como EKS, AKS o GKE.

Configuración del Terraform Kubernetes Provider

Vamos a configurar el Terraform Kubernetes Provider paso a paso. Primero, crea un directorio para tu proyecto:

mkdir terraform-k8s-demo
cd terraform-k8s-demo

1. Definir el provider

Crea un archivo providers.tf con la configuración del provider:

terraform {
  required_providers {
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.25"
    }
  }
  required_version = ">= 1.0"
}

provider "kubernetes" {
  config_path    = "~/.kube/config"
  config_context = "minikube"  # Cambia según tu contexto
}

Este código especifica que vamos a usar el provider oficial de HashiCorp. El provider se autentica usando tu archivo kubeconfig local.

Métodos de autenticación

El provider soporta múltiples métodos de autenticación, con el siguiente orden de prioridad:

  1. Plugins cloud-específicos (eks, az, gcloud) – Recomendado para producción
  2. Tokens OAuth2 – Para integración con sistemas de identidad
  3. Certificados TLS – Autenticación basada en certificados
  4. Archivos kubeconfig – Ideal para desarrollo local
  5. Autenticación HTTP básica – No recomendado para producción

Para clusters en AWS EKS, usa esta configuración:

provider "kubernetes" {
  host                   = data.aws_eks_cluster.cluster.endpoint
  cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
  token                  = data.aws_eks_cluster_auth.cluster.token
}

2. Inicializar Terraform

terraform init

Este comando descarga el plugin del Terraform Kubernetes Provider desde el Terraform Registry y lo instala localmente en tu directorio .terraform/.

Desplegar una Aplicación con Terraform Kubernetes Provider

Ahora vamos a desplegar una aplicación NGINX completa usando el Terraform Kubernetes Provider. Esta aplicación incluirá un Deployment, un Service y un ConfigMap.

1. Crear un Namespace

Primero, crea un namespace dedicado para organizar tus recursos. Añade este código a namespace.tf:

resource "kubernetes_namespace" "app" {
  metadata {
    name = "terraform-demo"
    labels = {
      environment = "development"
      managed-by  = "terraform"
    }
  }
}

2. Configurar un Deployment

Crea un archivo deployment.tf con la definición del Deployment de NGINX:

resource "kubernetes_deployment" "nginx" {
  metadata {
    name      = "nginx-deployment"
    namespace = kubernetes_namespace.app.metadata[0].name
    labels = {
      app = "nginx"
    }
  }

  spec {
    replicas = 3

    selector {
      match_labels = {
        app = "nginx"
      }
    }

    template {
      metadata {
        labels = {
          app = "nginx"
        }
      }

      spec {
        container {
          image = "nginx:1.25-alpine"
          name  = "nginx"

          port {
            container_port = 80
          }

          resources {
            limits = {
              cpu    = "500m"
              memory = "512Mi"
            }
            requests = {
              cpu    = "250m"
              memory = "256Mi"
            }
          }

          liveness_probe {
            http_get {
              path = "/"
              port = 80
            }
            initial_delay_seconds = 30
            period_seconds        = 10
          }

          readiness_probe {
            http_get {
              path = "/"
              port = 80
            }
            initial_delay_seconds = 5
            period_seconds        = 5
          }
        }
      }
    }
  }
}

Este Deployment crea 3 réplicas de NGINX con health checks configurados. Observa cómo referenciamos el namespace usando kubernetes_namespace.app.metadata[0].name – esto crea una dependencia implícita que asegura que el namespace se cree primero.

3. Exponer con un Service

Crea service.tf para exponer el Deployment:

resource "kubernetes_service" "nginx" {
  metadata {
    name      = "nginx-service"
    namespace = kubernetes_namespace.app.metadata[0].name
  }

  spec {
    selector = {
      app = kubernetes_deployment.nginx.spec[0].template[0].metadata[0].labels.app
    }

    port {
      port        = 80
      target_port = 80
      node_port   = 30080
    }

    type = "NodePort"
  }
}

El selector del Service referencia dinámicamente las labels del Deployment, garantizando que siempre estén sincronizados. Para producción en cloud, cambia el type a «LoadBalancer» para obtener un balanceador de carga externo.

4. Añadir un ConfigMap

Crea configmap.tf para gestionar configuración de la aplicación:

resource "kubernetes_config_map" "nginx_config" {
  metadata {
    name      = "nginx-config"
    namespace = kubernetes_namespace.app.metadata[0].name
  }

  data = {
    "nginx.conf" = <<-EOF
      server {
        listen 80;
        server_name localhost;
        
        location / {
          root   /usr/share/nginx/html;
          index  index.html;
        }
        
        location /health {
          access_log off;
          return 200 "healthy\n";
        }
      }
    EOF
  }
}

5. Aplicar la configuración

# Previsualizar cambios
terraform plan

# Aplicar cambios
terraform apply

# Confirmar con 'yes'

Terraform creará todos los recursos en el orden correcto gracias a su grafo de dependencias. Puedes verificar el despliegue con kubectl:

kubectl get all -n terraform-demo

Gestión de Variables en Terraform Kubernetes Provider

Para hacer tu configuración reutilizable, utiliza variables de Terraform. Crea un archivo variables.tf:

variable "namespace" {
  description = "Kubernetes namespace para los recursos"
  type        = string
  default     = "terraform-demo"
}

variable "app_name" {
  description = "Nombre de la aplicación"
  type        = string
  default     = "nginx"
}

variable "replicas" {
  description = "Número de réplicas del deployment"
  type        = number
  default     = 3
}

variable "image_tag" {
  description = "Tag de la imagen de contenedor"
  type        = string
  default     = "1.25-alpine"
}

Ahora modifica tus recursos para usar estas variables:

resource "kubernetes_deployment" "nginx" {
  metadata {
    name      = "${var.app_name}-deployment"
    namespace = var.namespace
  }

  spec {
    replicas = var.replicas

    template {
      spec {
        container {
          image = "nginx:${var.image_tag}"
          name  = var.app_name
          # ... resto de la configuración
        }
      }
    }
  }
}

Puedes sobrescribir valores desde línea de comandos:

terraform apply -var="replicas=5" -var="image_tag=1.26-alpine"

O crear un archivo terraform.tfvars para cada entorno:

# production.tfvars
namespace  = "production"
app_name   = "nginx"
replicas   = 10
image_tag  = "1.25-alpine"

Escalado y Actualización con Terraform Kubernetes Provider

Una de las ventajas del Terraform Kubernetes Provider es la facilidad para escalar y actualizar aplicaciones.

Escalar réplicas

Simplemente modifica el valor de replicas en tu configuración:

resource "kubernetes_deployment" "nginx" {
  # ...
  spec {
    replicas = 5  # Cambiar de 3 a 5
  }
}

Ejecuta terraform apply y Terraform actualizará el Deployment sin interrumpir el servicio.

Actualizar versión de imagen

container {
  image = "nginx:1.26-alpine"  # Nueva versión
}

Terraform actualizará el Deployment siguiendo la estrategia de rolling update configurada en Kubernetes, garantizando cero downtime.

Previsualizar cambios antes de aplicar

# Ver qué cambiará exactamente
terraform plan

# Ver el diff detallado
terraform plan -out=plan.out
terraform show plan.out

Gestión de Secrets con Terraform Kubernetes Provider

El Terraform Kubernetes Provider permite gestionar Secrets de Kubernetes, aunque con consideraciones de seguridad importantes.

Crear un Secret

resource "kubernetes_secret" "app_credentials" {
  metadata {
    name      = "app-credentials"
    namespace = kubernetes_namespace.app.metadata[0].name
  }

  data = {
    username = "admin"
    password = "changeme123"  # NO hacer esto en producción
  }

  type = "Opaque"
}

Mejores prácticas para Secrets

  • NO almacenar secrets en código: Usa variables de entorno o sistemas externos
  • Integrar con Vault: Usa el Terraform Vault Provider para obtener secrets dinámicos
  • Encriptar el state file: Almacena tu terraform.tfstate en S3 con encriptación o usa Terraform Cloud
  • Variables sensibles: Marca variables como sensitive para evitar que aparezcan en logs
variable "db_password" {
  description = "Database password"
  type        = string
  sensitive   = true
}

resource "kubernetes_secret" "db" {
  metadata {
    name = "database-credentials"
  }
  
  data = {
    password = var.db_password
  }
}

Para gestión avanzada de secrets, considera usar Vaultwarden o integrar con HashiCorp Vault.

Custom Resources y Terraform Kubernetes Provider

El Terraform Kubernetes Provider soporta Custom Resource Definitions (CRDs) mediante el recurso kubernetes_manifest.

Ejemplo: Desplegar un Ingress

resource "kubernetes_manifest" "nginx_ingress" {
  manifest = {
    apiVersion = "networking.k8s.io/v1"
    kind       = "Ingress"
    
    metadata = {
      name      = "nginx-ingress"
      namespace = kubernetes_namespace.app.metadata[0].name
      annotations = {
        "kubernetes.io/ingress.class"           = "nginx"
        "cert-manager.io/cluster-issuer"        = "letsencrypt-prod"
      }
    }

    spec = {
      rules = [
        {
          host = "app.example.com"
          http = {
            paths = [
              {
                path     = "/"
                pathType = "Prefix"
                backend = {
                  service = {
                    name = kubernetes_service.nginx.metadata[0].name
                    port = {
                      number = 80
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Este enfoque funciona con cualquier CRD instalado en tu cluster, como Prometheus Operators, Istio VirtualServices, o Argo CD Applications.

Módulos Reutilizables con Terraform Kubernetes Provider

Para equipos que gestionan múltiples aplicaciones, crear módulos reutilizables es esencial. Aquí un ejemplo de estructura de módulo:

modules/
└── k8s-app/
    ├── main.tf
    ├── variables.tf
    └── outputs.tf

Contenido de modules/k8s-app/main.tf:

resource "kubernetes_deployment" "app" {
  metadata {
    name      = var.app_name
    namespace = var.namespace
  }

  spec {
    replicas = var.replicas

    selector {
      match_labels = {
        app = var.app_name
      }
    }

    template {
      metadata {
        labels = {
          app = var.app_name
        }
      }

      spec {
        container {
          image = var.image
          name  = var.app_name

          dynamic "port" {
            for_each = var.ports
            content {
              container_port = port.value
            }
          }

          dynamic "env" {
            for_each = var.environment_vars
            content {
              name  = env.key
              value = env.value
            }
          }
        }
      }
    }
  }
}

resource "kubernetes_service" "app" {
  metadata {
    name      = var.app_name
    namespace = var.namespace
  }

  spec {
    selector = {
      app = var.app_name
    }

    dynamic "port" {
      for_each = var.service_ports
      content {
        port        = port.value.port
        target_port = port.value.target_port
      }
    }

    type = var.service_type
  }
}

Uso del módulo:

module "frontend_app" {
  source = "./modules/k8s-app"

  app_name  = "frontend"
  namespace = "production"
  replicas  = 5
  image     = "myapp/frontend:v1.2.0"

  ports = [3000]

  service_ports = [
    {
      port        = 80
      target_port = 3000
    }
  ]

  environment_vars = {
    NODE_ENV = "production"
    API_URL  = "https://api.example.com"
  }
}

Optimización y Best Practices del Terraform Kubernetes Provider

Estas son las mejores prácticas para usar el Terraform Kubernetes Provider en entornos de producción:

Organización del código

  • Separar infraestructura de aplicaciones: Mantén la creación del cluster en un directorio separado del deployment de aplicaciones
  • Usar workspaces: Gestiona múltiples entornos (dev, staging, prod) con Terraform workspaces
  • Módulos por responsabilidad: Crea módulos para patrones repetitivos (apps stateless, bases de datos, ingress)

State management

  • Backend remoto: Almacena el state en S3, Azure Blob, o Terraform Cloud
  • State locking: Usa DynamoDB (AWS) o equivalente para prevenir modificaciones concurrentes
  • Versionado del state: Habilita versionado en tu backend para recuperación ante errores
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "kubernetes/production/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-lock"
  }
}

Seguridad

  • RBAC estricto: Limita permisos del service account que usa Terraform
  • Network Policies: Define políticas de red para restringir tráfico entre pods
  • Pod Security Standards: Aplica PSS (restricted, baseline) en namespaces
  • Secrets externos: Integra con HashiCorp Vault o AWS Secrets Manager

CI/CD

Integra Terraform en tu pipeline de CI/CD:

# Ejemplo GitHub Actions
name: Terraform Kubernetes
on:
  push:
    branches: [main]
    
jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        
      - name: Terraform Init
        run: terraform init
        
      - name: Terraform Plan
        run: terraform plan -out=plan.out
        
      - name: Terraform Apply
        if: github.ref == 'refs/heads/main'
        run: terraform apply plan.out

Para monitorear tu infraestructura K8s, considera implementar Uptime Kuma para monitoreo.

Troubleshooting Terraform Kubernetes Provider

Aquí están los errores más comunes y sus soluciones al trabajar con el Terraform Kubernetes Provider:

Error: Unable to connect to the server

Error: Get "https://kubernetes.default.svc": dial tcp: lookup kubernetes.default.svc

Causa: Terraform no puede conectarse al cluster de Kubernetes.

Solución:

# Verificar que kubectl funciona
kubectl cluster-info

# Verificar contexto actual
kubectl config current-context

# Actualizar provider con contexto correcto
provider "kubernetes" {
  config_path    = "~/.kube/config"
  config_context = "nombre-contexto-correcto"
}

Error: Resource already exists

Error: namespaces "terraform-demo" already exists

Causa: El recurso ya existe en Kubernetes pero no está en el state de Terraform.

Solución: Importa el recurso existente:

terraform import kubernetes_namespace.app terraform-demo

Error: Field is immutable

Error: Service spec.selector is immutable

Causa: Intentas modificar un campo inmutable de Kubernetes.

Solución: Elimina y recrea el recurso:

# Forzar recreación
terraform taint kubernetes_service.nginx
terraform apply

# O usar replace (Terraform 1.0+)
terraform apply -replace="kubernetes_service.nginx"

Debugging avanzado

# Habilitar logs detallados
export TF_LOG=DEBUG
terraform apply

# Ver estado actual de un recurso
terraform state show kubernetes_deployment.nginx

# Listar todos los recursos en el state
terraform state list

Conclusión

El Terraform Kubernetes Provider es una herramienta esencial para equipos que practican infraestructura como código en entornos cloud-native. Al combinar Terraform con Kubernetes, obtienes gestión declarativa completa, control de versiones de tu infraestructura, y la capacidad de coordinar recursos K8s con servicios cloud externos en un único workflow.

Hemos cubierto desde la configuración básica hasta patrones avanzados como módulos reutilizables, gestión de secrets, y custom resources. Las ventajas clave incluyen previsualización de cambios con terraform plan, comprensión automática de dependencias, y state management que previene configuration drift.

Para producción, recuerda implementar backend remoto con locking, integración con sistemas de secrets externos como Vault, y pipelines de CI/CD que ejecuten plan/apply automáticamente. Combina este provider con otros recursos de Terraform para construir infraestructura completa desde la red hasta las aplicaciones.

Explora más tutoriales de infraestructura como código en nuestra sección de Docker Compose y continúa aprendiendo sobre automatización DevOps.

FAQ sobre Terraform Kubernetes Provider

¿Cuándo usar Terraform Kubernetes Provider vs kubectl?

Usa el Terraform Kubernetes Provider cuando necesites gestionar infraestructura completa como código, versionar cambios, o coordinar recursos K8s con servicios cloud (RDS, S3, etc.). Usa kubectl para debugging rápido, troubleshooting en vivo, o aplicar manifiestos YAML de terceros sin modificar.

¿El Terraform Kubernetes Provider puede crear clusters?

No directamente. El provider gestiona recursos dentro de un cluster existente. Para crear clusters, usa providers específicos como terraform-provider-aws (EKS), azurerm (AKS), o google (GKE). Una vez creado el cluster, el provider de Kubernetes gestiona las aplicaciones desplegadas en él.

¿Es seguro almacenar Secrets en Terraform?

No es recomendable. Los secrets en código Terraform aparecen en el state file en texto plano. En su lugar, integra con HashiCorp Vault, AWS Secrets Manager, o Azure Key Vault usando data sources. Otra opción es usar External Secrets Operator en Kubernetes y gestionarlo con el provider.

¿Puedo usar Terraform Kubernetes Provider con Helm?

Sí, son complementarios. Usa el Terraform Helm Provider para desplegar charts de Helm desde Terraform. Esto te permite combinar infraestructura base (managed by Terraform Kubernetes Provider) con aplicaciones empaquetadas (managed by Helm), todo desde el mismo workflow de Terraform.

¿Cómo gestiono múltiples clusters con el provider?

Usa alias de providers para gestionar múltiples clusters simultáneamente:

provider "kubernetes" {
  alias       = "prod"
  config_path = "~/.kube/config-prod"
}

provider "kubernetes" {
  alias       = "staging"
  config_path = "~/.kube/config-staging"
}

resource "kubernetes_namespace" "app_prod" {
  provider = kubernetes.prod
  # ...
}

Esto permite desplegar la misma configuración en múltiples clusters desde un único código Terraform.

Avatar

Por Mid

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x