Some checks failed
CI / lint-and-test (pull_request) Failing after 1m20s
CI / ansible-validation (pull_request) Successful in 6m40s
CI / secret-scanning (pull_request) Successful in 2m36s
CI / dependency-scan (pull_request) Successful in 6m12s
CI / sast-scan (pull_request) Successful in 6m48s
CI / license-check (pull_request) Successful in 1m16s
CI / vault-check (pull_request) Failing after 6m13s
CI / playbook-test (pull_request) Successful in 6m34s
CI / container-scan (pull_request) Successful in 6m57s
CI / sonar-analysis (pull_request) Failing after 1m10s
CI / workflow-summary (pull_request) Successful in 1m11s
- Add roles/pote: Python/venv deployment role with PostgreSQL, cron jobs - Add playbooks/app/: Proxmox app stack provisioning and configuration - Add roles/app_setup: Generic app deployment role (Node.js/systemd) - Add roles/base_os: Base OS hardening role - Enhance roles/proxmox_vm: Split LXC/KVM tasks, improve error handling - Add IP uniqueness validation: Preflight check for duplicate IPs within projects - Add Proxmox-side IP conflict detection: Check existing LXC net0 configs - Update inventories/production/group_vars/all/main.yml: Add pote project config - Add vault.example.yml: Template for POTE secrets (git key, DB, SMTP) - Update .gitignore: Exclude deploy keys, backup files, and other secrets - Update documentation: README, role docs, execution flow guides Security: - All secrets stored in encrypted vault.yml (never committed in plaintext) - Deploy keys excluded via .gitignore - IP conflict guardrails prevent accidental duplicate IP assignments
100 lines
3.8 KiB
YAML
100 lines
3.8 KiB
YAML
---
|
|
# Playbook: app/proxmox_info.yml
|
|
# Purpose: Query Proxmox API for VM/LXC info (status, node, name, vmid) and
|
|
# optionally filter to just the guests defined in `app_projects`.
|
|
# Targets: localhost
|
|
# Tags: app, proxmox, info
|
|
#
|
|
# Usage examples:
|
|
# - Show only projectA guests: ansible-playbook -i inventories/production playbooks/app/proxmox_info.yml -e app_project=projectA
|
|
# - Show all VMs/CTs on the cluster: ansible-playbook -i inventories/production playbooks/app/proxmox_info.yml -e proxmox_info_all=true
|
|
# - Restrict to only LXC: -e proxmox_info_type=lxc
|
|
|
|
- name: Proxmox inventory info (VMs and containers)
|
|
hosts: localhost
|
|
connection: local
|
|
gather_facts: false
|
|
vars:
|
|
selected_projects: >-
|
|
{{
|
|
(app_projects | dict2items | map(attribute='key') | list)
|
|
if (app_project is not defined or app_project | length == 0)
|
|
else [app_project]
|
|
}}
|
|
proxmox_info_all_default: false
|
|
proxmox_info_type_default: all # all|lxc|qemu
|
|
|
|
tasks:
|
|
- name: Validate requested project exists
|
|
ansible.builtin.assert:
|
|
that:
|
|
- app_project is not defined or app_project in app_projects
|
|
fail_msg: "Requested app_project={{ app_project | default('') }} does not exist in app_projects."
|
|
|
|
- name: Build list of expected VMIDs and names from app_projects
|
|
ansible.builtin.set_fact:
|
|
expected_vmids: >-
|
|
{{
|
|
selected_projects
|
|
| map('extract', app_projects)
|
|
| map(attribute='envs')
|
|
| map('dict2items')
|
|
| map('map', attribute='value')
|
|
| list
|
|
| flatten
|
|
| map(attribute='vmid')
|
|
| select('defined')
|
|
| list
|
|
}}
|
|
expected_names: >-
|
|
{{
|
|
selected_projects
|
|
| map('extract', app_projects)
|
|
| map(attribute='envs')
|
|
| map('dict2items')
|
|
| map('map', attribute='value')
|
|
| list
|
|
| flatten
|
|
| map(attribute='name')
|
|
| list
|
|
}}
|
|
|
|
- name: Query Proxmox for guest info
|
|
community.proxmox.proxmox_vm_info:
|
|
api_host: "{{ proxmox_host }}"
|
|
api_port: "{{ proxmox_api_port | default(8006) }}"
|
|
validate_certs: "{{ proxmox_validate_certs | default(false) }}"
|
|
api_user: "{{ proxmox_user }}"
|
|
api_password: "{{ vault_proxmox_password | default(omit) }}"
|
|
api_token_id: "{{ proxmox_token_id | default(omit, true) }}"
|
|
api_token_secret: "{{ vault_proxmox_token | default(omit, true) }}"
|
|
node: "{{ proxmox_node | default(omit) }}"
|
|
type: "{{ proxmox_info_type | default(proxmox_info_type_default) }}"
|
|
config: none
|
|
register: proxmox_info
|
|
|
|
- name: Filter guests to expected VMIDs/names (unless proxmox_info_all)
|
|
ansible.builtin.set_fact:
|
|
filtered_guests: >-
|
|
{{
|
|
(proxmox_info.proxmox_vms | default([]))
|
|
if (proxmox_info_all | default(proxmox_info_all_default) | bool)
|
|
else (
|
|
(proxmox_info.proxmox_vms | default([]))
|
|
| selectattr('name', 'in', expected_names)
|
|
| list
|
|
)
|
|
}}
|
|
|
|
- name: Display Proxmox guest summary
|
|
ansible.builtin.debug:
|
|
msg: |
|
|
Proxmox: {{ proxmox_host }} (node={{ proxmox_node | default('any') }}, type={{ proxmox_info_type | default(proxmox_info_type_default) }})
|
|
Showing: {{ 'ALL guests' if (proxmox_info_all | default(proxmox_info_all_default) | bool) else ('app_projects for ' ~ (selected_projects | join(', '))) }}
|
|
|
|
{% for g in (filtered_guests | sort(attribute='vmid')) %}
|
|
- vmid={{ g.vmid }} type={{ g.id.split('/')[0] if g.id is defined else 'unknown' }} name={{ g.name | default('') }} node={{ g.node | default('') }} status={{ g.status | default('') }}
|
|
{% endfor %}
|
|
|
|
|