ansible.utils.unsafe_proxy.AnsibleUnsafeT ext object' has no attribute - ansible

I am trying to modify and use this httpd ansible role https://github.com/CentOS/ansible-role-httpd
I'm facing an issue with pki-tls.yml
This piece of code will reproduce the issue I am facing.
---
- name: Copy certificates
hosts: myhost.domain.com
remote_user: user
become: yes
vars:
httpd_vhost_shared_list:
- name: emacs
fqdn: domain.com
path: /var/www/emacs
acl:
- 10.10.40.0/24
pkistore: /home/user/certificates
tasks:
- name: Debug
debug:
var: httpd_vhost_shared_list
- name: TLS certs
copy:
src: "{{ pkistore }}/{{ item.name }}"
dest: "/etc/pki/tls/certs/{{ item.name }}"
with_items:
- "{{ httpd_vhost_shared_list }}.crt"
- "{{ httpd_vhost_shared_list }}-CAChain.crt"
- name: TLS key
copy:
src: "{{ pkistore }}/{{ item.name }}"
dest: "/etc/pki/tls/private/{{ item.name }}"
with_items:
- "{{ httpd_vhost_shared_list }}.key"
When I run my playbook, I get the following error:
The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeT
ext object' has no attribute 'name'
However the variable is defined. How would one do to access name in variable httpd_vhost_shared_list?
Any feedback is welcome.

In the meantime, I figured out it is simple to split the play "TLS certs" in 2 plays. One for the server certificate and another one for chain certificate.
- name: TLS certificate
copy:
src: "{{ pkistore }}/{{ item.name }}.crt"
dest: "/etc/pki/tls/certs/{{ item.name }}.crt"
with_items:
- "{{ httpd_vhost_shared_list }}"
- name: TLS chain
copy:
src: "{{ pkistore }}/{{ item.name }}-CAChain.crt"
dest: "/etc/pki/tls/certs/{{ item.name }}-CAChain.crt"
with_items:
- "{{ httpd_vhost_shared_list }}"
- name: TLS key
copy:
src: "{{ pkistore }}/{{ item.name }}.key"
dest: "/etc/pki/tls/private/{{ item.name }}.key"
with_items:
- "{{ httpd_vhost_shared_list }}"

Related

Ansible - Recursive copy

I'm trying to copy the content of my directories (located on my bastion) on a server but it doesn't work.
I tried with "with_fileglob:", "with_items:" but each times, I had the error :
"'item' is undefined"
I don't understand why.
Ths is my code which doesn't work:
tasks:
- name: Copy directories...
copy:
src: "{{ item }}"
dest: "{{ dir_dest }}/"
owner: "{{ dir_owner }}"
group: "{{ dir_group }}"
mode: '0755'
with_fileglob:
- /home/ansible/delivery/my_dir/*
whereas this one works :
tasks:
- name: Copy directories...
copy:
src: "/home/ansible/delivery/my_dir/"
dest: "{{ dir_dest }}/"
owner: "{{ dir_owner }}"
group: "{{ dir_group }}"
mode: '0755'
But I can't use this 2nd solution because I have a lot a directories to copy.
Thank for your help.
tasks:
- name: Copy directories...
copy:
src: "{{ item }}"
dest: "{{ dir_dest }}/"
owner: "{{ dir_owner }}"
group: "{{ dir_group }}"
mode: '0755'
with_fileglob:
- /home/ansible/delivery/my_dir/*
Try this.

Ansible when condition always evaluates as false

I have been trying to get this conditional to work for a few hours now.
The solution is eluding me.
The "when" is always evaluating as false.
This is confusing as template/src works perfectly.
- name: Copy PHP Pool Config
template:
src: "{{ src_conf }}"
dest: /etc/php/{{ php_version }}/fpm/pool.d/{{ user.name }}.conf
mode: u=rw,g=r,o=r
with_flattened:
- "{{ users|default([]) }}"
notify: reload PhpFpm
vars:
user: "{{ item }}"
src_conf: "../files/etc/php/fpm/pool.d/{{ group_names | first }}/{{ user.name }}.conf"
tags:
- php
when: src_conf is exists
This works as expected if I remove the "when".
The issue is not all "{{ user.name }}.conf" files exist.
Does "when: src_conf is exists" search in different place?
Update:
I also tried it with location_action, but it still resulted in false.
- name: Copy PHP Pool Config files
local_action: stat path="../../files/etc/php/fpm/pool.d/{{ group_names | first }}/{{ user.name }}.conf"
register: phpPools
with_flattened:
- "{{ users|default([]) }}"
become: no
vars:
user: "{{ item }}"
tags:
- php
- name: Copy PHP Pool Config
template:
src: item.invocation.module_args.path
dest: /etc/php/{{ php_version }}/fpm/pool.d/{{ user.name }}.conf
mode: u=rw,g=r,o=r
with_flattened:
- "{{ phpPools.results }}"
notify: reload PhpFpm
vars:
user: "{{ item.item }}"
tags:
- php
when: item.stat.exists == true

In Ansible loop, test existence of files from registered results

I have several files that I need to backup in different directories. I have tried the code below and not working for me.
vars:
file_vars:
- {name: /file1}
- {name: /etc/file2}
- {name: /etc/file/file3}
tasks:
- name: "Checking if config files exists"
stat:
path: "{{ item.name }}"
with_items: "{{ file_vars }}"
register: stat_result
- name: Backup Files
copy: src={{ item.name }} dest={{ item.name }}{{ ansible_date_time.date }}.bak
with_items: "{{ file_vars }}"
remote_src: yes
when: stat_result.stat.exists == True
The problem is the condition
when: stat_result.stat.exists == True
There is no attribute stat_result.stat. Instead, the attribute stat_result.results is a list of the results from the loop. It's possible to create a dictionary of files and their statuses. For example
- set_fact:
files_stats: "{{ dict(my_files|zip(my_stats)) }}"
vars:
my_files: "{{ stat_result.results|json_query('[].item.name') }}"
my_stats: "{{ stat_result.results|json_query('[].stat.exists') }}"
Then simply use this dictionary in the condition
when: files_stats[item.name]
Below is a shorter version which creates the dictionary more efficiently
- set_fact:
files_stats: "{{ dict(stat_result.results|
json_query('[].[item.name, stat.exists]')) }}"
Please try using below worked for me:
---
- name: Copy files
hosts: localhost
become: yes
become_user: root
vars_files:
- files.yml
tasks:
- name: "Checking if config files exists"
stat:
path: "{{ item }}"
with_items: "{{ files }}"
register: stat_result
- name: Ansible
debug:
msg: "{{ stat_result }}"
- name: Backup Files
copy:
src: "{{ item }}"
dest: "{{ item.bak }}"
with_items: "{{ files }}"
when: stat_result == "True"
and files.yml will look like:
---
files:
- /tmp/file1
- /tmp/file2
you can check you playbook syntax using below command:
ansible-playbook copy.yml --syntax-check
Also you do dry run your playbook before actual execution.
ansible-playbook -i localhost copy.yml --check

Is it possible to install custom Ansible plugin from git

I'd like to share a custom inventory plugin across multiple playbooks and users.
Is it possible to host a custom inventory plugin on git and the like roles with requirements.yml do something like:
ansible-galaxy install -r requirements.yml
I tried to embbed it in a role using:
/myrole/library/inventory_plugins/custom_inventory.py
/myrole/plugins/inventory_plugins/custom_inventory.py
/myrole/inventory_plugins/custom_inventory.py
but so far no luck.
Q: "Is it possible to install custom Ansible plugin from git?"
A: Yes. It's possible. For example
1) Download and extract the plugins
vars:
ma_src_path: "/usr/local/ansible/src"
ma_plugins_path: "/usr/local/ansible/plugins"
map_mitogen_ver: 0.2.8
map_mitogen_sha256: "sha256:1bfca66bcc522346c9167a3a9829feac5ee3b84431e49354fb780e4b9a4b0eee"
ma_plugins:
- archive: mitogen-{{ map_mitogen_ver }}.tar.gz
archive_url: https://networkgenomics.com/try/mitogen-{{ map_mitogen_ver }}.tar.gz
checksum: "{{ map_mitogen_sha256 }}"
plugins:
- path: mitogen-{{ map_mitogen_ver }}/ansible_mitogen/plugins/strategy
ini_key: strategy_plugins
enable: true
tasks:
- name: "plugins: Download archives"
get_url:
url: "{{ item.archive_url }}"
dest: "{{ ma_src_path }}"
checksum: "{{ item.checksum }}"
loop: "{{ ma_plugins }}"
- name: "plugins: Extract archives"
unarchive:
src: "{{ ma_src_path }}/{{ item.archive }}"
dest: "{{ ma_plugins_path }}"
loop: "{{ ma_plugins }}"
2) Configure the plugins with template ansible-plugins.cfg.j2
vars:
ma_config:
- path: "/etc/ansible/ansible.cfg"
template: "ansible-plugins.cfg.j2"
owner: "root"
group: "root"
mode: "0644"
config:
- { section: "defaults", key: "inventory", value: "/etc/ansible/hosts" }
- { section: "defaults", key: "strategy", value: "mitogen_linear" }
tasks:
- name: "configure: Ansible configuration from template"
template:
src: "{{ item.template }}"
dest: "{{ item.path }}"
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
backup: "{{ ma_backup_conf }}"
loop: "{{ ma_config }}"
when: ma_config|length > 0
See the complete role at Ansible Galaxy.

Ansible write result command to local file with loop

I've write ansible-playbook to collect the result from many network devices. Below playbook is working fine. But if I have to collect result with lot of commands. Let say 20 commands, I've to create the many task to write the results into file in my playbook.
For now, I manually create the tasks to write to logs into file. Below is example with 3 commands.
- name: run multiple commands and evaluate the output
hosts: <<network-host>>
gather_facts: no
connection: local
vars:
datetime: "{{ lookup('pipe', 'date +%Y%m%d%H') }}"
backup_dir: "/backup/"
cli:
host: "{{ ansible_host }}"
username: <<username>>
password: <<password>>
tasks:
- sros_command:
commands:
- show version
- show system information
- show port
provider: "{{ cli }}"
register: result
- name: Writing output
local_action:
module: lineinfile
dest: "{{ backup_dir }}/{{ inventory_hostname }}-{{ datetime }}.txt"
line: "{{ inventory_hostname }}:# show version\n{{ result.stdout[0] }}"
create: yes
changed_when: False
- name: Writing output
local_action:
module: lineinfile
dest: "{{ backup_dir }}/{{ inventory_hostname }}-{{ datetime }}.txt"
line: "{{ inventory_hostname }}:# show system information\n{{ result.stdout[1] }}"
create: yes
changed_when: False
- name: Writing output
local_action:
module: lineinfile
dest: "{{ backup_dir }}/{{ inventory_hostname }}-{{ datetime }}.txt"
line: "{{ inventory_hostname }}:# show port\n{{ cmd_result.stdout[2] }}"
create: yes
changed_when: False
Is it possible to loop commands and result within one task?
Please kindly advice.
Thanks
try this one task alone in place above three tasks..
- name: Writing output
local_action:
module: lineinfile
dest: "{{ backup_dir }}/{{ inventory_hostname }}-{{ datetime }}.txt"
line: "{{ inventory_hostname }}:# show {{ item.command }}\n{{ cmd_result.stdout{{ item.outnum }} }}"
create: yes
changed_when: False
with_items:
- { command: version, outnum: [0] }
- { command: system information, outnum: [1] }
- { command: port, outnum: [2] }
Below playbook is worked for me
- name: Writing output
local_action:
module: lineinfile
dest: "{{ backup_dir }}/{{ inventory_hostname }}-{{ datetime }}.txt"
line: "{{ inventory_hostname }}:# show {{ item.command }}\n{{ item.cmdoutput}}"
create: yes
changed_when: False
with_items:
- { command: "version", cmdoutput: "{{ cmd_result.stdout[0] }}" }
- { command: "system information", cmdoutput: "{{ cmd_result.stdout[1] }}" }
- { command: "port", cmdoutput: "{{ cmd_result.stdout[2] }}" }

Resources