Aller au contenu
Infrastructure as Code medium

Module uri Ansible : appels API REST avec parsing JSON

9 min de lecture

Logo Ansible

ansible.builtin.uri: fait des appels HTTP/HTTPS depuis le managed node : GET, POST, PUT, DELETE. C’est l’équivalent d’un curl mais avec idempotence explicite, parsing JSON automatique, et gestion d’erreurs structurée.

Cas d’usage RHCE 2026 : healthchecks applicatifs, création de ressources via API (Kubernetes, Vault, Grafana), récupération de tokens OAuth, notifications webhook (Slack, Teams).

Options critiques : url:, method: (GET défaut), status_code: (liste de codes acceptés), return_content: true (capture la réponse), body: + body_format:, headers:.

  • Faire un GET simple et capturer la réponse JSON parsée.
  • Faire un POST avec body JSON automatiquement sérialisé.
  • Authentifier via Basic Auth ou Bearer token.
  • Accepter plusieurs codes de retour (200, 201, 204).
  • Faire un healthcheck avec until: + retries: + delay:.
  • Connaître les méthodes HTTP (GET, POST, PUT, DELETE) et les codes de retour (2xx, 4xx, 5xx).
  • Comprendre la structure d’un body JSON.
- name: Recuperer la derniere release Ansible
ansible.builtin.uri:
url: https://api.github.com/repos/ansible/ansible/releases/latest
method: GET
return_content: true
register: api_response
- name: Afficher la version
ansible.builtin.debug:
msg: "Derniere release : {{ api_response.json.tag_name }}"

Comportement :

  • return_content: true capture la réponse dans register.content (raw) ET register.json (parsé si Content-Type: application/json).
  • Pas besoin de from_json — Ansible parse automatiquement.
  • method: GET est le défaut — peut être omis.
- name: Creer une ressource via POST
ansible.builtin.uri:
url: https://httpbin.org/post
method: POST
body_format: json
body:
name: myapp
version: "1.0.0"
env: prod
status_code: [200, 201]
return_content: true
register: post_result

Détails :

  • body_format: json sérialise automatiquement le dict Ansible en JSON pour le body HTTP.
  • status_code: [200, 201] : la tâche réussit si le serveur retourne 200 OU 201. Sinon, failed.
  • Sans status_code:, le défaut est [200] — un 201 ferait failer la tâche.

Autres body_format: :

  • json — sérialise dict → JSON (le plus courant).
  • form-urlencoded — sérialise dict → key=value&key2=value2.
  • raw — body brut, vous gérez la sérialisation.
# Basic Auth (utilisateur/password)
- ansible.builtin.uri:
url: https://api.private.com/v1/resources
method: GET
url_username: "{{ vault_api_user }}"
url_password: "{{ vault_api_password }}"
force_basic_auth: true
return_content: true
# Bearer Token (OAuth, JWT, GitHub, GitLab)
- ansible.builtin.uri:
url: https://api.github.com/user
method: GET
headers:
Authorization: "Bearer {{ vault_github_token }}"
Accept: application/vnd.github+json
return_content: true

force_basic_auth: true envoie l’en-tête Authorization: Basic ... dès la première requête. Sans, Ansible attend un 401 du serveur avant de re-tenter avec auth (souvent OK, mais coûte un round-trip).

Secrets : toujours dans Ansible Vault.

Healthcheck applicatif (until: + retries: + delay:)

Section intitulée « Healthcheck applicatif (until: + retries: + delay:) »

Pattern classique : après déploiement d’une app, vérifier qu’elle répond avant de continuer.

- name: Demarrer myapp
ansible.builtin.systemd_service:
name: myapp
state: restarted
- name: Attendre que le port soit ouvert
ansible.builtin.wait_for:
port: 8080
host: 127.0.0.1
timeout: 30
- name: Verifier le healthcheck HTTP
ansible.builtin.uri:
url: http://localhost:8080/health
method: GET
status_code: 200
return_content: true
register: health
until: health.json.status == "ok"
retries: 5
delay: 2
- name: Afficher la version deployee
ansible.builtin.debug:
msg: "myapp version : {{ health.json.version }}"

until: + retries: + delay: = polling. Ansible relance la tâche jusqu’à ce que la condition soit vraie (max retries fois, avec delay secondes entre chaque essai). Idéal pour des services qui mettent quelques secondes à démarrer.

- name: Upload de config
ansible.builtin.uri:
url: https://api.private.com/v1/configs
method: POST
src: /tmp/myapp.yml
headers:
Authorization: "Bearer {{ vault_token }}"
Content-Type: application/yaml
status_code: [200, 201]

src: envoie le contenu du fichier comme body HTTP. Pour multipart/form-data : body_format: form-multipart (Ansible 2.10+).

CasModule
Télécharger un fichier (binaire, archive)get_url:
Télécharger avec checksumget_url:
Appeler une API REST (GET, POST, PUT, DELETE)uri:
Parser une réponse JSONuri: + register.json
Healthcheck HTTPuri: + until:
Upload de fichier vers APIuri: + src:

Règle : get_url: pour le téléchargement de fichiers (idempotence par checksum/ETag/taille). uri: pour toute interaction HTTP où la réponse compte autant que le statut.

SymptômeCauseFix
Tâche failed sur HTTP 201Défaut status_code: [200]Ajouter [200, 201]
register.json est nullContent-Type non JSONVérifier les headers ou parser manuellement avec from_json
Polling infiniCondition until: jamais vraieLimiter retries: à un maximum raisonnable
MITM ne déclenche pas d’erreurvalidate_certs: falseNe jamais désactiver TLS sauf cas dev
  • uri: = appels HTTP REST (GET, POST, PUT, DELETE).
  • return_content: true capture la réponse — JSON parsé automatiquement.
  • status_code: liste les codes acceptés (défaut [200]).
  • body_format: json sérialise un dict en JSON automatiquement.
  • Auth : url_username/url_password (Basic) ou headers: (Bearer).
  • until: + retries: + delay: = polling pour healthchecks.

Cette page a un lab d’accompagnement : labs/modules-reseau/uri/ dans stephrobert/ansible-training.

Challenge — sur db1.lab :

  1. GET sur https://httpbin.org/json + sauver la réponse.
  2. POST sur https://httpbin.org/post avec body JSON {name: rhce, version: 2026}.

Validation pytest+testinfra :

Fenêtre de terminal
ansible-playbook solution.yml
pytest -v labs/modules-reseau/uri/challenge/tests/

4 tests vérifient l’écriture des fichiers et le contenu JSON parsé.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn