ansiiiible
This commit is contained in:
parent
85d0217436
commit
a8aa633c49
12 changed files with 314 additions and 0 deletions
1
ansible/ANSIBLE.md
Normal file
1
ansible/ANSIBLE.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
ansible-galaxy collection install -r requirements.yml
|
||||||
5
ansible/ansible.cfg
Normal file
5
ansible/ansible.cfg
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[defaults]
|
||||||
|
inventory = ./inventory/hosts.yml
|
||||||
|
remote_user = root
|
||||||
|
host_key_checking = false
|
||||||
|
roles_path = ./roles
|
||||||
2
ansible/inventory.ini
Normal file
2
ansible/inventory.ini
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[proxmox]
|
||||||
|
proxmox-01 ansible_host=192.168.1.205 ansible_user=plasmagoat
|
||||||
14
ansible/inventory/group_vars/all.yml
Normal file
14
ansible/inventory/group_vars/all.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# VM/Template Configuration
|
||||||
|
backup_template_vmid: 9101
|
||||||
|
backup_template_vm_name: nixos-base-backup
|
||||||
|
latest_template_vmid: 9100
|
||||||
|
latest_template_vm_name: nixos-base-latest
|
||||||
|
|
||||||
|
storage_name: local-lvm # Proxmox storage to use (e.g., local-lvm, local)
|
||||||
|
|
||||||
|
result_path: "{{ playbook_dir }}/../result" # Build output directory
|
||||||
|
dest_image_path: "/var/lib/vz/dump/" # Directory on Proxmox to upload images
|
||||||
|
|
||||||
|
# Configuration for the restored VM
|
||||||
|
cpu_cores: 2
|
||||||
|
memory_mb: 2048
|
||||||
7
ansible/inventory/hosts.yml
Normal file
7
ansible/inventory/hosts.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
all:
|
||||||
|
children:
|
||||||
|
proxmox:
|
||||||
|
hosts:
|
||||||
|
proxmox-01:
|
||||||
|
ansible_host: 192.168.1.205 # Replace with your Proxmox host IP/hostname
|
||||||
16
ansible/playbooks/create-template.yml
Normal file
16
ansible/playbooks/create-template.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
- name: Restore and Convert to Template on Proxmox
|
||||||
|
hosts: proxmox # Target the Proxmox host
|
||||||
|
become: true # Need root/sudo on Proxmox host for qm commands
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# VM/Template specifics (can be passed via --extra-vars or from group_vars)
|
||||||
|
vmid_base_template: "{{ template_vmid }}"
|
||||||
|
vmname_base_template: "{{ template_vm_name }}"
|
||||||
|
vmid_latest_template: "{{ latest_template_vmid }}"
|
||||||
|
vmname_latest_template: "{{ latest_template_vm_name }}"
|
||||||
|
|
||||||
|
# Configuration for the restored VM
|
||||||
|
cpu_cores: 2
|
||||||
|
memory_mb: 2048
|
||||||
|
|
||||||
|
tasks:
|
||||||
130
ansible/playbooks/image-deploy.yml
Normal file
130
ansible/playbooks/image-deploy.yml
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
---
|
||||||
|
- name: Build and Upload NixOS Image
|
||||||
|
hosts: localhost # Run NixOS build and image upload on the CI runner or local machine
|
||||||
|
gather_facts: false # No need to gather facts for localhost
|
||||||
|
|
||||||
|
vars:
|
||||||
|
nixos_build_path: "{{ playbook_dir }}/../" # Path to your flake.nix
|
||||||
|
result_symlink_path: "{{ nixos_build_path }}/result" # Expected symlink output from Nix
|
||||||
|
dest_dir: "{{ dest_image_dir }}" # From group_vars/all.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure NixOS image build script is executable
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ playbook_dir }}/../scripts/build_nixos_image.sh"
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Build NixOS image (creates result/ symlink)
|
||||||
|
ansible.builtin.command: "{{ playbook_dir }}/../scripts/build_nixos_image.sh"
|
||||||
|
args:
|
||||||
|
chdir: "{{ nixos_build_path }}"
|
||||||
|
register: nixos_build_result
|
||||||
|
changed_when: nixos_build_result.rc == 0 # Consider it changed if build succeeds
|
||||||
|
|
||||||
|
- name: Get built image file (.vma.zst) from result/
|
||||||
|
ansible.builtin.find:
|
||||||
|
paths: "{{ result_symlink_path }}"
|
||||||
|
patterns: "*.vma.zst"
|
||||||
|
file_type: file # Ensure it's a file
|
||||||
|
register: built_image_files
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Fail if no image was built
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: "No .vma.zst image file found in {{ result_symlink_path }}/"
|
||||||
|
when: built_image_files.files | length == 0
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Set fact for built image path and filename
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
local_image_path: "{{ built_image_files.files[0].path | realpath }}"
|
||||||
|
image_filename: "{{ built_image_files.files[0].path | basename }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Display paths (for debugging)
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Local image path: {{ local_image_path }}, Filename: {{ image_filename }}"
|
||||||
|
|
||||||
|
- name: Copy image to Proxmox server
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ local_image_path }}"
|
||||||
|
dest: "{{ dest_dir }}{{ image_filename }}"
|
||||||
|
mode: "0644" # Ensure correct permissions on the destination
|
||||||
|
|
||||||
|
- name: Clean up local build result symlink
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ result_symlink_path }}"
|
||||||
|
state: absent
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Clean up local store paths (optional, for disk space on CI)
|
||||||
|
ansible.builtin.command: "nix store gc"
|
||||||
|
args:
|
||||||
|
chdir: "{{ nixos_build_path }}"
|
||||||
|
changed_when: true # Always consider it a change
|
||||||
|
|
||||||
|
- name: Restore and Convert to Template on Proxmox
|
||||||
|
hosts: proxmox_servers # Target the Proxmox host
|
||||||
|
become: true # Need root/sudo on Proxmox host for qm commands
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# Use variables from group_vars/all.yml and vault.yml
|
||||||
|
# Access API credentials from vault for this part
|
||||||
|
proxmox_api_user_id: "{{ proxmox_ci_api_user_name }}@{{ proxmox_ci_api_user_realm }}"
|
||||||
|
proxmox_api_token_id: "{{ proxmox_ci_api_token_id }}"
|
||||||
|
proxmox_api_token_secret: "{{ proxmox_ci_api_token_secret }}"
|
||||||
|
|
||||||
|
# VM/Template specifics (can be passed via --extra-vars or from group_vars)
|
||||||
|
vmid_base_template: "{{ template_vmid }}"
|
||||||
|
vmname_base_template: "{{ template_vm_name }}"
|
||||||
|
vmid_latest_template: "{{ latest_template_vmid }}"
|
||||||
|
vmname_latest_template: "{{ latest_template_vm_name }}"
|
||||||
|
|
||||||
|
# Configuration for the restored VM
|
||||||
|
cpu_cores: 2
|
||||||
|
memory_mb: 2048
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Set full image path on Proxmox
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
remote_image_path: "{{ dest_image_dir }}{{ image_filename }}"
|
||||||
|
delegate_to: localhost # Run this locally to set a fact accessible globally
|
||||||
|
|
||||||
|
- name: Destroy existing base template VM (if it exists)
|
||||||
|
ansible.builtin.shell: "qm destroy {{ vmid_base_template }} --purge || true"
|
||||||
|
args:
|
||||||
|
warn: no
|
||||||
|
changed_when: false # Assume idempotency; if it didn't exist, no change
|
||||||
|
failed_when: false # Don't fail if VM isn't found
|
||||||
|
|
||||||
|
- name: Destroy existing 'latest' template VM (if it exists)
|
||||||
|
ansible.builtin.shell: "qm destroy {{ vmid_latest_template }} --purge || true"
|
||||||
|
args:
|
||||||
|
warn: no
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Restore VM from image to base template VMID
|
||||||
|
ansible.builtin.command: >
|
||||||
|
qmrestore {{ remote_image_path }} {{ vmid_base_template }} --unique true --name {{ vmname_base_template }} --storage {{ storage_name }}
|
||||||
|
args:
|
||||||
|
creates: "/etc/pve/qemu-server/{{ vmid_base_template }}.conf" # Idempotency check: only run if config file doesn't exist
|
||||||
|
|
||||||
|
- name: Set CPU and memory for the base template VM
|
||||||
|
ansible.builtin.command: >
|
||||||
|
qm set {{ vmid_base_template }} --cores {{ cpu_cores }} --memory {{ memory_mb }}
|
||||||
|
# This task is not fully idempotent; it will always try to set.
|
||||||
|
# You'd need complex 'when' conditions to check current settings.
|
||||||
|
|
||||||
|
- name: Convert base template VM to a template
|
||||||
|
ansible.builtin.command: "qm template {{ vmid_base_template }}"
|
||||||
|
# This command is largely idempotent for the `qm template` operation itself.
|
||||||
|
|
||||||
|
- name: Clone base template to 'latest' template VMID
|
||||||
|
ansible.builtin.command: >
|
||||||
|
qm clone {{ vmid_base_template }} {{ vmid_latest_template }} --name {{ vmname_latest_template }} --full --storage {{ storage_name }}
|
||||||
|
args:
|
||||||
|
creates: "/etc/pve/qemu-server/{{ vmid_latest_template }}.conf" # Idempotency check: only run if config file doesn't exist
|
||||||
|
|
||||||
|
- name: Convert 'latest' template VM to a template
|
||||||
|
ansible.builtin.command: "qm template {{ vmid_latest_template }}"
|
||||||
38
ansible/playbooks/upload-image.yml
Normal file
38
ansible/playbooks/upload-image.yml
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
- name: Build and Upload NixOS Image, Restore and Convert to Template
|
||||||
|
hosts: proxmox
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
image_dir: "{{ playbook_dir }}/../result"
|
||||||
|
dest_dir: "/var/lib/vz/dump/"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Get built image file (.vma.zst) from result/
|
||||||
|
ansible.builtin.find:
|
||||||
|
paths: "{{ result_path }}"
|
||||||
|
patterns: "*.vma.zst"
|
||||||
|
file_type: file # Ensure it's a file
|
||||||
|
register: built_image_files
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Fail if no image was built
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: "No .vma.zst image file found in {{ result_path }}/"
|
||||||
|
when: built_image_files.files | length == 0
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Set fact for built image path and filename
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
local_image_path: "{{ built_image_files.files[0].path | realpath }}"
|
||||||
|
image_filename: "{{ built_image_files.files[0].path | basename }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Display paths (for debugging)
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Local image path: {{ local_image_path }}, Filename: {{ image_filename }}"
|
||||||
|
|
||||||
|
- name: Copy image to Proxmox server
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ local_image_path }}"
|
||||||
|
dest: "{{ dest_dir }}"
|
||||||
|
mode: "0644" # Ensure correct permissions on the destination
|
||||||
37
ansible/roles/create-template/tasks/main.yml
Normal file
37
ansible/roles/create-template/tasks/main.yml
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
- name: Set full image path on Proxmox
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
remote_image_path: "{{ dest_image_path }}{{ image_filename }}"
|
||||||
|
delegate_to: localhost # Run this locally to set a fact accessible globally
|
||||||
|
|
||||||
|
- name: Destroy existing backup template VM (if it exists)
|
||||||
|
ansible.builtin.shell: "qm destroy {{ vmid_backup_template }} --purge || true"
|
||||||
|
# args:
|
||||||
|
# warn: no
|
||||||
|
# changed_when: false # Assume idempotency; if it didn't exist, no change
|
||||||
|
failed_when: false # Don't fail if VM isn't found
|
||||||
|
|
||||||
|
- name: Clone 'lastest' template to 'backup' template VMID
|
||||||
|
ansible.builtin.command: >
|
||||||
|
qm clone {{ vmid_latest_template }} {{ vmid_backup_template }} --name {{ vmname_backup_template }} --full
|
||||||
|
# args:
|
||||||
|
# creates: "/etc/pve/qemu-server/{{ vmid_backup_template }}.conf" # Idempotency check: only run if config file doesn't exist
|
||||||
|
# failed_when: false # Don't fail if VM isn't found
|
||||||
|
|
||||||
|
- name: Convert 'backup' template VM to a template
|
||||||
|
ansible.builtin.command: "qm template {{ vmid_backup_template }}"
|
||||||
|
|
||||||
|
- name: Destroy existing backup template VM (if it exists)
|
||||||
|
ansible.builtin.shell: "qm destroy {{ vmid_backup_template }} --purge || true"
|
||||||
|
|
||||||
|
- name: Restore VM from image to 'latest' template VMID
|
||||||
|
ansible.builtin.command: >
|
||||||
|
qmrestore {{ remote_image_path }} {{ vmid_latest_template }} --unique true
|
||||||
|
# args:
|
||||||
|
# creates: "/etc/pve/qemu-server/{{ vmid_latest_template }}.conf" # Idempotency check: only run if config file doesn't exist
|
||||||
|
|
||||||
|
- name: Set CPU and memory for the base template VM
|
||||||
|
ansible.builtin.command: >
|
||||||
|
qm set {{ vmid_latest_template }} --cores {{ cpu_cores }} --memory {{ memory_mb }} --name {{ vmname_latest_template }}
|
||||||
|
|
||||||
|
- name: Convert 'backup' template VM to a template
|
||||||
|
ansible.builtin.command: "qm template {{ vmid_latest_template }}"
|
||||||
29
ansible/roles/upload/tasks/main.yml
Normal file
29
ansible/roles/upload/tasks/main.yml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
- name: Get built image file (.vma.zst) from result/
|
||||||
|
ansible.builtin.find:
|
||||||
|
paths: "{{ result_path }}"
|
||||||
|
patterns: "*.vma.zst"
|
||||||
|
file_type: file # Ensure it's a file
|
||||||
|
register: built_image_files
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Fail if no image was built
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: "No .vma.zst image file found in {{ result_path }}/"
|
||||||
|
when: built_image_files.files | length == 0
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Set fact for built image path and filename
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
local_image_path: "{{ built_image_files.files[0].path | realpath }}"
|
||||||
|
image_filename: "{{ built_image_files.files[0].path | basename }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Display paths (for debugging)
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Local image path: {{ local_image_path }}, Filename: {{ image_filename }}"
|
||||||
|
|
||||||
|
- name: Copy image to Proxmox server
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ local_image_path }}"
|
||||||
|
dest: "{{ dest_image_path }}"
|
||||||
|
mode: "0644" # Ensure correct permissions on the destination
|
||||||
20
ansible/upload-template.yml
Normal file
20
ansible/upload-template.yml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
- name: Build and Upload NixOS Image, Restore and Convert to Template
|
||||||
|
hosts: proxmox
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- role: upload
|
||||||
|
|
||||||
|
- name: Restore and Convert to Template on Proxmox
|
||||||
|
hosts: proxmox
|
||||||
|
become: true # Need root/sudo on Proxmox host for qm commands
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# VM/Template specifics (can be passed via --extra-vars or from group_vars)
|
||||||
|
vmid_backup_template: "{{ backup_template_vmid }}"
|
||||||
|
vmname_backup_template: "{{ backup_template_vm_name }}"
|
||||||
|
vmid_latest_template: "{{ latest_template_vmid }}"
|
||||||
|
vmname_latest_template: "{{ latest_template_vm_name }}"
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- role: create-template
|
||||||
15
ansible/vault.yml
Normal file
15
ansible/vault.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# To edit this file: ansible-vault edit ansible/vault.yml
|
||||||
|
|
||||||
|
# For initial Proxmox user creation (using root@pam to create the API user)
|
||||||
|
proxmox_root_password: "YOUR_PROXMOX_ROOT_PASSWORD_HERE" # CHANGE THIS AND ENCRYPT
|
||||||
|
|
||||||
|
# For the dedicated Proxmox API user and token (for CI/CD)
|
||||||
|
proxmox_ci_api_user_name: cicd-api-user
|
||||||
|
proxmox_ci_api_user_realm: pam
|
||||||
|
proxmox_ci_api_user_password: "SUPER_STRONG_PASSWORD_FOR_API_USER" # CHANGE THIS AND ENCRYPT
|
||||||
|
|
||||||
|
proxmox_ci_api_token_id: cicd-deploy-token
|
||||||
|
# The 'value' of the API token secret should be generated by 'pveum' or 'proxmox_api_token' module.
|
||||||
|
# You will get this after running proxmox_setup.yml for the first time.
|
||||||
|
# Then update this vault.yml with the actual secret.
|
||||||
|
proxmox_ci_api_token_secret: "pveum_token_secret_from_first_run_here" # POPULATE THIS AFTER FIRST RUN AND ENCRYPT
|
||||||
Loading…
Add table
Add a link
Reference in a new issue