Setup

# Install the Kubernetes collection
ansible-galaxy collection install kubernetes.core

# Install Python dependencies
pip install kubernetes openshift PyYAML

Deploy Applications

Create Namespace

- name: Create namespace
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: v1
      kind: Namespace
      metadata:
        name: myapp
        labels:
          environment: production

Deploy Application

- name: Deploy web application
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: webapp
        namespace: myapp
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: webapp
        template:
          metadata:
            labels:
              app: webapp
          spec:
            containers:
              - name: webapp
                image: "myregistry/webapp:{{ app_version }}"
                ports:
                  - containerPort: 8080
                resources:
                  requests:
                    memory: "128Mi"
                    cpu: "250m"
                  limits:
                    memory: "256Mi"
                    cpu: "500m"
                livenessProbe:
                  httpGet:
                    path: /health
                    port: 8080
                  initialDelaySeconds: 30

Expose with Service

- name: Create service
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: v1
      kind: Service
      metadata:
        name: webapp
        namespace: myapp
      spec:
        selector:
          app: webapp
        ports:
          - port: 80
            targetPort: 8080
        type: ClusterIP

Query Cluster

- name: Get all pods in namespace
  kubernetes.core.k8s_info:
    kind: Pod
    namespace: myapp
  register: pod_list

- name: Show pod names
  ansible.builtin.debug:
    msg: "{{ item.metadata.name }} - {{ item.status.phase }}"
  loop: "{{ pod_list.resources }}"

- name: Wait for deployment to be ready
  kubernetes.core.k8s_info:
    kind: Deployment
    name: webapp
    namespace: myapp
  register: deployment
  until: deployment.resources[0].status.readyReplicas | default(0) == deployment.resources[0].spec.replicas
  retries: 30
  delay: 10

Helm Charts

- name: Add Helm repo
  kubernetes.core.helm_repository:
    name: bitnami
    repo_url: https://charts.bitnami.com/bitnami

- name: Deploy PostgreSQL via Helm
  kubernetes.core.helm:
    name: postgresql
    chart_ref: bitnami/postgresql
    release_namespace: database
    create_namespace: true
    values:
      auth:
        postgresPassword: "{{ vault_pg_password }}"
      primary:
        persistence:
          size: 50Gi

ConfigMaps & Secrets

- name: Create ConfigMap
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: app-config
        namespace: myapp
      data:
        DATABASE_URL: "postgresql://db:5432/myapp"
        LOG_LEVEL: "info"

- name: Create Secret
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: v1
      kind: Secret
      metadata:
        name: app-secrets
        namespace: myapp
      type: Opaque
      stringData:
        DB_PASSWORD: "{{ vault_db_password }}"
        API_KEY: "{{ vault_api_key }}"

RBAC

- name: Create ServiceAccount
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: app-sa
        namespace: myapp

- name: Create Role
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: app-role
        namespace: myapp
      rules:
        - apiGroups: [""]
          resources: ["pods", "services", "configmaps"]
          verbs: ["get", "list", "watch"]
        - apiGroups: ["apps"]
          resources: ["deployments"]
          verbs: ["get", "list", "watch", "update", "patch"]

Rolling Updates

- name: Update image version (rolling update)
  kubernetes.core.k8s:
    state: present
    definition:
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: webapp
        namespace: myapp
      spec:
        strategy:
          type: RollingUpdate
          rollingUpdate:
            maxSurge: 1
            maxUnavailable: 0
        template:
          spec:
            containers:
              - name: webapp
                image: "myregistry/webapp:{{ new_version }}"

Delete Resources

- name: Delete deployment
  kubernetes.core.k8s:
    state: absent
    kind: Deployment
    name: webapp
    namespace: myapp

Conclusion

Ansible + Kubernetes is powerful for teams already using Ansible. Use kubernetes.core.k8s for resource management, k8s_info for querying, and helm for chart deployments. Combine with Ansible Vault for secrets management.

Related reading: running Ansible against Kubernetes clusters covers this in real-world detail.