Issue
Before patching a yum based Linux host using Ansible, I want to gather facts about packages currently installed and write the details to an http API.
The first task is to gather the facts and store it in a variable:
tasks:
- name: Gather installed packages
yum:
list: installed
register: installed_packages
The output of which looks like this:
[
{
"arch": "noarch",
"envra": "0:yum-3.4.3-168.el7.centos.noarch",
"epoch": "0",
"name": "yum",
"release": "168.el7.centos",
"repo": "installed",
"version": "3.4.3",
"yumstate": "installed"
},
{
"arch": "x86_64",
"envra": "0:zlib-1.2.7-19.el7_9.x86_64",
"epoch": "0",
"name": "zlib",
"release": "19.el7_9",
"repo": "installed",
"version": "1.2.7",
"yumstate": "installed"
}
]
My API expects additional fields; server_hostname
, server_ip_address
and review_id
and I need to add them into each element of the json array. I have tried using combine
and the best I can come up with is:
- name: Create empty list
set_fact:
list_two: []
- name: Add additional details to installed_packages fact
set_fact:
list_two: "{{ list_two + [item | combine ({ 'server_hostname': 'server-name','server_ip_address': '1.2.3.4','review_id': 'guid' })] }}"
with_items: "{{ installed_packages.results }}"
This is very slow on one of my development servers and hangs (and never finishes) on another development server.
How can I add these fields to the installed_packages
fact so it looks like the below and perform a POST using the uri
module.
[
{
"arch": "noarch",
"envra": "0:yum-3.4.3-168.el7.centos.noarch",
"epoch": "0",
"name": "yum",
"release": "168.el7.centos",
"repo": "installed",
"version": "3.4.3",
"yumstate": "installed",
"server_hostname": "server-name",
"server_ip_address": "1.2.3.4",
"review_id": "guid"
},
{
"arch": "x86_64",
"envra": "0:zlib-1.2.7-19.el7_9.x86_64",
"epoch": "0",
"name": "zlib",
"release": "19.el7_9",
"repo": "installed",
"version": "1.2.7",
"yumstate": "installed",
"server_hostname": "server-name",
"server_ip_address": "1.2.3.4",
"review_id": "guid"
}
]
Solution
This is quite hard to tell exactly why your current attempt with a loop is indeed failing, but here is an alternative way without a loop:
- debug:
msg: "{{ installed_packages.results | map('combine', _host_info) }}"
vars:
_host_info:
server_hostname: server-name
server_ip_address: 1.2.3.4
review_id: guid
Which you can, then, directly tailor in an uri
task, e.g.:
- ansible.builtin.uri:
url: https://httpbin.org/post
method: POST
body_format: json
body:
packages: "{{ installed_packages.results | map('combine', _host_info) }}"
vars:
_host_info:
server_hostname: server-name
server_ip_address: 1.2.3.4
review_id: guid
Answered By - β.εηοιτ.βε Answer Checked By - Gilberto Lyons (WPSolving Admin)