Is it possible to install custom Ansible plugin from git - ansible

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.

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.utils.unsafe_proxy.AnsibleUnsafeT ext object' has no attribute

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 }}"

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

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] }}" }

Problem with creating consul cluster using ansible

I'm trying to create a Consul cluster using Ansible and i'm using this example https://github.com/brianshumate/ansible-consul .i'm using the vagrant file to up 3 Ubuntu machines
the problem is that the task Install unzip package seem to always fail,and it gives this error message:
fatal: [consul1.consul -> localhost]: FAILED! => {"changed": false, "msg": "Could not detect which package manager to use. Try gathering facts or setting the \"use\" option."}
Ansible seem unable to recognize the package manager,even though ansible localhost -m setup | grep mgr shows that the variable ansible_pkg_mgr has the value apt
i'm not sure what could be the source of the problem.i tried upping 3 debian machines and i still have the same problem.
UPDATE:
here's the task file for consul
---
# File: install.yml - package installation tasks for Consul
- name: Install OS packages
package:
name: "{{ item }}"
state: present
with_items: "{{ consul_os_packages }}"
tags: installation
- name: Read package checksum file
local_action:
module: stat
path: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
register: consul_checksum
tags: installation
- name: Download package checksum file
local_action:
module: get_url
url: "{{ consul_checksum_file_url }}"
dest: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
tags: installation
when: not consul_checksum.stat.exists | bool
- name: Read package checksum
local_action:
module: shell
grep "{{ consul_pkg }}" "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS" | awk '{print $1}'
become: no
run_once: true
register: consul_sha256
tags: installation
- name: Check Consul package file
local_action:
module: stat
path: "{{ role_path }}/files/{{ consul_pkg }}"
become: no
run_once: true
register: consul_package
tags: installation
- name: Download Consul package
local_action:
module: get_url
url: "{{ consul_zip_url }}"
dest: "{{ role_path }}/files/{{ consul_pkg }}"
checksum: "sha256:{{ consul_sha256.stdout }}"
timeout: "42"
become: no
run_once: true
tags: installation
when: not consul_package.stat.exists | bool
- name: Update alpine package manager (apk)
local_action:
module: apk
update_cache: yes
run_once: true
when: lookup('file','/etc/alpine-release')
- name: Install unzip package
local_action:
module: package
name: unzip
state: present
run_once: true
when:
- consul_install_dependencies | bool
- name: Unarchive Consul package
local_action:
module: unarchive
src: "{{ role_path }}/files/{{ consul_pkg }}"
dest: "{{ role_path }}/files/"
creates: "{{ role_path }}/files/consul"
become: no
run_once: true
tags: installation
- name: Install Consul
copy:
src: "{{ role_path }}/files/consul"
dest: "{{ consul_bin_path }}/consul"
owner: "{{ consul_user }}"
group: "{{ consul_group }}"
mode: 0755
tags: installation
- name: Daemon reload systemd in case the binaries upgraded
command: systemctl daemon-reload
become: yes
notify: restart consul
when:
- ansible_service_mgr == "systemd"
- consul_install_upgrade
- name: Cleanup
local_action: file path="{{ item }}" state="absent"
become: no
with_fileglob: "{{ role_path }}/files/consul"
run_once: true
tags: installation
The problem is with the Alpine package Manager,somehow it seem to cause an error with Ubuntu,so all what i did is use Apt instead of Apk.
here's the new version of the task file
---
# File: install.yml - package installation tasks for Consul
- name: Install OS packages
package:
name: "{{ item }}"
state: present
with_items: "{{ consul_os_packages }}"
tags: installation
- name: Read package checksum file
local_action:
module: stat
path: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
register: consul_checksum
tags: installation
- name: Download package checksum file
local_action:
module: get_url
url: "{{ consul_checksum_file_url }}"
dest: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
tags: installation
when: not consul_checksum.stat.exists | bool
- name: Read package checksum
local_action:
module: shell
grep "{{ consul_pkg }}" "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS" | awk '{print $1}'
become: no
run_once: true
register: consul_sha256
tags: installation
- name: Check Consul package file
local_action:
module: stat
path: "{{ role_path }}/files/{{ consul_pkg }}"
become: no
run_once: true
register: consul_package
tags: installation
- name: Download Consul package
local_action:
module: get_url
url: "{{ consul_zip_url }}"
dest: "{{ role_path }}/files/{{ consul_pkg }}"
checksum: "sha256:{{ consul_sha256.stdout }}"
timeout: "42"
become: no
run_once: true
tags: installation
when: not consul_package.stat.exists | bool
- name: Install unzip package
apt:
name: unzip
state: present
run_once: true
when:
- consul_install_dependencies | bool
- name: Unarchive Consul package
local_action:
module: unarchive
src: "{{ role_path }}/files/{{ consul_pkg }}"
dest: "{{ role_path }}/files/"
creates: "{{ role_path }}/files/consul"
become: no
run_once: true
tags: installation
- name: Install Consul
copy:
src: "{{ role_path }}/files/consul"
dest: "{{ consul_bin_path }}/consul"
owner: "{{ consul_user }}"
group: "{{ consul_group }}"
mode: 0755
tags: installation
- name: Daemon reload systemd in case the binaries upgraded
command: systemctl daemon-reload
become: yes
notify: restart consul
when:
- ansible_service_mgr == "systemd"
- consul_install_upgrade
- name: Cleanup
local_action: file path="{{ item }}" state="absent"
become: no
with_fileglob: "{{ role_path }}/files/consul"
run_once: true
tags: installation

Resources