Automating Kubernetes Cluster Setup with Ansible
Over the years, I’ve found myself repeatedly setting up Kubernetes clusters using kubeadm—and while it works well, the manual process can get repetitive and error-prone. That’s why I built kubeadm-ansible: an Ansible playbook that automates the entire process of standing up a Kubernetes cluster.
This project was born out of my desire for a simple, reusable way to deploy multi-node clusters quickly—especially in test environments, homelabs, and lightweight production setups.
Table of Contents
What It Does
kubeadm-ansible simplifies Kubernetes provisioning by:
- Installing all required packages (containerd, kubeadm, etc.)
- Networking and firewall setup.
- Initializing the control plane
- Joining master to existing cluster.
- Joining worker nodes.
- Installing CNI - (Calico/Flannel)
- Installing CSI - (Rook-Ceph/Longhron)
- Addon app - metallb, metrics-server, kube-state-metrics, headlamp
- Support deployment on both Debian base or Redhat base distros.
Setup
Clone the repo:
1git clone https://github.com/mcbtaguiad/kubeadm-ansible.git
2cd kubeadm-ansible
Build docker image or just pull from my repository.
1docker compose build
2docker compose up -d
3
4# exec to container
5docker exec -it ansible-kubeadm bash
Inventory
Update your inventory file at inventory/hosts.ini with the IPs or hostnames of your master and worker nodes.
Single Master Cluster
hosts.ini
1[all]
2master01 ansible_host=192.168.254.201 ansible_user=mcbtaguiad
3worker01 ansible_host=192.168.254.204 ansible_user=mcbtaguiad
4worker02 ansible_host=192.168.254.205 ansible_user=mcbtaguiad
5
6[master]
7master01 ansible_host=192.168.254.201 ansible_user=mcbtaguiad
8
9[worker]
10worker01 ansible_host=192.168.254.204 ansible_user=mcbtaguiad
11worker02 ansible_host=192.168.254.205 ansible_user=mcbtaguiad
Multi Master Cluster
Note: Need at least 3 master nodes for high availability cluster
1[all]
2master01 ansible_host=192.168.254.201 ansible_user=mcbtaguiad
3master02 ansible_host=192.168.254.202 ansible_user=mcbtaguiad
4master03 ansible_host=192.168.254.203 ansible_user=mcbtaguiad
5worker01 ansible_host=192.168.254.204 ansible_user=mcbtaguiad
6worker02 ansible_host=192.168.254.205 ansible_user=mcbtaguiad
7
8[master]
9master01 ansible_host=192.168.254.201 ansible_user=mcbtaguiad
10master02 ansible_host=192.168.254.202 ansible_user=mcbtaguiad
11master03 ansible_host=192.168.254.203 ansible_user=mcbtaguiad
12
13[worker]
14worker01 ansible_host=192.168.254.204 ansible_user=mcbtaguiad
15worker02 ansible_host=192.168.254.205 ansible_user=mcbtaguiad
Cluster Config
Enable what you need in you k8s cluster. By default, it is configured with Calico for CNI and Rook-Ceph for CSI. Also Metallb is enabled in the addon role, if you need Ingress Controller then you might need to install that separately. Check the repo for full variable and applications available to install.
*kubeadm_init.yaml
1# ============================================================================ #
2# Author: Mark Taguiad <marktaguiad@marktaguiad.dev>
3# ============================================================================ #
4- hosts: all
5 become: true
6 vars:
7 HOST_COUNT: "{{ ansible_play_hosts | length }}"
8 KUBECONFIG: /etc/kubernetes/admin.conf
9
10 tasks:
11
12 - name: Run sys role
13 include_role:
14 name: sys
15
16 - name: Run k8s role
17 include_role:
18 name: k8s
19 vars:
20 K8S_VERSION: v1.35
21
22 - name: Wait 30 seconds
23 pause:
24 seconds: 30
25
26 - name: Run cni role
27 include_role:
28 name: cni
29 vars:
30 CNI_PLUGIN_VERSION: v1.9.0
31 CALICO_VERSION: v3.31.4
32 FLANNEL_VERSION: v0.28.1
33 apps_enabled:
34 - calico
35 # - flannel
36
37 - name: Wait 30 seconds
38 pause:
39 seconds: 30
40
41 - name: Run csi role
42 include_role:
43 name: csi
44 vars:
45 LONGHORN_VERSION: v1.11.0
46 ROOK_VERSION: v1.19.2
47 apps_enabled:
48 - rook-ceph
49 # - longhorn
50
51 - name: Wait 60 seconds
52 pause:
53 seconds: 60
54
55 - name: Run addons role
56 include_role:
57 name: addons
58 vars:
59 METALLB_VERSION: v0.15.3
60 METALLB_IP_RANGE: "192.168.254.220-192.168.254.250"
61 apps_enabled:
62 - metallb
63 - kube-state-metrics
64 - metrics-server
65 - headlamp
Init cluster
ansible-playbook playbook/kubeadm_init.yaml -i inventory/hosts.ini
That’s it. In just a few minutes, you’ll have a functional Kubernetes cluster ready to go. Kube Config file is generated as admin.yaml in the current directory.
Other Playbook
Check out the repo, I’ve also added playbook to add worker to existing cluster. Playbook to reset the nodes and installing k3s cluster (experimental).
k3s
For older or less powerful system, consider using k3s. The repo focus more on kubeadm, some error might be encountered if using this k3s playbook.
1$ ansible-playbook playbook/k3s_install.yaml -i inventory/hosts.ini