diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ec026c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +ansible/hosts.ini \ No newline at end of file diff --git a/ansible/README.md b/ansible/README.md index b5dc59a..0a4e7b7 100644 --- a/ansible/README.md +++ b/ansible/README.md @@ -1,84 +1,119 @@ -# Home Server Ansible Configuration +# Proxmox VM Management Suite -This directory contains Ansible playbooks for managing the Proxmox home server environment. +A comprehensive Ansible automation suite for managing Proxmox Virtual Machines. This suite allows you to easily create Cloud-Init templates, provision new VMs, manage backups, and decommission resources across multiple Proxmox hosts. -## Directory Structure +## Features -- `inventory/`: Contains the inventory file `hosts.ini` where you define your servers. -- `playbooks/`: Contains the actual Ansible playbooks. -- `ansible.cfg`: Local Ansible configuration. -- `requirements.yml`: List of Ansible collections required. +- **Template Management**: + - Automatically download Cloud Images (Ubuntu, Debian, etc.). + - Pre-configured with Cloud-Init (SSH keys, IP Config). + - Support for selecting images from a curated list or custom URLs. +- **VM Provisioning**: + - Clone from templates (Full or Linked clones). + - Auto-start option. +- **Lifecycle Management**: + - Backup VMs (Snapshot mode). + - Delete/Purge VMs. +- **Security**: + - **Automatic SSH Key Injection**: Automatically adds a defined Admin SSH key to every template. + - Support for injecting additional SSH keys per deployment. ## Setup -1. **Install Requirements**: - ```bash - ansible-galaxy install -r requirements.yml - ``` - -2. **Configure Inventory**: - Edit `inventory/hosts.ini` and update the following: - - `ansible_host`: The IP address of your Proxmox node. - - `ansible_user`: The SSH user (usually root). - - `proxmox_api_*`: Variables if you plan to use API-based modules in the future. - - *Note: Ensure you have SSH key access to your Proxmox node for passwordless login, or uncomment `ansible_ssh_pass`.* - -## Available Playbooks - -### Create Ubuntu Cloud Template (`playbooks/create_ubuntu_template.yml`) - -This playbook downloads a generic Ubuntu 22.04 Cloud Image and converts it into a Proxmox VM Template. - -**Usage:** +### 1. Requirements +Install the required Ansible collections: ```bash -# Run the playbook -ansible-playbook playbooks/create_ubuntu_template.yml +ansible-galaxy install -r requirements.yml ``` -**Variables:** -You can override variables at runtime or by editing the playbook: +### 2. Configuration -- `template_id`: Default `9000` -- `template_name`: Default `ubuntu-2204-cloud` -- `storage_pool`: Default `local-lvm` +Edit `roles/proxmox_vm/defaults/main.yml` to set your global defaults, specifically the **Admin SSH Key**. -Example overriding variables: -```bash -ansible-playbook playbooks/create_ubuntu_template.yml -e "template_id=9001 template_name=my-custom-template" +**Important Variable to Change:** +```yaml +# ansible/roles/proxmox_vm/defaults/main.yml +admin_ssh_key: "ssh-ed25519 AAAAC3... your-actual-public-key" ``` -### Manage VM Playbook (`playbooks/manage_vm.yml`) +## Usage -This unified playbook allows you to manage VMs (create from template, delete, backup, create template) across your Proxmox hosts. +The main entry point is the playbook `playbooks/manage_vm.yml`. You control the behavior using the `proxmox_action` variable. -**Usage:** +### 1. Create a Cloud-Init Template -The playbook target defaults to the `proxmox` group, but you should usually specify a specific host using `target_host` variable or `-l` limit. +You can create a template by selecting a predefined alias (e.g., `ubuntu-22.04`) or providing a custom URL. -1. **Create a New Template**: - ```bash - ansible-playbook playbooks/manage_vm.yml -e "proxmox_action=create_template vmid=9003 template_name=my-ubuntu-template" - ``` +**Option A: Select from List (Default)** +Current aliases: `ubuntu-22.04`, `ubuntu-24.04`, `debian-12`. -2. **Create a VM from Template**: - ```bash - ansible-playbook playbooks/manage_vm.yml -e "proxmox_action=create_vm vmid=9002 new_vmid=105 new_vm_name=my-new-vm" - ``` +```bash +# Create Ubuntu 22.04 Template (ID: 9000) +ansible-playbook playbooks/manage_vm.yml \ + -e "proxmox_action=create_template vmid=9000 template_name=ubuntu-22-template image_alias=ubuntu-22.04" +``` -3. **Delete a VM**: - ```bash - ansible-playbook playbooks/manage_vm.yml -e "proxmox_action=delete_vm vmid=105" - ``` +**Option B: Custom URL** +```bash +ansible-playbook playbooks/manage_vm.yml \ + -e "proxmox_action=create_template \ + vmid=9001 \ + template_name=custom-linux \ + image_source_type=url \ + custom_image_url='https://example.com/image.qcow2'" +``` -4. **Backup a VM**: - ```bash - ansible-playbook playbooks/manage_vm.yml -e "proxmox_action=backup_vm vmid=105" - ``` +### 2. Create a VM from Template -**Variables:** -- `proxmox_action`: One of `create_template`, `create_vm`, `delete_vm`, `backup_vm` (Default: `create_vm`) -- `target_host`: The host to run on (Default: `proxmox` group). Example: `-e "target_host=mercury"` +Clone a valid template to a new VM. -*See `roles/proxmox_vm/defaults/main.yml` for all available configuration options.* +```bash +ansible-playbook playbooks/manage_vm.yml \ + -e "proxmox_action=create_vm \ + vmid=9000 \ + new_vmid=105 \ + new_vm_name=web-server-01" +``` + +### 3. Backup a VM + +Create a snapshot backup of a specific VM. + +```bash +ansible-playbook playbooks/manage_vm.yml \ + -e "proxmox_action=backup_vm vmid=105" +``` + +### 4. Delete a VM + +Stop and purge a VM. + +```bash +ansible-playbook playbooks/manage_vm.yml \ + -e "proxmox_action=delete_vm vmid=105" +``` + +## Advanced Usage + +### Handling Multiple Hosts +You can target a specific Proxmox node using the `target_host` variable. + +```bash +ansible-playbook playbooks/manage_vm.yml -e "proxmox_action=create_vm ... target_host=mercury" +``` + +### Injecting Additional SSH Keys +You can add extra SSH keys for a specific run (or add them to the defaults file). + +```bash +ansible-playbook playbooks/manage_vm.yml \ + -e "proxmox_action=create_template ... additional_ssh_keys=['ssh-rsa AAAAB3... key1', 'ssh-ed25519 AAAA... key2']" +``` + +## Directory Structure + +- `roles/proxmox_vm/`: Core logic role. + - `defaults/main.yml`: Configuration variables (Images, Keys, Defaults). + - `tasks/`: Action modules (`create_template.yml`, `create_vm.yml`, etc.). +- `inventory/`: Host definitions. diff --git a/ansible/roles/proxmox_vm/defaults/main.yml b/ansible/roles/proxmox_vm/defaults/main.yml index 91fb708..46860f3 100644 --- a/ansible/roles/proxmox_vm/defaults/main.yml +++ b/ansible/roles/proxmox_vm/defaults/main.yml @@ -5,22 +5,54 @@ proxmox_action: create_vm # Common settings -storage_pool: local-lvm +storage_pool: Lithium vmid: 9000 +target_node: "{{ inventory_hostname }}" -# Template Creation settings +# --- Template Creation Settings --- + +# Image Source Selection +# Options: 'list' (use image_alias) or 'url' (use custom_image_url) +image_source_type: list + +# Predefined Image List +# You can select these by setting image_alias +image_list: + ubuntu-22.04: + url: "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img" + filename: "ubuntu-22.04-server-cloudimg-amd64.img" + ubuntu-24.04: + url: "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img" + filename: "ubuntu-24.04-server-cloudimg-amd64.img" + debian-12: + url: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2" + filename: "debian-12-generic-amd64.qcow2" + +# Selection (Default) +image_alias: ubuntu-22.04 + +# Custom URL (Used if image_source_type is 'url') +custom_image_url: "" +custom_image_name: "custom-image.img" + +# Template Config template_name: ubuntu-cloud-template -image_url: "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img" -image_name: "ubuntu-22.04-server-cloudimg-amd64.img" memory: 2048 cores: 2 -# Create VM settings (cloning) -new_vm_name: new-vm -target_node: "{{ inventory_hostname }}" # For cloning, usually same node -clone_full: true # Full clone (independent) vs Linked clone +# --- SSH Key Configuration --- +# The Admin Key is always added +admin_ssh_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..." # REPLACE THIS with your actual public key -# Backup settings +# Additional keys (list of strings) +additional_ssh_keys: [] + +# --- Create VM Settings (Cloning) --- +new_vm_name: new-vm +clone_full: true # Full clone (independent) vs Linked clone +start_after_create: true + +# --- Backup Settings --- backup_mode: snapshot # snapshot, suspend, stop backup_compress: zstd -backup_storage: local +backup_storage: Lithium diff --git a/ansible/roles/proxmox_vm/tasks/create_template.yml b/ansible/roles/proxmox_vm/tasks/create_template.yml index deb979f..bfd8b03 100644 --- a/ansible/roles/proxmox_vm/tasks/create_template.yml +++ b/ansible/roles/proxmox_vm/tasks/create_template.yml @@ -1,4 +1,16 @@ --- +- name: Resolve Image Variables (List) + set_fact: + _image_url: "{{ image_list[image_alias].url }}" + _image_name: "{{ image_list[image_alias].filename }}" + when: image_source_type == 'list' + +- name: Resolve Image Variables (URL) + set_fact: + _image_url: "{{ custom_image_url }}" + _image_name: "{{ custom_image_name }}" + when: image_source_type == 'url' + - name: Check if template already exists command: "qm status {{ vmid }}" register: vm_status @@ -12,8 +24,8 @@ - name: Download Cloud Image get_url: - url: "{{ image_url }}" - dest: "/tmp/{{ image_name }}" + url: "{{ _image_url }}" + dest: "/tmp/{{ _image_name }}" mode: '0644' - name: Install libguestfs-tools @@ -34,7 +46,7 @@ --serial0 socket --vga serial0 - name: Import Disk - command: "qm importdisk {{ vmid }} /tmp/{{ image_name }} {{ storage_pool }}" + command: "qm importdisk {{ vmid }} /tmp/{{ _image_name }} {{ storage_pool }}" - name: Attach Disk to SCSI command: "qm set {{ vmid }} --scsi0 {{ storage_pool }}:vm-{{ vmid }}-disk-0" @@ -45,6 +57,22 @@ - name: Set Boot Order command: "qm set {{ vmid }} --boot c --bootdisk scsi0" +- name: Prepare SSH Keys File + copy: + content: | + {{ admin_ssh_key }} + {% for key in additional_ssh_keys %} + {{ key }} + {% endfor %} + dest: "/tmp/ssh_keys_{{ vmid }}.pub" + mode: '0600' + +- name: Configure Cloud-Init (SSH Keys, User, IP) + command: > + qm set {{ vmid }} + --sshkeys /tmp/ssh_keys_{{ vmid }}.pub + --ipconfig0 ip=dhcp + - name: Resize Disk (Default 10G) command: "qm resize {{ vmid }} scsi0 10G" ignore_errors: yes @@ -54,5 +82,10 @@ - name: Remove Downloaded Image file: - path: "/tmp/{{ image_name }}" + path: "/tmp/{{ _image_name }}" + state: absent + +- name: Remove Temporary SSH Keys File + file: + path: "/tmp/ssh_keys_{{ vmid }}.pub" state: absent diff --git a/komodo/automate/semaphore/.env.sample b/komodo/automate/semaphore/.env.sample index 407bb5f..4076c77 100644 --- a/komodo/automate/semaphore/.env.sample +++ b/komodo/automate/semaphore/.env.sample @@ -17,3 +17,7 @@ SEMAPHORE_EMAIL_PASSWORD=smtp_password SEMAPHORE_EMAIL_SECURE=false +AUTHENTIK_URL=https://authentik.example.com/application/o// +AUTHENTIK_CLIENT_ID=your_client_id +AUTHENTIK_CLIENT_SECRET=your_client_secret +AUTHENTIK_REDIRECT_URI=https://semaphore.example.com/api/auth/oidc/authentik/redirect/ diff --git a/komodo/automate/semaphore/compose.yaml b/komodo/automate/semaphore/compose.yaml index a72efd9..cacbf38 100644 --- a/komodo/automate/semaphore/compose.yaml +++ b/komodo/automate/semaphore/compose.yaml @@ -34,6 +34,18 @@ services: SEMAPHORE_EMAIL_USERNAME: ${SEMAPHORE_EMAIL_USERNAME} SEMAPHORE_EMAIL_PASSWORD: ${SEMAPHORE_EMAIL_PASSWORD} SEMAPHORE_EMAIL_SECURE: ${SEMAPHORE_EMAIL_SECURE} + SEMAPHORE_OIDC_PROVIDERS: '{ + "authentik": { + "display_name": "Sign in with Authentik", + "provider_url": ${AUTHENTIK_URL}, + "client_id": ${AUTHENTIK_CLIENT_ID}, + "client_secret": ${AUTHENTIK_CLIENT_SECRET}, + "redirect_uri": ${AUTHENTIK_REDIRECT_URI}, + "scopes": ["openid", "profile", "email"], + "username_claim": "preferred_username", + "name_claim": "preferred_username" + } + }' volumes: - semaphore_data:/var/lib/semaphore - semaphore_config:/etc/semaphore