- name: Ensure Proxmox API user exists and has correct password (using pveum) ansible.builtin.shell: | set -e # Exit immediately if a command exits with a non-zero status USER_EXISTS=$(pveum user list --output-format json | jq -r '.[] | select(.userid == "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}") | .userid') if [ -z "$USER_EXISTS" ]; then pveum user add "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}" --password "{{ proxmox_api_user_password }}" --comment "CI/CD user created by Ansible" -enable 1 echo "User '{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}' was added." else # Always attempt to modify to ensure password/comment is up-to-date # pveum user modify does not return 'modified' for idempotency (echo "{{ proxmox_api_user_password }}"; echo "{{ proxmox_api_user_password }}") | pveum passwd "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}" pveum user modify "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}" --comment "CI/CD user updated by Ansible" echo "User '{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}' was modified (or already up-to-date)." fi register: pveum_user_result changed_when: "'added' in pveum_user_result.stdout or 'modified' in pveum_user_result.stdout" failed_when: pveum_user_result.rc != 0 and 'already exists' not in pveum_user_result.stderr no_log: true # Prevent password from being logged - name: Ensure Proxmox API token exists (using pveum) ansible.builtin.shell: | set -e TOKEN_INFO=$(pveum user token list "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}" --output-format json 2>/dev/null | jq -r '.[] | select(.tokenid == "{{ proxmox_api_token_id }}")') if [ -z "$TOKEN_INFO" ]; then pveum user token add "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}" "{{ proxmox_api_token_id }}" --comment "CI/CD token created by Ansible" # echo "Token '{{ proxmox_api_token_id }}' was added. Secret: $(cat ~/.pve/token-{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}!{{ proxmox_api_token_id }}.json | jq -r '.value')" # Capture secret else echo "Token '{{ proxmox_api_token_id }}' for user '{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}' already exists. No action taken." fi register: pveum_token_result changed_when: "'was added' in pveum_token_result.stdout" # This task is tricky for secret capture. # `pveum user token add` prints the secret to stdout on creation AND saves it to a file. # We try to capture it from stdout and then from the file for robustness. # You MUST parse `pveum_token_result.stdout` to get the secret when it's new. # In real CI/CD, generate a new token via pveum only ONCE and store the secret # then use `proxmox_api_token_secret` in your vars. no_log: false # Prevent password and token secret from being logged - debug: var: pveum_token_result.stdout - name: Ensure ACL for root exists ansible.builtin.shell: | set -e ACL_EXISTS=$(pveum acl list --output-format json 2>/dev/null | jq -r '.[] | select(.path == "/" and .user == "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}" and .roleid == "{{ proxmox_api_user_role }}") | .path') if [ -z "$ACL_EXISTS" ]; then pveum acl modify / -user "{{ proxmox_api_user_name }}@{{ proxmox_api_user_realm }}" -role "{{ proxmox_api_user_role }}" -propagate 1 echo "ACL for / was added." else echo "ACL for / already exists." fi register: pveum_acl_root_result changed_when: "'was added' in pveum_acl_root_result.stdout"