Provisioning Kubernetes with SemaphoreUI and Kubespray: Automating Cluster Deployment
Semaphore UI is an open-source web-based interface for managing and automating Ansible tasks and CI/CD workflows. It allows DevOps engineers to visually organize playbooks, run commands, and monitor automation pipelines without complex terminal operations. This makes it a powerful tool for simplifying infrastructure deployment, especially when combined with Kubespray, an Ansible-based Kubernetes installer.
In this article, we’ll walk you through how to install and deploy Kubernetes using SemaphoreUI and Kubespray — from setting up your inventory and playbooks to running automated tasks via Semaphore pipelines. This approach not only reduces manual effort but also ensures repeatable, consistent, and production-ready Kubernetes deployments suitable for DevOps teams and cloud-native environments.
Topology

Lab Details
Kubernetes Version: v1.31.9
ETCD : Kubeadm
CNI: Calico
CRI: Containerd
OS: Ubuntu 22.04.5 LTS
| IP | Hostname | 
|---|---|
| 10.10.61.21 | k8s-master-01 | 
| 10.10.61.22 | k8s-master-02 | 
| 10.10.61.23 | k8s-master-03 | 
| 10.10.61.25 | k8s-worker-01 | 
| 10.10.61.26 | k8s-worker-02 | 
Prerequisites
- SemaphoreUI installed
- All Kubernetes nodes can connect to each other via passwordless SSH
Preparation
- Go to the terminal where SemaphoreUIis located, then clone kubespray. This lab uses Docker
docker exec -it  semaphore-semaphore-1 sh
git clone https://github.com/kubernetes-sigs/kubespray /tmp/kubespray
cd /tmp/kubespray- Then switch to the release-2.27branch and installrequirements.txt
/tmp/kubespray $ git checkout release-2.27
/tmp/kubespray $ pip install -U -r requirements.txtDeploy Steps
- The first step is to create a project in the Semaphore UI.
- Then, copy the PrivateKeyfromk8s-master-01as a jumphost for SSH to all nodes.
cat ~/.ssh/id_rsa
...
-----BEGIN OPENSSH PRIVATE KEY-----
...
...
...
-----END OPENSSH PRIVATE KEY-----

- Then, create a repository.
Click Repository → NEW REPOSITORY-> SAVE

- Create Inventoryto include all hosts
Click Inventory → Ansible Inventory → NEW INVENTORY → Create
all:
  hosts:
    k8s-master-01:
      ansible_host: 10.10.61.21
      ip: 10.10.61.21
      access_ip: 10.10.61.21
      short_hostname: master-01
      node_taints:
        - "node-role.kubernetes.io/control-plane=:NoSchedule"
    k8s-master-02:
      ansible_host: 10.10.61.22
      ip: 10.10.61.22
      access_ip: 10.10.61.22
      short_hostname: master-02
      node_taints:
        - "node-role.kubernetes.io/control-plane=:NoSchedule"
    k8s-master-03:
      ansible_host: 10.10.61.23
      ip: 10.10.61.23
      access_ip: 10.10.61.23
      short_hostname: master-03
      node_taints:
        - "node-role.kubernetes.io/control-plane=:NoSchedule"
    k8s-worker-01:
      ansible_host: 10.10.61.25
      ip: 10.10.61.25
      access_ip: 10.10.61.25
      short_hostname: worker-01
      node_labels:
        node-role.kubernetes.io/worker: ""
        type: "app"
    k8s-worker-02:
      ansible_host: 10.10.61.26
      ip: 10.10.61.26
      access_ip: 10.10.61.26
      short_hostname: worker-02
      node_labels:
        node-role.kubernetes.io/worker: ""
        type: "app"
  children:
    kube_control_plane:
      hosts:
        k8s-master-01:
        k8s-master-02:
        k8s-master-03:
    kube_node:
      hosts:
        k8s-master-01:
        k8s-master-02:
        k8s-master-03:
        k8s-worker-01:
        k8s-worker-02:
    etcd:
      hosts:
        k8s-master-01:
        k8s-master-02:
        k8s-master-03:
    k8s_cluster:
      children:
        kube_control_plane:
        kube_node:
    calico_rr:
      hosts: {}
- Then create Environmentto define the cluster version, name clusters, etc.
Click Variable Groups → NEW GROUP → SAVE

etcd_deployment_type uses kubeadm so that etcd is a static manifest, not systemdSource: https://github.com/kubernetes-sigs/kubespray/blob/master/docs/operations/etcd.md#kubeadm
- Create a template: Task Templates→New Template→Ansible Playbook→ Input Value →Create

Deploy Cluster
- Select Task Templatesand clickDeploy Kubernetes→RUN

- Wait for the deployment process to complete

Verification
- Check the node status

- Check kube-system pods

By combining SemaphoreUI and Kubespray, deploying Kubernetes becomes more efficient, consistent, and less error-prone. This automation-driven approach not only simplifies infrastructure management but also accelerates your CI/CD workflows — helping teams focus more on innovation rather than manual configuration.
 
       
     
       
      