Ansible include task and loop register different result - ansible

I'm trying to use a module as an included task so I can loop several items and register the credentials in a variable.
Files:
main.yml:
---
- hosts: localhost
gather_facts: False
tasks:
- include: tasks/myvault/get-vault.yml
with_items:
- demo
register: output
- debug:
msg: "{{output}}"
get-vault.yml:
- name: Retrieve secret from Vault
community.hashi_vault.vault_kv2_get:
url: https://myvaul
path: "{{ item }}"
auth_method: token
token: '{{ mytoken }}'
namespace: MyNamespace
validate_certs: no
output:
ok: [localhost] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"include": "tasks/myvault/get-vault.yml",
"include_args": {},
"item": "demo"
}
],
"skipped": false
}
}
The output doesn't display the "real" result of the task.
If I remove:
register: output and put it in get-vault.yml, here is the result:
ok: [localhost] => {
"msg": {
"changed": false,
"data": {
"data": {
"password": "Password",
"username": "Username"
}, ...
How can I get this result returned when I register the output from my included task?

Related

How to check the size of a file list

With Ansible, I need to check if files in directory are bigger than 50M.
I do a set_fact with result of ls and then I loop to stat all files. This works, but I am not able to parse the result to create a fail condition when files are bigger than 50M.
I do this :
- shell: ls -1 "{{ logs_directory }}"*.log
register: list_logs
- set_fact:
list_logs: "{{ list_logs.stdout_lines }}"
- debug:
msg: "{{ list_logs}}"
- name: Get size
stat:
path: "{{ item }}"
with_items: "{{ list_logs }}"
register: size_log
- name: debug
fail:
msg: "Problem with log size > 50M"
when: 'size_log.stat.size / 1024 / 1024 | int > 50'
It works if I have only 1 file, but with multiple servers and multiple files, it doesn't work... How to parse the size_log_result?
Here an example of output size_log :
ok: [192.168.1.2] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/admin.log"
}
},
"item": "/var/logs/admin.log",
"stat": {
"size": 21711,
}
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/database.log"
}
},
"item": "/var/logs/database.log",
"stat": {
"size": 11162,
}
}
]
}
}
ok: [192.168.1.5] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/database.log"
}
},
"item": "/var/logs/database.log",
"stat": {
"size": 128453958,
}
}
]
}
}
It looks to me like you are reinventing the wheel here, when the find module seems to answer you use case perfectly already.
Given:
- hosts: localhost
gather_facts: no
tasks:
####
## You do not need this task, it is just to create a file
## big enough for demonstration purpose
####
- community.general.filesize:
path: /var/log/heavy.log
size: 51m
- find:
paths: /var/log
patterns: '*.log'
size: 51m
register: _logs
- fail:
msg: >-
Due to file(s): {{
_logs.files | map(attribute='path') | join(', ')
}}
when: _logs.files | length > 0
This will yield:
TASK [community.general.filesize] *********************************
ok: [localhost]
TASK [find] *******************************************************
ok: [localhost]
TASK [fail] *******************************************************
fatal: [localhost]: FAILED! => changed=false
msg: 'Due to file(s): /var/log/heavy.log'

ansible task doesn't resolve variable

I'm trying to get VG_Name using below code. I can see variable value using debug:var but it doesn't work inside actual task & print value as "vg": "hostvars[inventory_hostname].ansible_lvm.lvs.varlog.vg"
tasks:
- set_fact:
LV_name: "opt"
- name: Get VG Name
set_fact:
vg_command: "{{ 'hostvars[inventory_hostname].ansible_lvm.lvs.'+ LV_name +'.vg' }}"
- name: Show VG
debug:
var: "{{ vg_command }}"
- name: extend logical volume and file system
community.general.lvol:
vg: "{{ vg_command }}"
lv: "{{ LV_name }}"
size: +100%FREE
resizefs: yes
Output:
TASK [Get VG Name] *********************************************************************************************************************************************************************************
task path: /root/ansible_disk/disk_extend.yml:92
ok: [SERVER-NAME] => {
"ansible_facts": {
"vg_command": "hostvars[inventory_hostname].ansible_lvm.lvs.varlog.vg"
},
"changed": false
}
TASK [Show VG] *************************************************************************************************************************************************************************************
task path: /root/ansible_disk/disk_extend.yml:96
ok: [SERVER-NAME] => {
"hostvars[inventory_hostname].ansible_lvm.lvs.varlog.vg": "vg_00"
}
TASK [extend logical volume and file system] *******************************************************************************************************************************************************
task path: /root/ansible_disk/disk_extend.yml:109
fatal: [SERVER-NAME]: FAILED! => {
"changed": false,
"err": " Volume group name \"hostvars[inventory_hostname].ansible_lvm.lvs.varlog.vg\" has invalid characters.\n Cannot process volume group hostvars[inventory_hostname].ansible_lvm.lvs.varlog.vg\n",
"invocation": {
"module_args": {
"active": true,
"force": false,
"lv": "varlog",
"opts": null,
"pvs": null,
"resizefs": true,
"shrink": true,
"size": "+100%FREE",
"snapshot": null,
"state": "present",
"thinpool": null,
"vg": "hostvars[inventory_hostname].ansible_lvm.lvs.varlog.vg"
}
},
"msg": "Volume group hostvars[inventory_hostname].ansible_lvm.lvs.varlog.vg does not exist.",
"rc": 5
}
Tried all possible ways(lookup, vars etc) that I could think of but no luck, any help would be appreciated!
You are building your string incoorectly, leaving inventory[hostname] inside the single quotes, it will be treated as a literal; so:
vg_command: "{{ 'hostvars[inventory_hostname].ansible_lvm.lvs.'+ LV_name +'.vg' }}"
should instead be:
vg_command: "{{ hostvars[inventory_hostname].ansible_lvm.lvs[LV_name].vg }}"

Ansible getent module's loop output results parsing

I am trying to check if a number of users are present or not in the managed node using getent module and create a list of users who are not present.
The piece of code is:
- getent:
database: passwd
key: "{{ item }}"
fail_key: no
register: x
loop:
- "user1"
- "user2"
- debug: var=x.results
- set_fact:
fail_list: "{{ x.results | }}"
I am stuck at this point.
Is there any way I can save the users who are not present to the variable fail_list as a list?
In the above example, user1 is not present and user2 is present in the managed node.
The ansible version I am using is 2.9 and the debug output is a list of dicts as below:
"x.results": [
{
"ansible_facts": {
"getent_passwd": {
"user1": null
}
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": false,
"key": "user1",
"service": null,
"split": null
}
},
"item": "user1",
"msg": "One or more supplied key could not be found in the database."
},
{
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python",
"getent_passwd": {
"user2": [
"x",
"0",
"0",
"user2",
"/home/user2",
"/bin/bash"
]
}
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": false,
"key": "user2",
"service": null,
"split": null
}
},
"item": "user2"
},
Run getent once and search the list of users. For example
- hosts: localhost
tasks:
- getent:
database: passwd
- debug:
msg: User {{ item }} exists.
loop:
- root
- user1
- user2
when: item in my_users
vars:
my_users: "{{ getent_passwd.keys()|list }}"
gives
ok: [localhost] => (item=root) => {
"msg": "User root exists."
}
skipping: [localhost] => (item=user1)
skipping: [localhost] => (item=user2)

How can loop items as input parameters to a ansible role

I am trying to convert an existing ansible playbook (for extracting the webpage content of multiple webpage URL's in parallel fashion) to re-usable roles. I need the role to accept variables in a loop and produce the output for all the items in a single task which my current playbook is able to do. But the current role is only able to produce the output of the last item in the loop
I have tried registering the webpage content inside and outside the roles but of no use. And also looping the response results with_items same as of the role is producing results for non-200 values
FYI I got the expected output by including the loop inside the role but it's defeating the purpose of maintaining a role for GET call because I will not need a loop every time for the GET call. So I am expecting to loop the role in the testplaybook.yml.
Test-Role: main.yml
uri:
url: "{{ URL_Variable }}"
method: GET
status_code: 200
return_content: yes
register: response
ignore_errors: true
testplaybook.yml:
- hosts: localhost
gather_facts: true
tasks:
- name: Include roles
include_role:
name: Test-Role
vars:
URL_Variable: "http://{{ item }}:{{ hostvars[groups['group1'][0]]['port'] }}/{{ hostvars[groups['group1'][0]]['app'] }}/"
with_items: "{{ groups['group1'] }}"
- name: "Display content"
debug:
var: response.results
Expected Output:
response.results:
ok: [127.0.0.1] => (item=[0, 'item1']) => {
"ansible_loop_var": "item",
"item": [
0,
"item1"
],
"response": {
"accept_ranges": "bytes",
"changed": false,
"connection": "close",
"content": "content1",
"content_length": "719",
"content_type": "text/html",
"cookies": {},
"failed": false,
"msg": "OK (719 bytes)",
"redirected": false,
"server": "42",
"status": 200,
"url": "http://item1:port/app/"
}
}
ok: [127.0.0.1] => (item=[1, 'item2']) => {
"ansible_loop_var": "item",
"item": [
1,
"item2"
],
"response": {
"accept_ranges": "bytes",
"changed": false,
"connection": "close",
"content": "content2",
"content_length": "719",
"content_type": "text/html",
"cookies": {},
"failed": false,
"msg": "OK (719 bytes)",
"redirected": false,
"server": "42",
"status": 200,
"url": "http://item2:port/app/"
}
}
try this Test-Role: main.yml file:
- uri:
url: "{{ URL_Variable }}"
method: GET
status_code: 200
return_content: yes
register: response
ignore_errors: true
- name: Add response to responses array
set_fact:
responses_results: "{{ responses_results | default([]) + [{'URL': URL_Variable, 'response': response.content}] }}"
this works with include_tasks, i assume it would work with include_role as well, the variable responses_results should persist across roles assuming its in the same play. if not works, try to switch your code to a single role instead, with an include_tasks.
hope it helps

Fetch doesn't transfer when i use variable

fetch module does not transfer file when i use variable and getting message as "msg": "the remote file does not exist, not transferring, ignored". But file exits in the source directory. Please suggest if anything wrong in this.
ansible 2.1.0.0
---
- hosts: host_A
become_user: yes
gather_facts: no
tasks:
- name: list files
shell: ls -1 /root/stuff/install.1_comiskey-v01
register: dumpfiles
-debug: var=dumpfiles
- name: fetch files
fetch: src={{item}} dest=/tmp/fetched/ flat=yes
with_items: ('{{dumpfiles.stdout_lines}}')
register: test
- debug: var=test
Output:
TASK [fetch files]
*************************************************************
ok: [10.1.31.82] => (item=('[u'/root/stuff/install.1_comiskey-v01',u'/root/stuff/install.1_comiskey-v02']'))
TASK [debug] *******************************************************************
ok: [10.1.31.82] => {
"test": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"changed": false,
"file": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')",
"invocation": {
"module_args": {
"dest": "/tmp/fetched/",
"flat": "yes",
"src": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')"
},
"module_name": "fetch"
},
"item": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')",
"msg": "the remote file does not exist, not transferring, ignored"
}
]
}
}
Remove parentheses from with_items. You can note that item variable is not correct on your debug output.

Categories

Resources