AAP is running. Now we wire it up to deploy the K3s cluster. This phase covers creating a GitHub project, configuring credentials, building the inventory, and launching job templates — all through the AAP web UI.

By the end, you’ll deploy a 4-node K3s cluster with two clicks.

No AAP? Skip to the Vanilla Ansible section at the bottom for the command-line equivalent.


1. Playbook Overview

We use two playbooks stored in a GitHub repository:

prep_k3s.yml — OS Preparation

Runs on all nodes. Handles package updates, installs dependencies, and disables swap (required for Kubernetes).

---
- name: Prepare Ubuntu Nodes for K3s
  hosts: all
  become: true
  tasks:
    - name: Update apt cache and upgrade packages
      apt:
        update_cache: yes
        upgrade: dist
 
    - name: Install required dependencies
      apt:
        name: [curl, nfs-common, jq]
        state: present
 
    - name: Disable Swap (Required for K8s)
      command: swapoff -a
      when: ansible_swaptotal_mb > 0
 
    - name: Remove Swap from fstab
      replace:
        path: /etc/fstab
        regexp: '^([^#].*?\sswap\s+.*)$'
        replace: '# \1'

install_k3s.yml — Cluster Bootstrap

Installs K3s on the master, reads the join token, then joins all agents. Key patterns:

  • when: inventory_hostname == k3s_master_ip — targets only the master for server install
  • delegate_to + run_once: true — reads the token from the master, runs once
  • args: creates: — idempotent; skips if K3s is already installed
  • slurp + b64decode — reads the token file and decodes it in one step
---
- name: Build my K3s Lab
  hosts: all
  become: true
  vars:
    k3s_master_ip: "192.168.5.40"
 
  tasks:
    - name: Ensure curl is installed
      apt:
        name: curl
        state: present
        update_cache: yes
 
    - name: Install K3s Server on the Master node
      shell: curl -sfL https://get.k3s.io | sh -
      when: inventory_hostname == k3s_master_ip
      args:
        creates: /usr/local/bin/k3s
 
    - name: Get K3s Node Token from Master
      slurp:
        src: /var/lib/rancher/k3s/server/node-token
      register: node_token_encoded
      delegate_to: "{{ k3s_master_ip }}"
      run_once: true
 
    - name: Install K3s on Agents and join Cluster
      shell: >
        curl -sfL https://get.k3s.io | K3S_URL=https://{{ k3s_master_ip }}:6443
        K3S_TOKEN={{ node_token_encoded['content'] | b64decode | trim }} sh -
      when: inventory_hostname != k3s_master_ip
      args:
        creates: /usr/local/bin/k3s

2. Push Playbooks to GitHub

Create the two playbook files locally, then push them so AAP can pull from the repo.

mkdir k3s-lab-automation && cd k3s-lab-automation

Save the YAML from Section 1 as:

  • prep_k3s.yml
  • install_k3s.yml

Then push:

git init
git add .
git commit -m "add k3s preparation and install playbooks"
git remote add origin https://github.com/<your-username>/k3s-lab-automation.git
git push -u origin main

Everything else — inventory, credentials, project — is configured in the AAP web UI in the following steps.


3. Create a Project in AAP

A Project in AAP is a pointer to a Git repository containing playbooks.

  1. Navigate to Resources → Projects → Add
  2. Fill in:
FieldValue
NameK3s Lab Automation
OrganizationDefault
Source Control TypeGit
Source Control URLhttps://github.com/<your-username>/k3s-lab-automation.git
Source Control Branch/Tagmain
Source Control Credential(leave blank for public repos; select PAT credential for private)
  1. Click Save
  2. Wait for the Status column to show a green checkmark (successful sync)

4. Configure Credentials

AAP needs two credentials: one to SSH into the Ubuntu nodes, and one to pull from GitHub (private repos only).

Machine Credential (SSH to K3s Nodes)

  1. Navigate to Resources → Credentials → Add
  2. Fill in:
FieldValue
NameK3s Node SSH
Credential TypeMachine
Usernamejmartinez (your SSH user on the Ubuntu nodes)
Privilege Escalation Methodsudo
Password or SSH KeyYour SSH private key or password
  1. Click Save

Source Control Credential (Private GitHub Only)

  1. Navigate to Resources → Credentials → Add
  2. Generate a PAT in GitHub: Settings → Developer Settings → Tokens (classic) → Generate
    • Select scope: repo
  3. Fill in AAP:
FieldValue
NameGitHub PAT
Credential TypeSource Control
UsernameYour GitHub username
PasswordThe generated PAT
  1. Click Save

5. Build the Inventory

AAP needs its own inventory (separate from the file-based one in the repo). This is the “map” it uses to know which hosts to target.

Create the Inventory

  1. Navigate to Resources → Inventories → Add → Add Inventory
  2. Fill in:
FieldValue
NameK3s Cluster
OrganizationDefault
  1. Click Save

Add Groups

  1. Open the K3s Cluster inventory
  2. Go to the Groups tab → Add
  3. Create two groups:
Group NamePurpose
k3s_serverK3s master/control plane
k3s_agentsK3s worker nodes

Add Hosts

  1. Go to the Hosts tab → Add
  2. Add each node:
Host NameVariablesGroups
k3s-master-01ansible_host: 192.168.5.40k3s_server
k3s-worker-01ansible_host: 192.168.5.41k3s_agents
k3s-worker-02ansible_host: 192.168.5.42k3s_agents
k3s-worker-03ansible_host: 192.168.5.43k3s_agents

For each host, set the Variables field (YAML):

ansible_host: 192.168.5.40
ansible_user: jmartinez

Verify Connectivity

From the Hosts tab, select all hosts → Run Command → choose the ping module. All four should return pong.


6. Create Job Templates

Job Templates define what playbook to run, against which inventory, with which credentials.

Template 1: 01 - Prepare Nodes

This runs prep_k3s.yml to prepare the OS on all 4 nodes.

  1. Navigate to Resources → Templates → Add → Add Job Template
  2. Fill in:
FieldValue
Name01 - Prepare Nodes
Job TypeRun
InventoryK3s Cluster
ProjectK3s Lab Automation
Playbookprep_k3s.yml
CredentialsK3s Node SSH
Forks2 (limits parallel SSH connections to save RAM)
  1. Click Save

Template 2: 02 - Install K3s Cluster

This runs install_k3s.yml to bootstrap the cluster.

  1. Navigate to Resources → Templates → Add → Add Job Template
  2. Fill in:
FieldValue
Name02 - Install K3s Cluster
Job TypeRun
InventoryK3s Cluster
ProjectK3s Lab Automation
Playbookinstall_k3s.yml
CredentialsK3s Node SSH
Forks2
  1. Click Save

7. Deploy the Cluster

Run the templates in order.

Step 1: Prepare Nodes

  1. Navigate to Resources → Templates
  2. Click the rocket icon next to 01 - Prepare Nodes
  3. Watch the output in real time

Expected output:

TASK [Update apt cache and upgrade packages] ********
changed: [k3s-master-01]
changed: [k3s-worker-01]
...

TASK [Disable Swap (Required for K8s)] **************
changed: [k3s-master-01]
changed: [k3s-worker-01]
...

Step 2: Install K3s

  1. Return to Resources → Templates
  2. Click the rocket icon next to 02 - Install K3s Cluster
  3. Watch the output

Expected output:

TASK [Install K3s Server on the Master node] ********
changed: [k3s-master-01]

TASK [Get K3s Node Token from Master] ***************
ok: [k3s-master-01]

TASK [Install K3s on Agents and join Cluster] *******
changed: [k3s-worker-01]
changed: [k3s-worker-02]
changed: [k3s-worker-03]

8. Verify the Cluster

SSH into the master node and check cluster status:

ssh jmartinez@192.168.5.40
k3s kubectl get nodes

Expected output:

NAME              STATUS   ROLES                  AGE   VERSION
k3s-master-01     Ready    control-plane,master   2m    v1.31.x+k3s1
k3s-worker-01     Ready    <none>                 1m    v1.31.x+k3s1
k3s-worker-02     Ready    <none>                 1m    v1.31.x+k3s1
k3s-worker-03     Ready    <none>                 1m    v1.31.x+k3s1

Optional: Verification Playbook via AAP

Create a third job template using this playbook to verify from AAP:

---
- name: Verify K3s Cluster Status
  hosts: k3s_server
  become: true
  tasks:
    - name: Check K3s Node Status
      command: k3s kubectl get nodes
      register: nodes_output
 
    - name: Display Cluster Health
      debug:
        msg: "{{ nodes_output.stdout_lines }}"

9. Troubleshooting

Template Fails: “Project Sync Failed”

  • Verify the GitHub URL is correct
  • For private repos, confirm the Source Control credential has the right PAT
  • Re-sync manually: Resources → Projects → K3s Lab Automation → Sync

SSH Connection Timeout

  • Verify ansible_host is set on each host in the AAP inventory
  • Confirm SSH key was added to the Machine credential
  • Test from AAP host: ssh jmartinez@192.168.5.40

K3s Install Fails on Agents

  • Ensure prep_k3s.yml ran first (swap must be disabled)
  • Check the master is reachable: curl -k https://192.168.5.40:6443
  • Verify the join token hasn’t expired (tokens are valid by default)

Forks Setting

If the AAP host runs out of memory during playbook execution, reduce Forks to 1. This runs tasks sequentially but uses less RAM.


Alternative: Vanilla Ansible (No AAP)

If you don’t want to deploy AAP, you can run the playbooks directly from the command line. This skips Phase 1 entirely.

Prerequisites

Install Ansible on your control node (your workstation or the RHEL host):

# RHEL 10
sudo dnf install -y ansible-core
 
# Ubuntu
sudo apt update && sudo apt install -y ansible

Create the Inventory

Save this as inventory.yml in your project directory:

all:
  children:
    k3s_server:
      hosts:
        k3s-master-01:
          ansible_host: 192.168.5.40
          ansible_user: jmartinez
    k3s_agents:
      hosts:
        k3s-worker-01:
          ansible_host: 192.168.5.41
          ansible_user: jmartinez
        k3s-worker-02:
          ansible_host: 192.168.5.42
          ansible_user: jmartinez
        k3s-worker-03:
          ansible_host: 192.168.5.43
          ansible_user: jmartinez

Verify Connectivity

ansible -i inventory.yml all -m ping

All four nodes should return pong.

Prepare the Nodes

ansible-playbook -i inventory.yml prep_k3s.yml

Install the Cluster

ansible-playbook -i inventory.yml install_k3s.yml

Verify

ssh jmartinez@192.168.5.40 "k3s kubectl get nodes"

Useful Flags

FlagPurpose
--checkDry run — no changes made
--diffShow what would change
-vvvVerbose output for debugging
--limit k3s-master-01Run on a single host
--becomeEscalate to root (already in playbooks)

What’s Next

Your 4-node K3s cluster is up and running, deployed entirely through AAP’s web UI. In Phase 3, we cover post-install tasks: non-root cluster administration, Ansible Vault integration, and production hardening.