feat(proxmox): add hosts config
Signed-off-by: Tuan-Dat Tran <tuan-dat.tran@tudattr.dev>
This commit is contained in:
74
issues/001_fix_vault_security_issue.md
Normal file
74
issues/001_fix_vault_security_issue.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Issue: Fix Vault Security Risk in Proxmox Role
|
||||
|
||||
**Status**: Open
|
||||
**Priority**: High
|
||||
**Component**: proxmox/15_create_secret.yaml
|
||||
**Assignee**: Junior Dev
|
||||
|
||||
## Description
|
||||
The current vault handling in `roles/proxmox/tasks/15_create_secret.yaml` uses insecure shell commands to decrypt/encrypt vault files, creating temporary plaintext files that pose a security risk.
|
||||
|
||||
## Current Problematic Code
|
||||
```yaml
|
||||
- name: Decrypt vm vault file
|
||||
ansible.builtin.shell: cd ../; ansible-vault decrypt "./playbooks/{{ proxmox_vault_file }}"
|
||||
no_log: true
|
||||
|
||||
- name: Encrypt vm vault file
|
||||
ansible.builtin.shell: cd ../; ansible-vault encrypt "./playbooks/{{ proxmox_vault_file }}"
|
||||
no_log: true
|
||||
```
|
||||
|
||||
## Required Changes
|
||||
|
||||
### Step 1: Replace shell commands with Ansible vault module
|
||||
Replace the shell-based decryption/encryption with `ansible.builtin.ansible_vault` module.
|
||||
|
||||
### Step 2: Remove temporary plaintext file operations
|
||||
Eliminate the need for temporary plaintext files by using in-memory operations.
|
||||
|
||||
### Step 3: Add proper error handling
|
||||
Include error handling for vault operations (missing files, decryption failures).
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
1. **Read the current vault file securely**:
|
||||
```yaml
|
||||
- name: Load vault content securely
|
||||
ansible.builtin.include_vars:
|
||||
file: "{{ proxmox_vault_file }}"
|
||||
name: vault_data
|
||||
no_log: true
|
||||
```
|
||||
|
||||
2. **Use ansible_vault module for operations**:
|
||||
```yaml
|
||||
- name: Update vault data securely
|
||||
ansible.builtin.set_fact:
|
||||
new_vault_data: "{{ vault_data | combine({vm_name_secret: cipassword}) }}"
|
||||
when: not variable_exists
|
||||
no_log: true
|
||||
```
|
||||
|
||||
3. **Write encrypted vault directly**:
|
||||
```yaml
|
||||
- name: Write encrypted vault
|
||||
ansible.builtin.copy:
|
||||
content: "{{ new_vault_data | ansible.builtin.ansible_vault.encrypt('vault_password') }}"
|
||||
dest: "{{ proxmox_vault_file }}"
|
||||
mode: "0600"
|
||||
when: not variable_exists
|
||||
no_log: true
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
- Test with existing vault files
|
||||
- Verify no plaintext files are created during operation
|
||||
- Confirm vault can be decrypted properly after updates
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] No shell commands used for vault operations
|
||||
- [ ] No temporary plaintext files created
|
||||
- [ ] All vault operations use Ansible built-in modules
|
||||
- [ ] Existing functionality preserved
|
||||
- [ ] Proper error handling implemented
|
||||
57
issues/002_replace_dict2items_filter.md
Normal file
57
issues/002_replace_dict2items_filter.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Issue: Replace Deprecated dict2items Filter
|
||||
|
||||
**Status**: Open
|
||||
**Priority**: Medium
|
||||
**Component**: proxmox/40_prepare_vm_creation.yaml
|
||||
**Assignee**: Junior Dev
|
||||
|
||||
## Description
|
||||
The task `roles/proxmox/tasks/40_prepare_vm_creation.yaml` uses the deprecated `dict2items` filter which may be removed in future Ansible versions.
|
||||
|
||||
## Current Problematic Code
|
||||
```yaml
|
||||
- name: Download Cloud Init Isos
|
||||
ansible.builtin.include_tasks: 42_download_isos.yaml
|
||||
loop: "{{ proxmox_cloud_init_images | dict2items | map(attribute='value') }}"
|
||||
loop_control:
|
||||
loop_var: distro
|
||||
```
|
||||
|
||||
## Required Changes
|
||||
|
||||
### Step 1: Replace dict2items with modern Ansible practices
|
||||
Use `dict` filter or direct dictionary iteration instead of deprecated filter.
|
||||
|
||||
### Step 2: Update variable references
|
||||
Ensure the loop variable structure matches the new iteration method.
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Option A: Use dict filter (recommended)
|
||||
```yaml
|
||||
- name: Download Cloud Init Isos
|
||||
ansible.builtin.include_tasks: 42_download_isos.yaml
|
||||
loop: "{{ proxmox_cloud_init_images | dict | map(attribute='value') }}"
|
||||
loop_control:
|
||||
loop_var: distro
|
||||
```
|
||||
|
||||
### Option B: Direct dictionary iteration
|
||||
```yaml
|
||||
- name: Download Cloud Init Isos
|
||||
ansible.builtin.include_tasks: 42_download_isos.yaml
|
||||
loop: "{{ proxmox_cloud_init_images.values() | list }}"
|
||||
loop_control:
|
||||
loop_var: distro
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
- Verify all cloud init images are still downloaded correctly
|
||||
- Test with different dictionary structures
|
||||
- Confirm no regression in functionality
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Deprecated `dict2items` filter removed
|
||||
- [ ] All cloud init images download successfully
|
||||
- [ ] No changes to existing functionality
|
||||
- [ ] Code works with current and future Ansible versions
|
||||
105
issues/003_add_granular_tags.md
Normal file
105
issues/003_add_granular_tags.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Issue: Add Granular Tags for Better Control
|
||||
|
||||
**Status**: Open
|
||||
**Priority**: Medium
|
||||
**Component**: proxmox/tasks/main.yaml
|
||||
**Assignee**: Junior Dev
|
||||
|
||||
## Description
|
||||
The Proxmox role lacks granular tags, making it difficult to run specific parts of the role independently. Currently only has high-level `proxmox` tag.
|
||||
|
||||
## Current Limitation
|
||||
```yaml
|
||||
# Current tag structure
|
||||
roles:
|
||||
- role: proxmox
|
||||
tags:
|
||||
- proxmox
|
||||
```
|
||||
|
||||
## Required Changes
|
||||
|
||||
### Step 1: Add tags to main task includes
|
||||
Add specific tags to each major task group in `roles/proxmox/tasks/main.yaml`.
|
||||
|
||||
### Step 2: Update playbook to use new tags
|
||||
Ensure playbooks can leverage the new tag structure.
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Update roles/proxmox/tasks/main.yaml
|
||||
```yaml
|
||||
- name: Prepare Machines
|
||||
ansible.builtin.include_tasks: 00_setup_machines.yaml
|
||||
tags:
|
||||
- proxmox:setup
|
||||
- proxmox
|
||||
|
||||
- name: Create VM vault
|
||||
ansible.builtin.include_tasks: 10_create_secrets.yaml
|
||||
when: is_localhost
|
||||
tags:
|
||||
- proxmox:vault
|
||||
- proxmox
|
||||
|
||||
- name: Prime node for VM
|
||||
ansible.builtin.include_tasks: 40_prepare_vm_creation.yaml
|
||||
when: is_proxmox_node
|
||||
tags:
|
||||
- proxmox:prepare
|
||||
- proxmox
|
||||
|
||||
- name: Create VMs
|
||||
ansible.builtin.include_tasks: 50_create_vms.yaml
|
||||
when: is_localhost
|
||||
tags:
|
||||
- proxmox:vms
|
||||
- proxmox
|
||||
|
||||
- name: Create LXC containers
|
||||
ansible.builtin.include_tasks: 60_create_containers.yaml
|
||||
when: is_localhost
|
||||
tags:
|
||||
- proxmox:containers
|
||||
- proxmox
|
||||
```
|
||||
|
||||
### Update individual task files
|
||||
Add appropriate tags to tasks within each included file:
|
||||
|
||||
```yaml
|
||||
# Example for 04_configure_hosts.yaml
|
||||
- name: Configure /etc/hosts with Proxmox cluster nodes
|
||||
ansible.builtin.blockinfile:
|
||||
# ... existing content ...
|
||||
tags:
|
||||
- proxmox:setup
|
||||
- proxmox:network
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
After implementation, users can run specific parts:
|
||||
|
||||
```bash
|
||||
# Run only setup tasks
|
||||
ansible-playbook playbooks/proxmox.yaml --tags "proxmox:setup"
|
||||
|
||||
# Run only VM creation
|
||||
ansible-playbook playbooks/proxmox.yaml --tags "proxmox:vms"
|
||||
|
||||
# Run setup and preparation
|
||||
ansible-playbook playbooks/proxmox.yaml --tags "proxmox:setup,proxmox:prepare"
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
- Verify each tag group runs the correct subset of tasks
|
||||
- Test tag combinations work properly
|
||||
- Ensure backward compatibility with existing `proxmox` tag
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Granular tags added to all major task groups
|
||||
- [ ] Each functional area has its own tag
|
||||
- [ ] Original `proxmox` tag still works for backward compatibility
|
||||
- [ ] Documentation updated with tag usage examples
|
||||
- [ ] All tags tested and working
|
||||
125
issues/004_add_error_handling.md
Normal file
125
issues/004_add_error_handling.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Issue: Add Comprehensive Error Handling
|
||||
|
||||
**Status**: Open
|
||||
**Priority**: High
|
||||
**Component**: proxmox/tasks
|
||||
**Assignee**: Junior Dev
|
||||
|
||||
## Description
|
||||
The Proxmox role lacks comprehensive error handling, particularly for critical operations like API calls, vault operations, and file manipulations.
|
||||
|
||||
## Current Issues
|
||||
- No error handling for Proxmox API failures
|
||||
- No validation of VM/LXC configurations before creation
|
||||
- No retries for network operations
|
||||
- No cleanup on failure
|
||||
|
||||
## Required Changes
|
||||
|
||||
### Step 1: Add validation tasks
|
||||
Validate configurations before attempting creation.
|
||||
|
||||
### Step 2: Add error handling blocks
|
||||
Use `block/rescue/always` for critical operations.
|
||||
|
||||
### Step 3: Add retries for network operations
|
||||
Use `retries` and `delay` for API calls.
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Example 1: VM Creation with Error Handling
|
||||
```yaml
|
||||
- name: Create VM with error handling
|
||||
block:
|
||||
- name: Validate VM configuration
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- vm.vmid is defined
|
||||
- vm.vmid | int > 0
|
||||
- vm.node is defined
|
||||
- vm.cores is defined and vm.cores | int > 0
|
||||
- vm.memory is defined and vm.memory | int > 0
|
||||
msg: "Invalid VM configuration for {{ vm.name }}"
|
||||
|
||||
- name: Create VM
|
||||
community.proxmox.proxmox_kvm:
|
||||
# ... existing parameters ...
|
||||
register: vm_creation_result
|
||||
retries: 3
|
||||
delay: 10
|
||||
until: vm_creation_result is not failed
|
||||
|
||||
rescue:
|
||||
- name: Handle VM creation failure
|
||||
ansible.builtin.debug:
|
||||
msg: "Failed to create VM {{ vm.name }}: {{ ansible_failed_result.msg }}"
|
||||
|
||||
- name: Cleanup partial resources
|
||||
# Add cleanup tasks here
|
||||
when: cleanup_partial_resources | default(true)
|
||||
|
||||
always:
|
||||
- name: Log VM creation attempt
|
||||
ansible.builtin.debug:
|
||||
msg: "VM creation attempt for {{ vm.name }} completed with status: {{ vm_creation_result is defined and vm_creation_result.changed | ternary('success', 'failed') }}"
|
||||
```
|
||||
|
||||
### Example 2: API Call with Retries
|
||||
```yaml
|
||||
- name: Check Proxmox API availability
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ proxmox_api_host }}:8006/api2/json/version"
|
||||
validate_certs: no
|
||||
return_content: yes
|
||||
register: api_check
|
||||
retries: 5
|
||||
delay: 5
|
||||
until: api_check.status == 200
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Fail if API unavailable
|
||||
ansible.builtin.fail:
|
||||
msg: "Proxmox API unavailable at {{ proxmox_api_host }}"
|
||||
when: api_check is failed
|
||||
```
|
||||
|
||||
### Example 3: File Operation Error Handling
|
||||
```yaml
|
||||
- name: Manage vault file safely
|
||||
block:
|
||||
- name: Backup existing vault
|
||||
ansible.builtin.copy:
|
||||
src: "{{ proxmox_vault_file }}"
|
||||
dest: "{{ proxmox_vault_file }}.backup"
|
||||
remote_src: yes
|
||||
when: vault_file_exists.stat.exists
|
||||
|
||||
- name: Perform vault operations
|
||||
# ... vault operations ...
|
||||
|
||||
rescue:
|
||||
- name: Restore vault from backup
|
||||
ansible.builtin.copy:
|
||||
src: "{{ proxmox_vault_file }}.backup"
|
||||
dest: "{{ proxmox_vault_file }}"
|
||||
remote_src: yes
|
||||
when: vault_file_exists.stat.exists
|
||||
|
||||
- name: Fail with error details
|
||||
ansible.builtin.fail:
|
||||
msg: "Vault operation failed: {{ ansible_failed_result.msg }}"
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
- Test error scenarios (invalid configs, API unavailable)
|
||||
- Verify cleanup works on failure
|
||||
- Confirm retries work for transient failures
|
||||
- Validate error messages are helpful
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] All critical operations have error handling
|
||||
- [ ] Validation added for configurations
|
||||
- [ ] Retry logic implemented for network operations
|
||||
- [ ] Cleanup procedures in place for failures
|
||||
- [ ] Helpful error messages provided
|
||||
- [ ] No silent failures
|
||||
119
issues/005_add_performance_optimizations.md
Normal file
119
issues/005_add_performance_optimizations.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Issue: Add Performance Optimizations
|
||||
|
||||
**Status**: Open
|
||||
**Priority**: Medium
|
||||
**Component**: proxmox/tasks
|
||||
**Assignee**: Junior Dev
|
||||
|
||||
## Description
|
||||
The Proxmox role could benefit from performance optimizations, particularly for image downloads and repeated operations.
|
||||
|
||||
## Current Performance Issues
|
||||
- Sequential image downloads (no parallelization)
|
||||
- No caching of repeated operations
|
||||
- No async operations for long-running tasks
|
||||
- Inefficient fact gathering
|
||||
|
||||
## Required Changes
|
||||
|
||||
### Step 1: Add parallel downloads
|
||||
Use async for image downloads to run concurrently.
|
||||
|
||||
### Step 2: Implement caching
|
||||
Add fact caching for repeated operations.
|
||||
|
||||
### Step 3: Add conditional execution
|
||||
Skip tasks when results are already present.
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Example 1: Parallel Image Downloads
|
||||
```yaml
|
||||
- name: Download Cloud Init Isos in parallel
|
||||
ansible.builtin.include_tasks: 42_download_isos.yaml
|
||||
loop: "{{ proxmox_cloud_init_images | dict | map(attribute='value') }}"
|
||||
loop_control:
|
||||
loop_var: distro
|
||||
async: 3600 # 1 hour timeout
|
||||
poll: 0
|
||||
register: download_tasks
|
||||
|
||||
- name: Check download status
|
||||
ansible.builtin.async_status:
|
||||
jid: "{{ item.ansible_job_id }}"
|
||||
register: download_results
|
||||
until: download_results.finished
|
||||
retries: 30
|
||||
delay: 10
|
||||
loop: "{{ download_tasks.results }}"
|
||||
loop_control:
|
||||
loop_var: item
|
||||
```
|
||||
|
||||
### Example 2: Add Fact Caching
|
||||
```yaml
|
||||
# In ansible.cfg or playbook
|
||||
[defaults]
|
||||
fact_caching = jsonfile
|
||||
fact_caching_connection = /tmp/ansible_facts
|
||||
fact_caching_timeout = 86400
|
||||
|
||||
# In tasks
|
||||
- name: Gather facts with caching
|
||||
ansible.builtin.setup:
|
||||
cacheable: yes
|
||||
```
|
||||
|
||||
### Example 3: Conditional Task Execution
|
||||
```yaml
|
||||
- name: Check if image already exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ proxmox_dirs.isos }}/{{ distro.name }}"
|
||||
register: image_stat
|
||||
changed_when: false
|
||||
|
||||
- name: Download image only if missing
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ distro.url }}"
|
||||
dest: "{{ proxmox_dirs.isos }}/{{ distro.name }}"
|
||||
mode: "0644"
|
||||
when: not image_stat.stat.exists
|
||||
register: download_result
|
||||
|
||||
- name: Skip conversion if raw image exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ proxmox_dirs.isos }}/{{ raw_image_name }}"
|
||||
register: raw_image_stat
|
||||
changed_when: false
|
||||
|
||||
- name: Convert to raw only if needed
|
||||
ansible.builtin.command:
|
||||
cmd: "qemu-img convert -O raw {{ proxmox_dirs.isos }}/{{ distro.name }} {{ proxmox_dirs.isos }}/{{ raw_image_name }}"
|
||||
when:
|
||||
- download_result is changed or not raw_image_stat.stat.exists
|
||||
- image_stat.stat.exists
|
||||
```
|
||||
|
||||
### Example 4: Batch VM Operations
|
||||
```yaml
|
||||
- name: Create VMs in batches
|
||||
ansible.builtin.include_tasks: 55_create_vm.yaml
|
||||
loop: "{{ vms | batch(3) | flatten }}"
|
||||
loop_control:
|
||||
loop_var: "vm"
|
||||
throttle: 3
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
- Measure performance before and after changes
|
||||
- Verify parallel operations don't cause conflicts
|
||||
- Test caching works correctly
|
||||
- Confirm conditional execution skips appropriately
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Image downloads run in parallel
|
||||
- [ ] Fact caching implemented and working
|
||||
- [ ] Tasks skip when results already exist
|
||||
- [ ] Performance metrics show improvement
|
||||
- [ ] No race conditions in parallel operations
|
||||
- [ ] Documentation updated with performance notes
|
||||
Reference in New Issue
Block a user