From d0ea778e1a6a1ae4333ea90f7c5b70755212acb9 Mon Sep 17 00:00:00 2001 From: marito Date: Tue, 10 Jun 2025 13:40:55 +0800 Subject: [PATCH] init incus --- README.md | 38 +++++++ inventory.ini | 1 + playbook.yml | 121 +++++++++++++++++++++++ templates/incus-preseed.yml.j2 | 22 +++++ templates/zabbly-incus-stable.sources.j2 | 7 ++ 5 files changed, 189 insertions(+) create mode 100644 README.md create mode 100644 inventory.ini create mode 100644 playbook.yml create mode 100644 templates/incus-preseed.yml.j2 create mode 100644 templates/zabbly-incus-stable.sources.j2 diff --git a/README.md b/README.md new file mode 100644 index 0000000..46ae431 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# Ansible Playbook for Local Incus Installation + +This playbook automates the installation and setup of the **stable** version of Incus on the **local machine** (Debian/Ubuntu). It is designed to be run directly on the server you wish to configure. + +## Prerequisites + +1. **Ansible:** Must be installed on the machine where you are running the playbook. + ```bash + sudo apt update + sudo apt install ansible -y + ``` +2. **UFW Ansible Collection:** The playbook uses the `community.general.ufw` module. Install it if you don't have it: + ```bash + ansible-galaxy collection install community.general + ``` +3. **Sudo Access:** Your user must have `sudo` privileges to run the playbook. + +## How to Run + +1. **Customize Variables (Optional):** Open `playbook.yml` and review the `vars` section. You can change the storage pool driver, network settings, etc. The defaults are sensible for a standard ZFS-based setup. + +2. **Execute the Playbook:** + Run the following command from the same directory as the playbook file. It will prompt you for your `sudo` password to perform the administrative tasks. + + ```bash + ansible-playbook playbook.yml --ask-become-pass + ``` + * `--ask-become-pass`: This flag tells Ansible to prompt for the password needed for privilege escalation (`sudo`). + +## Post-Installation Steps + +After the playbook completes successfully: + +1. **Log Out and Log Back In:** To apply the `incus-admin` group membership to your user session, you **must log out and log back in**. Alternatively, for the current session only, you can run `newgrp incus-admin`. + +2. **Access the Web UI:** Open a browser and navigate to `https://localhost:8443`. You will need to accept the self-signed certificate. + +3. **Verify Setup:** You can test the installation by running `incus list`. If it runs without `sudo`, the setup is successful. diff --git a/inventory.ini b/inventory.ini new file mode 100644 index 0000000..2fbb50c --- /dev/null +++ b/inventory.ini @@ -0,0 +1 @@ +localhost diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..f2e99b5 --- /dev/null +++ b/playbook.yml @@ -0,0 +1,121 @@ +--- +- name: Install and Configure Incus (Stable) on Localhost + hosts: localhost + connection: local + become: true + vars: + # ==> User Configuration + # The user to grant Incus admin privileges. + # 'ansible_user' resolves to the user running the playbook (e.g., 'ubuntu', 'your_user'). + incus_admin_user: "{{ ansible_user }}" + + # ==> Incus Initialization (Preseed) Configuration + # Name for the default storage pool + incus_storage_pool_name: "default" + # Storage driver. 'zfs' is recommended. 'dir' is a fallback. + incus_storage_driver: "zfs" + # Network bridge name + incus_network_bridge: "incusbr0" + # IPv4 address and subnet for the bridge + incus_ipv4_addr: "10.0.5.1/24" + # IPv6 address and subnet for the bridge + incus_ipv6_addr: "fd42:5c6b:76c3:513::1/64" + + tasks: + - name: 1. Install prerequisite packages + ansible.builtin.apt: + name: + - curl + - gnupg + - ufw # Ensure ufw is installed for firewall rules + state: present + update_cache: true + + - name: 2. Create APT keyrings directory + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + mode: '0755' + + - name: 3. Add Zabbly GPG key + ansible.builtin.get_url: + url: https://pkgs.zabbly.com/key.asc + dest: /etc/apt/keyrings/zabbly.asc + mode: '0644' + force: true + + - name: 4. Add Zabbly Incus Stable repository + ansible.builtin.template: + src: templates/zabbly-incus-stable.sources.j2 + dest: /etc/apt/sources.list.d/zabbly-incus-stable.sources + mode: '0644' + notify: Update APT Cache + + - name: Handler to update APT cache + meta: flush_handlers + + - name: 5. Install Incus packages (with ZFS) + ansible.builtin.apt: + name: + - incus + - incus-client + - incus-ui-canonical + - zfsutils-linux + state: present + when: incus_storage_driver == 'zfs' + + - name: 5. Install Incus packages (non-ZFS) + ansible.builtin.apt: + name: + - incus + - incus-client + - incus-ui-canonical + state: present + when: incus_storage_driver != 'zfs' + + - name: 6. Add user to the 'incus-admin' group + ansible.builtin.user: + name: "{{ incus_admin_user }}" + groups: incus-admin + append: yes + + - name: 7. Template the Incus preseed configuration file + ansible.builtin.template: + src: templates/incus-preseed.yml.j2 + dest: /tmp/incus-preseed.yml + mode: '0600' + + - name: 8. Initialize Incus using preseed configuration + ansible.builtin.command: + cmd: incus admin init --preseed < /tmp/incus-preseed.yml + args: + # This task will only run if the storage pool doesn't already exist, making it idempotent. + creates: /var/lib/incus/storage-pools/{{ incus_storage_pool_name }} + + - name: 9. Configure Incus to listen for Web UI access + ansible.builtin.command: + cmd: incus config set core.https_address :8443 + changed_when: false # This command is idempotent + + - name: 10. Configure UFW firewall rules for Incus bridge + community.general.ufw: + rule: "{{ item.rule }}" + direction: "{{ item.direction | default(omit) }}" + interface: "{{ incus_network_bridge }}" + route: "{{ item.route | default(omit) }}" + loop: + - { rule: 'allow', direction: 'in' } + - { rule: 'allow', route: 'yes', direction: 'in' } + - { rule: 'allow', route: 'yes', direction: 'out' } + + - name: Display post-installation instructions + ansible.builtin.debug: + msg: + - "Incus installation and configuration is complete!" + - "IMPORTANT: To manage Incus without 'sudo', you must LOG OUT and LOG BACK IN, or run 'newgrp incus-admin' in your current shell." + - "Access the Web UI at: https://localhost:8443" + + handlers: + - name: Update APT Cache + ansible.builtin.apt: + update_cache: true diff --git a/templates/incus-preseed.yml.j2 b/templates/incus-preseed.yml.j2 new file mode 100644 index 0000000..9dfbd22 --- /dev/null +++ b/templates/incus-preseed.yml.j2 @@ -0,0 +1,22 @@ +# Ansible-generated Incus preseed configuration +config: {} +storage_pools: + - name: {{ incus_storage_pool_name }} + driver: {{ incus_storage_driver }} +networks: + - name: {{ incus_network_bridge }} + type: bridge + config: + ipv4.address: {{ incus_ipv4_addr }} + ipv6.address: {{ incus_ipv6_addr }} +profiles: + - name: default + devices: + root: + path: / + pool: {{ incus_storage_pool_name }} + type: disk + eth0: + name: eth0 + network: {{ incus_network_bridge }} + type: nic diff --git a/templates/zabbly-incus-stable.sources.j2 b/templates/zabbly-incus-stable.sources.j2 new file mode 100644 index 0000000..09ccf24 --- /dev/null +++ b/templates/zabbly-incus-stable.sources.j2 @@ -0,0 +1,7 @@ +Enabled: yes +Types: deb +URIs: https://pkgs.zabbly.com/incus/stable +Suites: {{ ansible_lsb.codename }} +Components: main +Architectures: {{ ansible_architecture }} +Signed-By: /etc/apt/keyrings/zabbly.asc