Ansible Kubernetes (k8s) Module: Manage K8s Resources (Guide)
By Luca Berton · Published 2024-01-01 · Category: installation
Complete guide to Ansible k8s module. Manage Kubernetes deployments, services, configmaps, secrets, namespaces, and Helm charts with practical playbook.
The kubernetes.core.k8s module manages Kubernetes resources through Ansible — create, update, patch, and delete any Kubernetes object using YAML manifests or inline definitions. Combined with k8s_info, helm, and k8s_exec, it provides complete Kubernetes automation without writing custom scripts.
Prerequisites
# Install the collection
ansible-galaxy collection install kubernetes.core
# Python dependencies on controller
pip install kubernetes PyYAML jsonpatch
Authentication
# Option 1: Use default kubeconfig (~/.kube/config)
- name: Create namespace
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: myapp
# Option 2: Explicit kubeconfig
- name: Create namespace
kubernetes.core.k8s:
kubeconfig: /path/to/kubeconfig
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: myapp
# Option 3: In-cluster (ServiceAccount)
- name: Create namespace
kubernetes.core.k8s:
host: https://kubernetes.default.svc
api_key: "{{ lookup('file', '/var/run/secrets/kubernetes.io/serviceaccount/token') }}"
validate_certs: false
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: myapp
See also: Ansible for Kubernetes: Automate K8s Cluster Management and Application Deployment
Basic Operations
Create Resources from Inline YAML
- name: Create namespace
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
- name: Create deployment
kubernetes.core.k8s:
state: present
namespace: production
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: "myapp:{{ app_version }}"
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
Create from YAML Files
- name: Apply manifest file
kubernetes.core.k8s:
state: present
src: /path/to/deployment.yml
- name: Apply multiple manifests
kubernetes.core.k8s:
state: present
src: "{{ item }}"
loop:
- namespace.yml
- configmap.yml
- deployment.yml
- service.yml
# Apply all YAML files in a directory
- name: Apply all manifests
kubernetes.core.k8s:
state: present
src: "{{ item }}"
with_fileglob:
- manifests/*.yml
Create from Template
- name: Apply templated manifest
kubernetes.core.k8s:
state: present
template: deployment.yml.j2
Delete Resources
- name: Delete deployment
kubernetes.core.k8s:
state: absent
api_version: apps/v1
kind: Deployment
namespace: production
name: myapp
- name: Delete namespace (and everything in it)
kubernetes.core.k8s:
state: absent
api_version: v1
kind: Namespace
name: staging
Common Resources
ConfigMap
- name: Create ConfigMap
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
namespace: production
data:
DATABASE_HOST: "db.internal"
DATABASE_PORT: "5432"
LOG_LEVEL: "info"
app.conf: |
[server]
port = 8080
workers = 4
Secret
- name: Create Secret
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
namespace: production
type: Opaque
stringData:
DATABASE_PASSWORD: "{{ vault_db_password }}"
API_KEY: "{{ vault_api_key }}"
Service
- name: Create Service
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: production
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: ClusterIP
Ingress
- name: Create Ingress
kubernetes.core.k8s:
state: present
definition:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
namespace: production
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- app.example.com
secretName: myapp-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
See also: Ansible for Kubernetes: Deploy, Manage, and Automate K8s Clusters Complete Guide
Query Resources (k8s_info)
- name: Get all pods in namespace
kubernetes.core.k8s_info:
kind: Pod
namespace: production
register: pod_list
- name: Show running pods
ansible.builtin.debug:
msg: "{{ item.metadata.name }} - {{ item.status.phase }}"
loop: "{{ pod_list.resources }}"
when: item.status.phase == 'Running'
- name: Get specific deployment
kubernetes.core.k8s_info:
api_version: apps/v1
kind: Deployment
name: myapp
namespace: production
register: deploy_info
- name: Check deployment replicas
ansible.builtin.debug:
msg: "Ready: {{ deploy_info.resources[0].status.readyReplicas | default(0) }}/{{ deploy_info.resources[0].spec.replicas }}"
Wait for Resources
- name: Deploy and wait for rollout
kubernetes.core.k8s:
state: present
definition: "{{ lookup('template', 'deployment.yml.j2') }}"
wait: true
wait_timeout: 120
wait_condition:
type: Available
status: "True"
- name: Wait for pod to be ready
kubernetes.core.k8s_info:
kind: Pod
namespace: production
label_selectors:
- app=myapp
wait: true
wait_timeout: 60
wait_condition:
type: Ready
status: "True"
See also: Install Minikube with Ansible Role on All Hosts
Helm Charts
- name: Add Helm repo
kubernetes.core.helm_repository:
name: bitnami
repo_url: https://charts.bitnami.com/bitnami
- name: Install chart
kubernetes.core.helm:
name: redis
chart_ref: bitnami/redis
release_namespace: production
create_namespace: true
values:
architecture: standalone
auth:
password: "{{ vault_redis_password }}"
master:
resources:
requests:
memory: 256Mi
cpu: 100m
- name: Upgrade chart
kubernetes.core.helm:
name: redis
chart_ref: bitnami/redis
release_namespace: production
values:
master:
resources:
requests:
memory: 512Mi
- name: Uninstall chart
kubernetes.core.helm:
name: redis
release_namespace: production
state: absent
FAQ
How do I manage Kubernetes with Ansible?
Install the kubernetes.core collection and use the k8s module. Define resources as inline YAML, from files, or templates. The module is idempotent — it creates resources if missing, updates if changed, and does nothing if already matching.
What is the difference between k8s module and kubectl?
The k8s module is idempotent and declarative — it compares desired vs actual state. kubectl apply does the same but requires shell commands. The k8s module integrates with Ansible variables, templates, loops, and error handling.
Do I need kubectl installed for the k8s module?
No, the k8s module uses the Python kubernetes library directly. You need pip install kubernetes on the Ansible controller, not kubectl.
How do I wait for a deployment to be ready?
Use wait: true with wait_condition: kubernetes.core.k8s: wait=true wait_timeout=120 wait_condition.type=Available wait_condition.status=True.
Can I use Ansible with Helm?
Yes, the kubernetes.core.helm module installs, upgrades, and uninstalls Helm charts. Use helm_repository to add repos and pass values as a dictionary for chart configuration.
Conclusion
The kubernetes.core collection provides complete K8s management:
• k8s — Create, update, delete any K8s resource
• k8s_info — Query and inspect resources
• helm — Manage Helm chart releases
• wait: true — Wait for rollout completion
• Combine with Ansible variables, templates, and vault for GitOps workflows
Related Articles
• Apply Multiple YAML Files on Kubernetes with Ansible • Ansible docker_container Module Guide • Ansible Collections: Install, Use & CreateCategory: installation