Ansible: installing roles in requirements file upon playbook execution - ansible

Vagrant has a very nice feature called galaxy_role_file that allows one to point to a requirements.yml file and to install the roles listed there upon vagrant up (provided that the vm is configured to use ansible provisioner).
My question is whether there is such an option in ansible itself, given that I was unable to find it available configurations.
or do we always have to explicitly type ansible-galaxy install -r requirements.yml before each first playbook execution?

Related

How can I install galaxy collections in awx?

I use a plugin such as nginx in ansible playbook.
https://galaxy.ansible.com/nginxinc/nginx_core
On server I can use cli to install the roles and collections as
ansible-galaxy collection install nginxinc.nginx_core
But how can I install it on AWX(Tower)?
I tried to run the command in one of AWX container - awx-ee (others are awx-web, awx-task, redis). When run a template in AWX, it still caused a role not found error.
In addition to #Zeitounator comment, you could also manually install your collection into a dedicated path (i.e into collections folder from awx directory)
If you use a requirements.yml file :
sudo -u awx_user ansible-galaxy collection install -r /var/lib/awx/projects/my_project/collections/requirements.yml -p /var/lib/awx/projects/my_project/collections
or manually
ansible-galaxy collection install ansible.my_collection -f
'/home/.ansible/collections/ansible_collections/ansible/my_collection'

dpkg-reconfigure openssh-server in ansible playbook

In an ansible (ver. 2.10) playbook I would need to invoke the dpkg-reconfigure openssh-server command to recreate SSH server keys.
- name: Create new SSH host's keys
shell: dpkg-reconfigure openssh-server
notify: restart sshd
The problem is that dpkg-reconfigure openssh-server opens a dialog box, and the script get stucked...
Looking into ansible documentation, it seems that dpkg-reconfigure can be managed by debconf module:
Code example related to locales module:
- name: Set default locale to fr_FR.UTF-8
debconf:
name: locales
question: locales/default_environment_locale
value: fr_FR.UTF-8
vtype: select
The question from openssh-server debconf module is: What do you want to do about modified configuration file sshd_config? and the answer would be: keep the local version currently installed.
How could I manage it using ansible debconf module?
This is not a debconf issue. The file is marked as a config file by Debian packaging and dpkg is handling it at a generic level. dpkg --configure has --force-confold but dpkg-reconfigure does not.
https://wiki.debian.org/ConfigPackages may also be useful.
TL;DR; Yes, use Ansible debconf but mv /var/lib/dpkg/info/<package>.config file aside whilst reconfiguring.
The rest of this is for others searching for insight into debconf and Ansible's debconf module.
I spent some time digging into this and have submitted some docs to the Ansible debconf module which I've edited a bit for this answer.
Reconfiguring packages in Debian using debconf is not straightforward!
The Ansible debconf module does not reconfigure packages, it just updates the debconf database. An additional playbook step is needed (typically via notify if debconf makes a change) to reconfigure the package and apply the changes.
Now debconf is primarily used for pre-seeding configuration prior to installation.
So, whilst dpkg-reconfigure does use debconf data, it is not always authoritative and you may need to check how your package is handled.
dpkg-reconfigure is a 3-phase process. It invokes the control scripts from the /var/lib/dpkg/info directory with the following arguments:
<package>.prerm reconfigure <version>
<package>.config reconfigure <version>
<package>.postinst control <version>
The main issue is that the <package>.config reconfigure step for many packages will first reset the debconf database (overriding changes made by the Ansible module) by checking the on-disk configuration. If this is the case for your package then dpkg-reconfigure will effectively ignore changes made by this debconf module.
However although dpkg-reconfigure finally invokes:
/var/lib/dpkg/info/<package>.postinst configure <version>
to actually configure the package; using this turns out not to be that simple. The script is expected to be run from a "debconf frontend" and uses IPC to respond to the _db_cmd statements in the script.
To see this in more detail
export DPKG_MAINTSCRIPT_PACKAGE=<package>
export DPKG_MAINTSCRIPT_NAME=<script path>
export DEBIAN_HAS_FRONTEND=1
and run the script. I was trying to setup unattended-upgrades so I ran:
sh -x /var/lib/dpkg/info/unattended-upgrades.postinst configure 1.11.2
This then halts waiting for a response from the frontend.
Running
/usr/share/debconf/frontend /var/lib/dpkg/info/unattended-upgrades.postinst configure 1.11.2
works... but has the exact same problem as dpkg-reconfigure - it resets the debconf database :(
This is because running
/var/lib/dpkg/info/unattended-upgrades.postinst configure 1.11.2
sources /usr/share/debconf/confmodule which exec()s /usr/share/debconf/frontend which forces the <package>.config configure phase to take place.
This is done based on the existence (ie using shell [-e]) of the .config file and cannot be avoided.
The solution is to mv /var/lib/dpkg/info/<package>.config out of the way whilst dpkg-reconfigure (or other related debconf code) runs.
Note the Debian programmers manual says that the config script's sole purpose is to populate debconf and must not affect other files; so doing this in a playbook is (to my understanding) compliant with debian policy: http://www.fifi.org/doc/debconf-doc/tutorial.html#AEN113
HTH
I also had this problem and I want to share my workaround.
In my case, I want non-root users to be able to sniff network traffic with wireshark/tshark. The package in question is wireshark-common which I normally reconfigure to modify dumpcap as setuid.
In my playbook, I do the following. First, use debconf to modify the config and than run the dpkg-reconfigure command in non-interactive mode, but only if the config has changed.
- name: wireshark setuid
ansible.builtin.debconf:
name: wireshark-common
question: wireshark-common/install-setuid
value: yes
vtype: boolean
register: reconfigure_changed
- name: make debconf changes active
ansible.builtin.command:
cmd: "dpkg-reconfigure wireshark-common"
environment:
DEBIAN_FRONTEND: noninteractive
when: reconfigure_changed.changed
Hope this is helpful.
I am looking myself for a solution but I haven't found one yet to achieve that with debconf and ansible.
The Problem is, debconf has no "selection" in terms of sshd_config.
When you look for debconf and preseed (Debian unattended installation) there is simply no Argument where you can specify to keep the current sshd_config.
for example active debconf settings:
sudo debconf-show openssh-server
openssh-server/permit-root-login: false
openssh-server/password-authentication: false
These are the questions for the ansible debconf module.
what we are looking for, but thats not possible:
- debconf:
name: openssh-server
question: openssh-server/keep-current-sshd-config
value: true
Unfortunately, we have to find a workaround.
For my case, I wanted to reconfigure openssh-server on my raspberry pi's
Luckily, there is a systemd file on raspbian OS /lib/systemd/system/regenerate_ssh_host_keys.service that does what the name says.
To make use of it, just delete the ssh_host_* files and reboot the machine.
If you need to get that for different hosts, you need to find another workaround. Maybe importing new ssh_host key files via ansible, or build a small script.

How do I install an Ansible Galaxy role from a tar.gz file?

I have seen a number of sites that explain how to install a role from a tar.gz file using ansible-galaxy, and they all seem to say the same thing.
In my case I have downloaded the following role file from ansible galaxy :
dsglaser-cis_security-1.2.0.tar.gz
Then I tried to install the role:
ansible-galaxy collection install dsglaser-cis_security-1.2.0.tar.gz
which gives me the warning :
[WARNING]: - collection was NOT installed successfully: Failed to get data from the API server (https://galaxy.ansible.com/api/): Failed to connect to galaxy.ansible.com at port 443: [Errno 104] Connection reset by peer
This is correct, because this machine is not, and never will be connected to the internet.
Another attempt :
ansible-galaxy install dsglaser-cis_security-1.2.0.tar.gz
results in another warning:
[WARNING]: - dsglaser-cis_security-1.2.0.tar.gz was NOT installed successfully: the specified roles path exists and is not a directory.
Also tried using the -p option to indicate where I want the role to be installed, with and without the directory present, but every attempt resulted in the last warning.
I'm not doing this as root...
Ansible version is 2.8.13
Just discovered that the command
ansible-galaxy install dsglaser-cis_security-1.2.0.tar.gz -p ./bla
does work, but only as root. And that's not what I want...
What am I doing wrong ?
I have been banging my head against the wall on this one for a while. I found that the collections I am trying to install have dependencies, that are not included in the tar.gz file.
This makes galaxy go out to download the files not found.
The way to get around this is by using another machine with ansible (2.10+) and transferring the files over.
Once you have ansible installed on a machine with internet use the following command
ansible-galaxy collection download {{ name of collection, if multiple use space as a separator }}
i.e.
ansible-galaxy collection download cisco.ios cisco.asa
This will create a folder in your current working directory with a tar.gz of the collection and its dependencies, as well as a requirements.yml file.
Note: with the requirements.yml file, if you re-run the download command, it will overwrite this, so if you have multiple collections use the single line command above.
Then it's just a matter of copying that folder over to the offline ansible server (2.9+), cd to that directory, and run:
ansible-galaxy collection install -r requirements.yml
Bobs your uncle.
I hope this saves someone time.
Thanks goes to this reddit post on the same topic
https://www.reddit.com/r/ansible/comments/lh1do0/ansible_newbie_trying_to_install_an_ansible/
AFAIK, installation from archives was never support for roles but was supported for collections.
For roles you are stuck with installation from git URLs.
This alone is a good-enough reason for me to avoid using old standalone roles, especially as support for them in galaxy is minimal, no new features being added (like install from tar archives).

how to get commands from ansible playbook

Is there a simple way how to get back what precisely ansible script(playbook) is trying to do?
E.g. I have
- name: Install required packages
yum: name={{item}} state=present
with_items:
- nmp
become: True
And I want to get:
sudo yum install nmp
That said, I want to know what commands (OS level) ansible is running.
Basically, I need the reverse process to: Ansible and Playbook. How to convert shell commands into yaml syntax?
Summarizing here the central points from comments above [1][2].
Ansible rarely runs external commands, it's mostly Python code & Python libraries being used to control hosts. Therefor, Ansible's "translation" isn't necessarily converting yum (Ansible module) usage into yum (CLI) invocations.
While you may be able to depend on the output, in some cases, by parsing for command sequences in the output of ansible-playbook -vvv foo.yml - the implementation would be flaky at best.
I'd encourage you to keep discussing on this thread what you're trying to accomplish. It's likely there is already a solution, and someone can point you to a tool that already exists.

Best way to manage local changes to Ansible Galaxy role

I am fairly new to Ansible. I am using a couple of Ansible roles that need some tweaking of specific tasks to work on CentOS 7. What is the best workflow to handle local changes to Ansible-Galaxy roles?
Here are the options I am considering:
Fork the role and make change. Downside is that I would lose the ability to grab dependencies by running Ansible-Galaxy install -r requirements.txt
File an issue with the developer on github. Downside is they may never accept my change or may take several days/weeks.
Make changes locally. Downside is I wont be able to update roles from galaxy without losing my local changes.
After reading the documentation for the ansible-galaxy command I realized I could be pointed directly at my github fork and not affect the ability to grab dependencies using Ansible-Galaxy install -r requirements.txt.
Example: Adding a github repo to requirements.yml:
# from GitHub
src: https://github.com/bennojoy/nginx

Resources