AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible uri Module: REST API Requests (GET, POST, PUT, DELETE)

By Luca Berton · Published 2024-01-01 · Category: troubleshooting

How to interact with REST APIs using Ansible uri module. Send GET, POST, PUT, DELETE requests, handle authentication, parse JSON responses with examples.

Ansible uri Module: REST API Requests (GET, POST, PUT, DELETE)

How to submit a GET request to a REST API endpoint with Ansible?

I'm going to show you a live Playbook and some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.

See also: Ansible URI Module: REST API Authentication & HTTP Requests Guide

Ansible submits a GET request to a REST API endpoint

• ansible.builtin.uri • Interacts with web services supports Digest, Basic, and WSSE HTTP authentication mechanisms

Today we're talking about Ansible module uri. The full name is ansible.builtin.uri, which means that is part of the collection of modules "builtin" with ansible and shipped with it. It's a module pretty stable and out for years and it works in a different variety of POSIX operating systems. It interacts with web services and supports Digest, Basic, and WSSE HTTP authentication mechanisms. If you need to download content, use the Ansible ansible.builtin.get_url module. For Windows targets, use the ansible.windows.win_uri module instead.

Parameters

• url string - (http|https)://host.domain[:port]/path • method string - "GET", "POST", "PUT", "PATCH", "DELETE" • user (url_username), password (url_password) string - username, password credentials • force_basic_auth boolean - no,yes - Basic authentication header • status_code list/integer - [200, 202] • headers dictionary - custom HTTP headers, Content-Type • body_format string - raw, json, form-urlencoded, form-multipart • body raw - request body • return_content boolean - no/yes - return the body of the response • timeout integer - 30 seconds

This module has some parameters to perform any tasks. The only required is "url", where you specify the API URL. The parameter "method" specifies the HTTP method of the request: "GET", "POST", "PUT", "PATCH", "DELETE". The parameters "user" and "password" specify the credentials to access the API. Several authentications methods are supported, for the simplest is the Basic HTTP authentication remember to enable the "force_basic_auth" boolean. The parameter "status_code" sets the expected single or list of expected HTTP status codes. The most commons are okay is 200, not fount is 404, and so on… If Please note that Ansible is going to return an error if the status code is different. The parameter "headers" set the custom HTTP headers and HTTP Content-Type. The parameter "body_format" sets the serialization format of the body content. Default is raw, but you could customize it to send an image for example. There are some restrictions with Content-Type and some serializations. The parameter "return_content" is very important to return the body of the response as a "content" key in the dictionary result. The default timeout is set to 30 seconds, but you could customize it with the "timeout" parameter.

See also: Ansible uri Module: Make HTTP Requests and API Calls (Complete Guide)

Links

• https://reqres.in/ • https://reqres.in/api/users?page=2 • https://docs.ansible.com/ansible/latest/collections/ansible/builtin/uri_module.html

## Playbook

Let's jump into a real-life playbook on how to submit a GET request to a REST API endpoint with Ansible.

code

• get_list_users.yml
---
- name: uri module Playbook
  hosts: all
  become: false
  vars:
    server: "https://reqres.in"
    endpoint: "/api/users?page=2"
  tasks:
    - name: list users
      ansible.builtin.uri:
        url: "{{ server }}{{ endpoint }}"
        method: GET
        status_code: 200
        timeout: 30
      register: result

- name: debug ansible.builtin.debug: var: result.json.data

API

browser result (https://reqres.in/api/users?page=2):
{"page":2,"per_page":6,"total":12,"total_pages":2,"data":[{"id":7,"email":"michael.lawson@reqres.in","first_name":"Michael","last_name":"Lawson","avatar":"https://reqres.in/img/faces/7-image.jpg"},{"id":8,"email":"lindsay.ferguson@reqres.in","first_name":"Lindsay","last_name":"Ferguson","avatar":"https://reqres.in/img/faces/8-image.jpg"},{"id":9,"email":"tobias.funke@reqres.in","first_name":"Tobias","last_name":"Funke","avatar":"https://reqres.in/img/faces/9-image.jpg"},{"id":10,"email":"byron.fields@reqres.in","first_name":"Byron","last_name":"Fields","avatar":"https://reqres.in/img/faces/10-image.jpg"},{"id":11,"email":"george.edwards@reqres.in","first_name":"George","last_name":"Edwards","avatar":"https://reqres.in/img/faces/11-image.jpg"},{"id":12,"email":"rachel.howell@reqres.in","first_name":"Rachel","last_name":"Howell","avatar":"https://reqres.in/img/faces/12-image.jpg"}],"support":{"url":"https://reqres.in/#support-heading","text":"To keep ReqRes free, contributions towards server costs are appreciated!"}}

execution


$ ansible-playbook -i virtualmachines/demo/inventory interract\ webservices/list_users.yml
PLAY [uri module Playbook] ****************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [list users] *********************************************************************************
ok: [demo.example.com]
TASK [debug] **************************************************************************************
ok: [demo.example.com] => {
    "result.json.data": [
        {
            "avatar": "https://reqres.in/img/faces/7-image.jpg",
            "email": "michael.lawson@reqres.in",
            "first_name": "Michael",
            "id": 7,
            "last_name": "Lawson"
        },
        {
            "avatar": "https://reqres.in/img/faces/8-image.jpg",
            "email": "lindsay.ferguson@reqres.in",
            "first_name": "Lindsay",
            "id": 8,
            "last_name": "Ferguson"
        },
        {
            "avatar": "https://reqres.in/img/faces/9-image.jpg",
            "email": "tobias.funke@reqres.in",
            "first_name": "Tobias",
            "id": 9,
            "last_name": "Funke"
        },
        {
            "avatar": "https://reqres.in/img/faces/10-image.jpg",
            "email": "byron.fields@reqres.in",
            "first_name": "Byron",
            "id": 10,
            "last_name": "Fields"
        },
        {
            "avatar": "https://reqres.in/img/faces/11-image.jpg",
            "email": "george.edwards@reqres.in",
            "first_name": "George",
            "id": 11,
            "last_name": "Edwards"
        },
        {
            "avatar": "https://reqres.in/img/faces/12-image.jpg",
            "email": "rachel.howell@reqres.in",
            "first_name": "Rachel",
            "id": 12,
            "last_name": "Howell"
        }
    ]
}

code with ❤️ in GitHub

Conclusion

Now you know how to submit a GET request to a REST API endpoint with Ansible.

See also: Master Ansible Automation for Docker, Podman, and Kubernetes

GET Request

- name: Get API status
  ansible.builtin.uri:
    url: https://api.example.com/status
    method: GET
    return_content: true
  register: response

- debug: msg: "Status: {{ response.json.status }}, Version: {{ response.json.version }}"

POST Request (JSON)

- ansible.builtin.uri:
    url: https://api.example.com/users
    method: POST
    body_format: json
    body:
      name: "John Doe"
      email: "john@example.com"
      role: "admin"
    headers:
      Authorization: "Bearer {{ api_token }}"
    status_code: [200, 201]
  register: create_user

PUT (Update)

- uri:
    url: "https://api.example.com/users/{{ user_id }}"
    method: PUT
    body_format: json
    body:
      name: "Updated Name"
    headers:
      Authorization: "Bearer {{ api_token }}"

DELETE

- uri:
    url: "https://api.example.com/users/{{ user_id }}"
    method: DELETE
    headers:
      Authorization: "Bearer {{ api_token }}"
    status_code: [200, 204]

Authentication Methods

# Bearer token
- uri:
    url: https://api.example.com/data
    headers:
      Authorization: "Bearer {{ api_token }}"

# Basic auth - uri: url: https://api.example.com/data url_username: "{{ api_user }}" url_password: "{{ api_password }}" force_basic_auth: true

# API key - uri: url: https://api.example.com/data headers: X-API-Key: "{{ api_key }}"

Parse Response

- uri:
    url: https://api.example.com/servers
    return_content: true
  register: servers

# Access JSON response - debug: msg: "Server: {{ item.name }} ({{ item.status }})" loop: "{{ servers.json.results }}"

# Filter response - set_fact: active_servers: "{{ servers.json.results | selectattr('status', 'eq', 'active') | list }}"

Health Check Pattern

- uri:
    url: http://localhost:8080/health
    status_code: 200
  register: health
  until: health.status == 200
  retries: 30
  delay: 10

Upload File

- uri:
    url: https://api.example.com/upload
    method: POST
    body_format: form-multipart
    body:
      file:
        filename: report.pdf
        src: /tmp/report.pdf
    headers:
      Authorization: "Bearer {{ api_token }}"

Key Parameters

| Parameter | Description | |-----------|-------------| | url | Request URL | | method | GET, POST, PUT, PATCH, DELETE | | body | Request body | | body_format | json, form-urlencoded, form-multipart, raw | | headers | HTTP headers dict | | status_code | Expected status codes | | return_content | Include body in result | | validate_certs | SSL verification (default: true) | | timeout | Request timeout (seconds) | | url_username | Basic auth username | | url_password | Basic auth password |

FAQ

How do I handle API pagination?

- uri:
    url: "https://api.example.com/items?page={{ item }}&per_page=100"
  loop: "{{ range(1, total_pages + 1) }}"
  register: all_pages

Can I disable SSL verification?

validate_certs: false  # For self-signed certs (dev only!)

How do I handle rate limiting?

Use until/retries/delay or add pause between requests.

GET Request

- ansible.builtin.uri:
    url: https://api.example.com/status
    method: GET
    return_content: true
  register: response

- debug: msg: "Status: {{ response.json.status }}"

POST Request

- uri:
    url: https://api.example.com/users
    method: POST
    body_format: json
    body:
      name: "Alice"
      email: "alice@example.com"
      role: "admin"
    status_code: [200, 201]
    headers:
      Authorization: "Bearer {{ api_token }}"
  register: result

PUT (Update)

- uri:
    url: "https://api.example.com/users/{{ user_id }}"
    method: PUT
    body_format: json
    body:
      name: "Alice Updated"
    headers:
      Authorization: "Bearer {{ api_token }}"
    status_code: 200

DELETE

- uri:
    url: "https://api.example.com/users/{{ user_id }}"
    method: DELETE
    headers:
      Authorization: "Bearer {{ api_token }}"
    status_code: [200, 204]

Authentication

# Bearer token
- uri:
    url: https://api.example.com/data
    headers:
      Authorization: "Bearer {{ vault_api_token }}"

# Basic auth - uri: url: https://api.example.com/data url_username: admin url_password: "{{ vault_password }}" force_basic_auth: true

# OAuth2 token request - uri: url: https://auth.example.com/oauth/token method: POST body_format: form-urlencoded body: grant_type: client_credentials client_id: "{{ client_id }}" client_secret: "{{ client_secret }}" register: auth no_log: true

- set_fact: access_token: "{{ auth.json.access_token }}" no_log: true

Health Check Pattern

- uri:
    url: "http://localhost:{{ app_port }}/health"
    status_code: 200
  register: health
  retries: 10
  delay: 5
  until: health.status == 200

Download File

- uri:
    url: https://releases.example.com/app-v2.tar.gz
    dest: /tmp/app-v2.tar.gz
    status_code: [200, 304]

Parse Paginated API

- uri:
    url: "https://api.example.com/items?page={{ item }}&per_page=100"
    return_content: true
  loop: "{{ range(1, 6) | list }}"
  register: pages

- set_fact: all_items: "{{ pages.results | map(attribute='json') | map(attribute='items') | flatten | list }}"

Error Handling

- uri:
    url: https://api.example.com/risky-endpoint
    method: POST
    body_format: json
    body: { action: deploy }
  register: result
  failed_when: result.status not in [200, 201, 202]
  ignore_errors: true

- debug: msg: "API returned {{ result.status }}: {{ result.json | default({}) }}"

FAQ

uri vs get_url?

uri is for API interactions (any HTTP method, JSON parsing). get_url is for downloading files (simpler, supports checksums).

How to handle self-signed certificates?

validate_certs: false  # Development only!

Can I send form data?

body_format: form-urlencoded
body:
  username: admin
  password: secret

Related Articles

become directives in AnsibleAnsible inventory best practicesamazon.aws collection walkthroughdesired-state Windows config with Ansible

Category: troubleshooting

Watch the video: Ansible uri Module: REST API Requests (GET, POST, PUT, DELETE) — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home