I need some help with API and Ansible URI module

ptselios

New Member
Sep 14, 2025
11
2
3
Hallo,
I want to automate as much as possible my Proxmox lab since I want to redeploy it regularly.
I tried a couple of solutions that I found in galaxy but none of them does what I want to do, so I started writing some roles/playbooks on my own.

And the most frustrating issue I have is the usage or tokens/tickets with the URI module.


Now, if I read this, https://pve.proxmox.com/wiki/Proxmox_VE_API#API_URL, it seems that I need to grab the ticket from a POST request towards the `/api2/json/access/ticket` and then use the ticket/API.

I have tried this:
YAML:
    - name: Get an ticket if needed
      ansible.builtin.uri:
        url: "https://{{ inventory_hostname }}:8006/api2/json/access/ticket"
        body:
          username: "{{ pve_admin_api_username }}"
          password: "{{ pve_admin_api_password }}"
        force_basic_auth: true
        method: POST
        return_content: true
      when: ipc_certificates_token | default('') | length == 0
      delegate_to: localhost
      register: __ticket_json

    - name: Store ticket to a variable
      ansible.builtin.set_fact:
        __api_ticket: "{{ __ticket_json.json.data.CSRFPreventionToken }}"
      when: __ticket_json is defined


YAML:
- name: Custom certificate is installed
  ansible.builtin.uri:
    url: "https://{{ inventory_hostname }}:8006/api2/json/nodes/{{ inventory_hostname }}/certificate/custom"
    method: POST
    force_basic_auth: "{{ __auth_method | default(true) }}"
    headers:
      CSRFPreventionToken: "{{ ipc_certificates_token | default(__api_ticket, true) | default('NO TICKET') }}"
    body:
      certificates: "{{ ipc_certificates_cert_file_content }}"
      node: "{{ inventory_hostname }}"
      key: "{{ ipc_certificates_key_file_content }}"
      restart: true
  register: __pve_certificate
  tags: ipc_pve_ui_certificates

But it gives me a 401.

I also tried a couple of other things, but I am out of ideas now.
Any help would be appreciated.
 
Hi ptselios,

maybe a case of grave digging, but maybe it is still helpful:
With username + password the solution described over here worked during testing:
https://github.com/ansible/ansible/issues/67048

Utilizing the an API Token preconfigured (e.g. via WebUI) worked for me with the following snipped:

Code:
    - name: Utilizing token to query api for ha resources
      ansible.builtin.uri:
        url: "https://{{ <pve_host> }}:8006/api2/json/cluster/ha/resources"
        method: GET
        headers:
          Authorization: |
              "PVEAPIToken={{ <token_name> }}={{ <token_secret> }}"

BR, Lucas

------

PS: For utilizing POST requests it helped to set

body_format: form-urlencoded

so the arguments passed to the api could be listed as a dict e.g.
Code:
    - ansible.builtin.uri:
        url: "https://{{ pve_api_endpoint }}:8006/api2/json/cluster/ha/resources"
        method: POST
        headers:
          Authorization: xxxxxx
        body_format: form-urlencoded
        body:
          sid: "399"
 
Last edited:
I failed to update the thread. The correct answer to my question is... RTFM!
Actually it CLEARLY says that I need BOTH cookie AND token.

So, the correct code (example from token removal) is the following:

YAML:
- name: Delete tokens
  ansible.builtin.uri:
    url: "{{ pve_api_base_url }}/access/users/{{ item.0.userid }}/token/{{ item.1 }}"
    headers:
      Cookie: "PVEAuthCookie={{ __pve_ticket }}"
      CSRFPreventionToken: "{{ __pve_csrf_token }}"
    method: DELETE
    status_code:
      - 200
      - 404
  loop: "{{ __tokens_to_delete | default([]) | subelements('name', skip_missing=True) }}"
  loop_control:
    label: "{{ item.0.userid }}!{{ item.1 }}"
  register: __delete_result
  failed_when: __delete_result.status not in [200, 404]
  changed_when: true
 
Last edited:
  • Like
Reactions: bl1mp