Compare commits

..

4 Commits

Author SHA1 Message Date
JamesAllenby 872161a16a feat: ansible checkpoint 2026-06-27 00:35:03 +01:00
JamesAllenby 4e0b073a39 fix: rename to homelab for name length requirement 2026-06-26 23:46:47 +01:00
JamesAllenby 83abf1f978 fix: move profile to module 2026-06-26 23:44:30 +01:00
JamesAllenby fba3827961 feat: modularise incus vm 2026-06-26 23:31:14 +01:00
20 changed files with 254 additions and 146 deletions
+1
View File
@@ -0,0 +1 @@
# Home Infrastructure
View File
+1 -1
View File
@@ -1,7 +1,7 @@
plugin: community.general.incus
strict: true
remotes:
- local:home-infrastructure
- local:homelab
groups:
masters: "'master' in inventory_hostname"
workers: "'worker' in inventory_hostname"
+7
View File
@@ -0,0 +1,7 @@
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_ssh._tcp</type>
<port>22</port>
</service>
</service-group>
+4
View File
@@ -0,0 +1,4 @@
- name: Restart Avahi Daemon
ansible.builtin.service:
name: avahi-daemon
state: restarted
+19
View File
@@ -0,0 +1,19 @@
- name: Install Avahi Daemon
ansible.builtin.apt:
pkg:
- avahi-daemon
state: present
- name: Enable Avahi Daemon Service
ansible.builtin.service:
name: avahi-daemon
state: started
enabled: true
- name: Copy Avahi SSH service configuration
ansible.builtin.copy:
src: ssh.service
dest: /etc/avahi/services/ssh.service
mode: "644"
notify:
- Restart Avahi Daemon
+6
View File
@@ -1,2 +1,8 @@
- name: Install required packages
ansible.builtin.import_tasks: packages.yaml
- name: Setup networking configuration
ansible.builtin.import_tasks: network.yaml
- name: Setup Avahi Daemon
ansible.builtin.import_tasks: avahi.yaml
+5
View File
@@ -0,0 +1,5 @@
- name: Enable IPv4 Forwarding
ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: "1"
sysctl_set: true
+2 -1
View File
@@ -1,5 +1,6 @@
- name: Install Python 3 Dependencies
- name: Install Ansible Dependencies
ansible.builtin.apt:
pkg:
- python3-debian
- python3-kubernetes
state: present
@@ -0,0 +1,27 @@
---
- name: Initialise Kubernetes cluster
ansible.builtin.command:
argv:
- kubeadm
- init
- --pod-network-cidr=172.16.0.0/16
- --control-plane-endpoint={{ ansible_facts['default_ipv4']['address'] }}:6443
- --upload-certs
args:
creates: /etc/kubernetes/admin.conf
- name: Copy Kubernetes Admin Config
ansible.builtin.command: "{{ item }}"
loop:
- mkdir -p $HOME/.kube
- cp /etc/kubernetes/admin.conf $HOME/.kube/config
- chown $(id -u):$(id -g) $HOME/.kube/config
args:
creates: $HOME/.kube/config
# - name: Install Pod Network (Calico)
# ansible.builtin.shell: kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.32.0/manifests/calico.yaml > pod_network_setup.txt
# args:
# chdir: $HOME
# creates: pod_network_setup.txt
@@ -1,24 +0,0 @@
---
- name: Initialise high-availability Kubernetes cluster
ansible.builtin.command: >-
kubeadm init
--pod-network-cidr="172.16.0.0/16"
--control-plane-endpoint="{{ ansible_default_ipv4.address }}:6443"
--upload-certs
args:
creates: /etc/kubernetes/admin.conf
- name: Copy Kubernetes Admin Config
ansible.builtin.command: "{{ item }}"
loop:
- mkdir -p $HOME/.kube
- cp /etc/kubernetes/admin.conf $HOME/.kube/config
- chown $(id -u):$(id -g) $HOME/.kube/config
args:
creates: $HOME/.kube/config
- name: Install Pod Network (Calico)
ansible.builtin.shell: kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.32.0/manifests/calico.yaml > pod_network_setup.txt
args:
chdir: $HOME
creates: pod_network_setup.txt
+21 -6
View File
@@ -1,9 +1,24 @@
- name: Bootstrap
- name: Common setup
hosts: all
roles:
- common
- name: Setup Kubernetes masters
hosts: masters
roles:
- kubernetes_node
- kubernetes_master
# # ========================
# # SETUP KUBERNETES CLUSTER
# # ========================
# - name: Initialise Kubernetes cluster
# hosts: masters[0]
# roles:
# - kubernetes_master
# # =======================
# # JOIN MASTERS TO CLUSTER
# # =======================
# - name: Adkfk
# hosts: masters[0]
# tasks:
# - name: Generate Kubernetes 'join' command
# ansible.builtin.command: echo hi
# changed_when: true
+27 -114
View File
@@ -7,8 +7,8 @@ locals {
ext_disk_size = "16GiB"
network_cidr = "10.150.0.1/24"
master_count = 1
worker_count = 1
master_count = 2
worker_count = 0
image = "ubuntu/26.04"
}
@@ -18,7 +18,7 @@ locals {
# ---------
resource "incus_project" "this" {
name = "home-infrastructure"
name = "homelab"
description = "An emulated home infrastructure stack."
}
@@ -32,35 +32,9 @@ resource "incus_image" "this" {
}
}
resource "incus_profile" "this" {
name = "Default"
description = "The default profile applied to both masters and workers."
project = incus_project.this.name
depends_on = [incus_network.this]
config = {
"limits.cpu" = var.cpus
"limits.memory" = var.memory
"boot.autostart" = false
"security.secureboot" = false
}
device {
name = "root"
type = "disk"
properties = {
"pool" = "default"
"path" = "/"
"size" = local.root_disk_size
}
}
}
resource "incus_network" "this" {
name = "deskpi-cluster"
description = "An emulated network for the DeskPi Super6C cluster project."
name = "homelab"
description = "An emulated home infrastructure stack."
project = incus_project.this.name
type = "bridge"
@@ -70,93 +44,32 @@ resource "incus_network" "this" {
}
}
resource "incus_instance" "master" {
count = local.master_count
module "master" {
source = "./modules/incus_vm"
count = local.master_count
name = "master-${count.index}"
description = "Kubernetes Master ${count.index}"
project = incus_project.this.name
name = "master-${count.index}"
project = incus_project.this.name
image = incus_image.this.fingerprint
cpu = 2
memory = "2GiB"
type = "virtual-machine"
image = incus_image.this.fingerprint
profiles = [incus_profile.this.name]
wait_for {
type = "agent"
}
device {
name = "eth0"
type = "nic"
properties = {
"network" = incus_network.this.name
"ipv4.address" = cidrhost(local.network_cidr, 2 + (2 * count.index))
}
}
device {
name = "ext"
type = "disk"
properties = {
"pool" = "default"
"source" = incus_storage_volume.master[count.index].name
}
}
network = incus_network.this.name
ipv4_address = cidrhost(local.network_cidr, 2 + (2 * count.index))
}
resource "incus_storage_volume" "master" {
count = local.master_count
module "worker" {
source = "./modules/incus_vm"
count = local.worker_count
name = "master-ext-${count.index}"
description = "External drive for master ${count.index}"
pool = "default"
project = incus_project.this.name
name = "worker-${count.index}"
project = incus_project.this.name
image = incus_image.this.fingerprint
cpu = 2
memory = "2GiB"
content_type = "block"
config = {
"size" = local.ext_disk_size
}
}
resource "incus_instance" "worker" {
count = local.worker_count
name = "worker-${count.index}"
description = "Kubernetes Worker ${count.index}"
project = incus_project.this.name
type = "virtual-machine"
image = incus_image.this.fingerprint
profiles = [incus_profile.this.name]
wait_for {
type = "agent"
}
device {
name = "eth0"
type = "nic"
properties = {
"network" = incus_network.this.name
"ipv4.address" = cidrhost(local.network_cidr, 3 + (2 * count.index))
}
}
}
# -------
# Outputs
# -------
output "master_addresses" {
value = incus_instance.master[*].ipv4_address
}
output "worker_addresses" {
value = incus_instance.worker[*].ipv4_address
network = incus_network.this.name
ipv4_address = cidrhost(local.network_cidr, 3 + (2 * count.index))
}
# ---------
@@ -164,12 +77,12 @@ output "worker_addresses" {
# ---------
terraform {
required_version = "~> 1"
required_version = "~> 1.12"
required_providers {
incus = {
source = "lxc/incus"
version = "~> 1"
version = "~> 1.1"
}
}
}
+79
View File
@@ -0,0 +1,79 @@
terraform {
required_providers {
incus = {
source = "lxc/incus"
version = ">= 1.1.1"
}
}
}
resource "incus_instance" "this" {
name = var.name
description = var.description
project = var.project
type = "virtual-machine"
image = var.image
profiles = concat([incus_profile.this.name], var.profiles)
wait_for {
type = "agent"
}
device {
name = "eth0"
type = "nic"
properties = {
"network" = var.network
"ipv4.address" = var.ipv4_address
}
}
device {
name = "ext"
type = "disk"
properties = {
"pool" = "default"
"source" = incus_storage_volume.this.name
}
}
}
resource "incus_storage_volume" "this" {
name = "${var.name}-ext"
description = "External disk for ${var.name}"
pool = "default"
project = var.project
content_type = "block"
config = {
"size" = "16GiB"
}
}
resource "incus_profile" "this" {
name = var.name
description = "Default profile for ${var.name}"
project = var.project
config = {
"limits.cpu" = var.cpu
"limits.memory" = var.memory
"boot.autostart" = false
"security.secureboot" = true
}
device {
name = "root"
type = "disk"
properties = {
"pool" = "default"
"path" = "/"
"size" = "16GiB"
}
}
}
View File
+55
View File
@@ -0,0 +1,55 @@
variable "name" {
type = string
description = "The name for this instance."
nullable = false
}
variable "description" {
type = string
description = "The description for this instance."
nullable = false
default = ""
}
variable "project" {
type = string
description = "The project this instance belongs to."
nullable = true
}
variable "image" {
type = string
description = "The image for this instance."
nullable = false
}
variable "profiles" {
type = list(string)
description = "The profiles for this instance."
nullable = false
default = []
}
variable "network" {
type = string
description = "The network for this instance."
nullable = false
}
variable "ipv4_address" {
type = string
description = "The IPv4 address for this instance."
nullable = false
}
variable "cpu" {
type = number
description = "The number of CPUs for this instance."
nullable = false
}
variable "memory" {
type = string
description = "The amount of memory allocated for this instance."
nullable = false
}