Files
infra-automation/roles/deploy_linux_vm/handlers/main.yml
ansible eba1a05e7d Implement critical role improvements per ROLE_ANALYSIS_AND_IMPROVEMENTS.md
This commit addresses the critical issues identified in the role analysis:

## Security Improvements

### Remove Hardcoded Secrets (deploy_linux_vm)
- Replaced hardcoded SSH key in defaults/main.yml with vault variable reference
- Replaced hardcoded root password with vault variable reference
- Created vault.yml.example to document secret structure
- Updated README.md with comprehensive security best practices section
- Added documentation for Ansible Vault, external secret managers, and environment variables
- Included SSH key generation and password generation best practices

## Role Documentation & Planning

### CHANGELOG.md Files
- Created comprehensive CHANGELOG.md for deploy_linux_vm role
  - Documented v1.0.0 initial release features
  - Tracked v1.0.1 security improvements
- Created comprehensive CHANGELOG.md for system_info role
  - Documented v1.0.0 initial release
  - Tracked v1.0.1 critical bug fixes (block-level failed_when, Jinja2 templates, OS variables)

### ROADMAP.md Files
- Created detailed ROADMAP.md for deploy_linux_vm role
  - Version 1.1.0: Security & compliance hardening (Q1 2026)
  - Version 1.2.0: Multi-distribution support (Q2 2026)
  - Version 1.3.0: Advanced features (Q3 2026)
  - Version 2.0.0: Enterprise features (Q4 2026)
- Created detailed ROADMAP.md for system_info role
  - Version 1.1.0: Enhanced monitoring & metrics (Q1 2026)
  - Version 1.2.0: Cloud & container support (Q2 2026)
  - Version 1.3.0: Hardware & firmware deep dive (Q3 2026)
  - Version 2.0.0: Visualization & reporting (Q4 2026)

## Error Handling Enhancements

### deploy_linux_vm Role - Block/Rescue/Always Pattern
- Wrapped deployment tasks in comprehensive error handling block
- Block section:
  - Pre-deployment VM name collision check
  - Enhanced IP address acquisition with better error messages
  - Descriptive failure messages for troubleshooting
- Rescue section (automatic rollback):
  - Diagnostic information gathering
  - VM status checking
  - Attempted console log capture
  - Automatic VM destruction and cleanup
  - Disk image removal (primary, LVM, cloud-init ISO)
  - Detailed troubleshooting guidance
- Always section:
  - Deployment logging to /var/log/ansible-vm-deployments.log
  - Success/failure tracking
- Improved task FQCNs (ansible.builtin.*)

## Handlers Implementation

### deploy_linux_vm Role - Complete Handler Suite
- VM Lifecycle Handlers:
  - restart vm, shutdown vm, destroy vm
- Cloud-Init Handlers:
  - regenerate cloud-init iso (full rebuild and reattach)
- Storage Handlers:
  - refresh libvirt storage pool
  - resize vm disk (with safe shutdown/start)
- Network Handlers:
  - refresh network configuration
  - restart libvirt network
- Libvirt Daemon Handlers:
  - restart libvirtd, reload libvirtd
- Cleanup Handlers:
  - cleanup temporary files
  - remove cloud-init iso
- Validation Handlers:
  - validate vm status
  - check connectivity

## Impact

### Security
- Eliminates hardcoded secrets from version control
- Implements industry best practices for secret management
- Provides clear guidance for secure deployment

### Maintainability
- CHANGELOGs enable version tracking and change auditing
- ROADMAPs provide clear development direction and prioritization
- Comprehensive error handling reduces debugging time
- Handlers enable modular, reusable state management

### Reliability
- Automatic rollback prevents partial deployments
- Comprehensive error messages reduce MTTR
- Handlers ensure consistent state management
- Better separation of concerns

### Compliance
- Aligns with CLAUDE.md security requirements
- Implements proper secrets management per organizational policy
- Provides audit trail through changelogs

## References

- ROLE_ANALYSIS_AND_IMPROVEMENTS.md: Initial analysis document
- CLAUDE.md: Organizational infrastructure standards

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 02:21:38 +01:00

180 lines
5.6 KiB
YAML

---
# =============================================================================
# Deploy Linux VM Role - Handlers
# =============================================================================
# Handlers are triggered by notify directives in tasks
# They execute only once at the end of a play, even if notified multiple times
# =============================================================================
# -----------------------------------------------------------------------------
# VM Lifecycle Handlers
# -----------------------------------------------------------------------------
- name: restart vm
community.libvirt.virt:
name: "{{ deploy_linux_vm_name }}"
state: restarted
listen: "restart vm"
tags: [never, vm-restart]
- name: shutdown vm
community.libvirt.virt:
name: "{{ deploy_linux_vm_name }}"
state: shutdown
listen: "shutdown vm"
tags: [never, vm-shutdown]
- name: destroy vm
community.libvirt.virt:
name: "{{ deploy_linux_vm_name }}"
state: destroyed
listen: "destroy vm"
tags: [never, vm-destroy]
# -----------------------------------------------------------------------------
# Cloud-Init Handlers
# -----------------------------------------------------------------------------
- name: regenerate cloud-init iso
block:
- name: Remove old cloud-init ISO
ansible.builtin.file:
path: "{{ deploy_linux_vm_cloud_init_iso_path }}"
state: absent
- name: Recreate cloud-init ISO with updated configuration
ansible.builtin.command:
cmd: >
genisoimage -output {{ deploy_linux_vm_cloud_init_iso_path }}
-volid cidata -joliet -rock
/tmp/cloud-init-{{ deploy_linux_vm_name }}/user-data
/tmp/cloud-init-{{ deploy_linux_vm_name }}/meta-data
register: regenerate_iso_result
changed_when: regenerate_iso_result.rc == 0
- name: Attach updated cloud-init ISO to VM
ansible.builtin.command:
cmd: >
virsh change-media {{ deploy_linux_vm_name }}
hda {{ deploy_linux_vm_cloud_init_iso_path }}
--update
when: regenerate_iso_result is succeeded
changed_when: true
listen: "regenerate cloud-init"
tags: [cloud-init]
# -----------------------------------------------------------------------------
# Storage Handlers
# -----------------------------------------------------------------------------
- name: refresh libvirt storage pool
community.libvirt.virt_pool:
name: default
state: refreshed
listen: "refresh storage pool"
tags: [storage]
- name: resize vm disk
block:
- name: Shutdown VM for disk resize
community.libvirt.virt:
name: "{{ deploy_linux_vm_name }}"
state: shutdown
- name: Wait for VM to shutdown
ansible.builtin.wait_for:
timeout: 30
- name: Resize disk image
ansible.builtin.command:
cmd: >
qemu-img resize
{{ deploy_linux_vm_disk_path }}
{{ deploy_linux_vm_disk_size_gb }}G
register: resize_result
changed_when: resize_result.rc == 0
- name: Start VM after resize
community.libvirt.virt:
name: "{{ deploy_linux_vm_name }}"
state: running
listen: "resize disk"
tags: [never, storage-resize]
# -----------------------------------------------------------------------------
# Network Handlers
# -----------------------------------------------------------------------------
- name: refresh network configuration
ansible.builtin.command:
cmd: virsh net-update {{ deploy_linux_vm_network }} add ip-dhcp-host "{{ network_xml }}" --live --config
listen: "refresh network"
tags: [network]
vars:
network_xml: "<host mac='{{ vm_mac_address }}' name='{{ deploy_linux_vm_hostname }}' ip='{{ vm_ip_address }}'/>"
- name: restart libvirt network
ansible.builtin.command:
cmd: virsh net-destroy {{ deploy_linux_vm_network }} && virsh net-start {{ deploy_linux_vm_network }}
listen: "restart network"
tags: [never, network-restart]
changed_when: true
# -----------------------------------------------------------------------------
# Libvirt Daemon Handlers
# -----------------------------------------------------------------------------
- name: restart libvirtd
ansible.builtin.service:
name: libvirtd
state: restarted
listen: "restart libvirtd"
tags: [never, libvirt-restart]
- name: reload libvirtd
ansible.builtin.service:
name: libvirtd
state: reloaded
listen: "reload libvirtd"
tags: [libvirt]
# -----------------------------------------------------------------------------
# Cleanup Handlers
# -----------------------------------------------------------------------------
- name: cleanup temporary files
ansible.builtin.file:
path: "/tmp/cloud-init-{{ deploy_linux_vm_name }}"
state: absent
listen: "cleanup temp files"
tags: [cleanup]
- name: remove cloud-init iso
ansible.builtin.file:
path: "{{ deploy_linux_vm_cloud_init_iso_path }}"
state: absent
when: deploy_linux_vm_remove_cloud_init_iso_after_boot | bool
listen: "remove cloud-init iso"
tags: [cleanup]
# -----------------------------------------------------------------------------
# Validation Handlers
# -----------------------------------------------------------------------------
- name: validate vm status
community.libvirt.virt:
name: "{{ deploy_linux_vm_name }}"
command: status
register: vm_status_check
listen: "validate vm"
tags: [validate]
- name: check vm connectivity
ansible.builtin.wait_for:
host: "{{ deploy_linux_vm_hostname }}"
port: 22
timeout: "{{ deploy_linux_vm_ssh_wait_timeout }}"
state: started
listen: "check connectivity"
tags: [validate]