Ansible
Why Ansible?
K3s cluster creation requires knowing server node IPs to connect other nodes. Since my router assigns IPs dynamically via DHCP, I can't hardcode them in cloud-init config.
The solution: Terraform process generates an inventory.yml
with node IPs,
then Ansible uses this to install and configure k3s.
Alternative Approach
A simpler alternative would be configuring a static IP for the first server node and referencing it in cloud-init configs for other nodes to join the cluster. This approach would eliminate the need for Ansible.
TODO: Test this approach.
Install
I use pipx to install Ansible.
# install pipx
sudo apt install -y pipx
pipx ensurepath
# install ansible
pipx install --include-deps ansible
Deployment
Required Files
inventory.yml
- Generated by Terraform with node IPs and k3s token.playbook.yml
- Defines k3s installation and copying config file to local~/.kube/config
.
# inventory.yml
all:
hosts:
%{~ for name, details in nodes ~}
${name}:
ansible_host: ${details.ip}
%{~ endfor ~}
vars:
k3s_token: ${k3s_token}
k3s_servers:
hosts:
%{~ for name, details in nodes ~}
%{~ if details.role == "server" ~}
${name}:
%{~ endif ~}
%{~ endfor ~}
k3s_agents:
hosts:
%{~ for name, details in nodes ~}
%{~ if details.role == "agent" ~}
${name}:
%{~ endif ~}
%{~ endfor ~}
# playbook.yml
- hosts: k3s_servers
tasks:
- name: Install K3S server
shell: >
curl -sfL https://get.k3s.io |
sh -s - server --cluster-init
--disable servicelb
--kube-proxy-arg proxy-mode=ipvs
--kube-proxy-arg ipvs-strict-arp
environment:
K3S_TOKEN: '{{ k3s_token }}'
args:
creates: /usr/local/bin/k3s
- hosts: k3s_servers[0]
vars:
k3s_server: "{{ groups['k3s_servers'][0] }}"
k3s_url: "https://{{ hostvars[k3s_server]['ansible_host'] }}:6443"
tasks:
- name: Display K3S config
shell: k3s kubectl config view --raw
become: true
register: config_output
- name: Update server URL in config
set_fact:
updated_config: "{{ config_output.stdout | regex_replace('server: .*', 'server: ' + k3s_url) }}"
- name: Copy K3S config to local.
copy:
content: '{{ updated_config }}'
dest: '/home/viet/.kube/config'
delegate_to: localhost
- hosts: k3s_agents
vars:
k3s_server: "{{ groups['k3s_servers'][0] }}"
k3s_url: "https://{{ hostvars[k3s_server]['ansible_host'] }}:6443"
tasks:
- name: Install K3S agent
shell: >
curl -sfL https://get.k3s.io |
sh -s - agent
environment:
K3S_TOKEN: '{{ k3s_token }}'
K3S_URL: '{{ k3s_url }}'
args:
creates: /usr/local/bin/k3s
Execution
ANSIBLE_HOST_KEY_CHECKING=False
is needed to avoid typing yes
when Ansible connecting to the VM for the first time.
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory.yml playbook.yml