ansible: restructure with dynamic inventory from flake
- Move playbooks/ to ansible/playbooks/ - Add dynamic inventory script that extracts hosts from flake - Groups by tier (tier_test, tier_prod) and role (role_dns, etc.) - Reads homelab.host.* options for metadata - Add static inventory for non-flake hosts (Proxmox) - Add ansible.cfg with inventory path and SSH optimizations - Add group_vars/all.yml for common variables - Add restart-service.yml playbook for restarting systemd services - Update provision-approle.yml with single-host safeguard - Add ANSIBLE_CONFIG to devshell for automatic inventory discovery - Add ansible = "false" label to template2 to exclude from inventory - Update CLAUDE.md to reference ansible/README.md for details Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
146
ansible/playbooks/build-and-deploy-template.yml
Normal file
146
ansible/playbooks/build-and-deploy-template.yml
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
- name: Build and deploy NixOS Proxmox template
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
template_name: "template2"
|
||||
nixos_config: "template2"
|
||||
proxmox_node: "pve1.home.2rjus.net" # Change to your Proxmox node name
|
||||
proxmox_host: "pve1.home.2rjus.net" # Change to your Proxmox host
|
||||
template_vmid: 9000 # Template VM ID
|
||||
storage: "local-zfs"
|
||||
|
||||
tasks:
|
||||
- name: Build NixOS image
|
||||
ansible.builtin.command:
|
||||
cmd: "nixos-rebuild build-image --image-variant proxmox --flake .#template2"
|
||||
chdir: "{{ playbook_dir }}/../.."
|
||||
register: build_result
|
||||
changed_when: true
|
||||
|
||||
- name: Find built image file
|
||||
ansible.builtin.find:
|
||||
paths: "{{ playbook_dir}}/../../result"
|
||||
patterns: "*.vma.zst"
|
||||
recurse: true
|
||||
register: image_files
|
||||
|
||||
- name: Fail if no image found
|
||||
ansible.builtin.fail:
|
||||
msg: "No QCOW2 image found in build output"
|
||||
when: image_files.matched == 0
|
||||
|
||||
- name: Set image path
|
||||
ansible.builtin.set_fact:
|
||||
image_path: "{{ image_files.files[0].path }}"
|
||||
|
||||
- name: Extract image filename
|
||||
ansible.builtin.set_fact:
|
||||
image_filename: "{{ image_path | basename }}"
|
||||
|
||||
- name: Display image info
|
||||
ansible.builtin.debug:
|
||||
msg: "Built image: {{ image_path }} ({{ image_filename }})"
|
||||
|
||||
- name: Deploy template to Proxmox
|
||||
hosts: proxmox
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
template_name: "template2"
|
||||
template_vmid: 9000
|
||||
storage: "local-zfs"
|
||||
|
||||
tasks:
|
||||
- name: Get image path and filename from localhost
|
||||
ansible.builtin.set_fact:
|
||||
image_path: "{{ hostvars['localhost']['image_path'] }}"
|
||||
image_filename: "{{ hostvars['localhost']['image_filename'] }}"
|
||||
|
||||
- name: Set destination path
|
||||
ansible.builtin.set_fact:
|
||||
image_dest: "/var/lib/vz/dump/{{ image_filename }}"
|
||||
|
||||
- name: Copy image to Proxmox
|
||||
ansible.builtin.copy:
|
||||
src: "{{ image_path }}"
|
||||
dest: "{{ image_dest }}"
|
||||
mode: '0644'
|
||||
|
||||
- name: Check if template VM already exists
|
||||
ansible.builtin.command:
|
||||
cmd: "qm status {{ template_vmid }}"
|
||||
register: vm_status
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Destroy existing template VM if it exists
|
||||
ansible.builtin.command:
|
||||
cmd: "qm destroy {{ template_vmid }} --purge"
|
||||
when: vm_status.rc == 0
|
||||
changed_when: true
|
||||
|
||||
- name: Import image
|
||||
ansible.builtin.command:
|
||||
cmd: "qmrestore {{ image_dest }} {{ template_vmid }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Convert VM to template
|
||||
ansible.builtin.command:
|
||||
cmd: "qm template {{ template_vmid }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Clean up uploaded image
|
||||
ansible.builtin.file:
|
||||
path: "{{ image_dest }}"
|
||||
state: absent
|
||||
|
||||
- name: Display success message
|
||||
ansible.builtin.debug:
|
||||
msg: "Template VM {{ template_vmid }} created successfully on {{ storage }}"
|
||||
|
||||
- name: Update Terraform template name
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
terraform_dir: "{{ playbook_dir }}/../../terraform"
|
||||
|
||||
tasks:
|
||||
- name: Get image filename from earlier play
|
||||
ansible.builtin.set_fact:
|
||||
image_filename: "{{ hostvars['localhost']['image_filename'] }}"
|
||||
|
||||
- name: Extract template name from image filename
|
||||
ansible.builtin.set_fact:
|
||||
new_template_name: "{{ image_filename | regex_replace('\\.vma\\.zst$', '') | regex_replace('^vzdump-qemu-', '') }}"
|
||||
|
||||
- name: Read current Terraform variables file
|
||||
ansible.builtin.slurp:
|
||||
src: "{{ terraform_dir }}/variables.tf"
|
||||
register: variables_tf_content
|
||||
|
||||
- name: Extract current template name from variables.tf
|
||||
ansible.builtin.set_fact:
|
||||
current_template_name: "{{ (variables_tf_content.content | b64decode) | regex_search('variable \"default_template_name\"[^}]+default\\s*=\\s*\"([^\"]+)\"', '\\1') | first }}"
|
||||
|
||||
- name: Check if template name has changed
|
||||
ansible.builtin.set_fact:
|
||||
template_name_changed: "{{ current_template_name != new_template_name }}"
|
||||
|
||||
- name: Display template name status
|
||||
ansible.builtin.debug:
|
||||
msg: "Template name: {{ current_template_name }} -> {{ new_template_name }} ({{ 'changed' if template_name_changed else 'unchanged' }})"
|
||||
|
||||
- name: Update default_template_name in variables.tf
|
||||
ansible.builtin.replace:
|
||||
path: "{{ terraform_dir }}/variables.tf"
|
||||
regexp: '(variable "default_template_name"[^}]+default\s*=\s*)"[^"]+"'
|
||||
replace: '\1"{{ new_template_name }}"'
|
||||
when: template_name_changed
|
||||
|
||||
- name: Display update result
|
||||
ansible.builtin.debug:
|
||||
msg: "Updated terraform/variables.tf with new template name: {{ new_template_name }}"
|
||||
when: template_name_changed
|
||||
Reference in New Issue
Block a user