Ansible Yum Module pending transactions error - ansible

I'm very new to Ansible.
I am trying to follow a tutorial on the concept of Roles in Ansible.
I have the following Master Playbook:
--- # Master Playbook for Webservers
- hosts: apacheweb
user: test
sudo: yes
connection: ssh
roles:
- webservers
Which refers to the webservers role that has the following task/main.yml:
- name: Install Apache Web Server
yum: pkg=httpd state=latest
notify: Restart HTTPD
And a handler/main.yml:
- name: Restart HTTPD
service: name=httpd state=started
When I execute the Master Playbook, mentioned above, I get the following error:
TASK [webservers : Install Apache Web Server] **********************************
fatal: [test.server.com]: FAILED! => {"changed": false, "failed": true, "msg": "The following packages have pending transactions: httpd-x86_64", "rc": 128, "results": ["The following packages have pending transactions: httpd-x86_64"]}
I cannot understand what this error corresponds to. There does not seem to be anything similar, based on my research, that could suggest the issue with the way I am using the Yum module.
NOTE: Ansible Version:
ansible 2.2.1.0
config file = /etc/ansible/ansible.cfg

It seems there are unfinished / pending transactions on the target host.
Try installing yum-utils package to run yum-complete-transaction to the target hosts giving the error.
# yum-complete-transaction --cleanup-only
Look at Fixing There are unfinished transactions remaining for more details.
yum-complete-transaction is a program which finds incomplete or
aborted yum transactions on a system and attempts to complete them. It
looks at the transaction-all* and transaction-done* files which can
normally be found in /var/lib/yum if a yum transaction aborted in the
middle of execution.
If it finds more than one unfinished transaction it will attempt to
complete the most recent one first. You can run it more than once to
clean up all unfinished transactions.

Unfinished transaction remaining
sudo yum install yum-utils
yum-complete-transaction --cleanup-only

I am using for ansible this type of config for the playbooks:
- name: Install Apache Web Server
yum: name=httpd state=latest
notify: Restart HTTPD
As far as i know there is no such option as yum: pkg=httpd in ansbile for the yum module (if I'm not wrong, that pkg=httpd is for apt-get on debian based distros)
If you need to install multiple packages you could use something like:
- name: "Install httpd packages"
yum: name={{ item }} state=present
with_items:
- httpd
- httpd-devel
- httpd-tools
Of course you can change the state=present to state=latest or whatever option might suits you best
http://docs.ansible.com/ansible/yum_module.html - ansible documentation for yum module

Related

Install apache2 sqlite3 git - Ansible Loop

I have read all the similar questions here and yet I don't see a solution that fixed my issue.
This is my code:
---
- name: install apache2, sqlite3, git
tasks:
- name: Install list of packages
apt:
name: "{{ item }}"
state: installed
with_items:
- apache2
- sqlite3
- git
Here is the error:
ERROR! unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>
The error appears to be in '/projects/challenge/fresco_loops/tasks/main.yml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- name: install apache2, sqlite3, git
^ here
I am not really an ansible expert and this is just one of the trainings we have to take. Thank you in advance.
firstly the best way to install multiple packages is shown below:
---
- name: install apache2, sqlite3, git
hosts: localhost # run locally
become: yes
tasks:
- name: Install list of packages
apt:
state: present
name:
- apache2
- sqlite3
- git
And a couple of final points:
"installed" is not a valid option for apt, try "present".
package installation requires sudo (become: yes).
To run the code above, which is locally on the node where the playbook sits, you need to use the command: ansible-playbook playbook.yml --ask-become-pass and enter the sudo password when prompted.
Secondly when I tried to run your code I got the following error
[DEPRECATION WARNING]: Invoking "apt" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['apache2', 'sqlite3',
'git']` and remove the loop. This feature will be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
failed: [localhost] (item=['apache2', 'sqlite3', 'git']) => {"ansible_loop_var": "item", "changed": false, "item": ["apache2", "sqlite3", "git"], "msg": "value of state must be one of: absent, build-dep, fixed, latest, present, got: installed"}
When using Ansible 2.9.6, if you are using a different version that might explain it? Its always worth telling people what version you are using, in case the problem is version-specific.
Otherwise your code snippet is not representative of what is actually giving you the error.

package installation not considered in playbook

I got some trouble with automating an installation using ansible.
I use this role (https://github.com/elastic/ansible-elasticsearch) to install elasticsearch on my ubuntu 16.04 server.
The role depends on the package python-jmespath, as mentioned in the documentation.
The role DOES NOT install the package itsself, so i try to install it before role execution.
- hosts: elasticsearch_master_servers
become: yes
tasks:
- name: preinstall jmespath
command: "apt-get install python-jmespath"
- name: Run the equivalent of "apt-get update" as a separate step
apt:
update_cache: yes
- hosts: elasticsearch_master_servers
become: yes
roles:
- role: elastic.elasticsearch
vars:
...
When running the playbook i expect the python-jmespath package to be installed before execuction of role takes place, but role execution fails with
You need to install \"jmespath\" prior to running json_query filter"
When i check if the package is installed manually using dpkg -s python-jmespath i can see the package is installed correctly.
A second run of the playbook (with the package already installed) doesnt fail.
Do I miss an ansible configuration, that updates the list of installed packages during the playbook run ?
Am I doing something wrong in general ?
Thanks in advance
FWIW. It's possible to tag installation tasks and install the packages in the first step. For example
- name: install packages
package:
name: "{{ item.name }}"
state: "{{ item.state|default('present') }}"
state: present
loop: "{{ packages_needed_by_this_role }}"
tags: manage_packages
Install packages first
shell> ansible_playbook my-playbook.yml -t manage_packages
and then run the playbook
shell> ansible_playbook my-playbook.yml
Notes
This approach makes checking of the playbooks with "--check" much easier.
Checking idempotency is also easier.
With tags: [manage_packages, never] the package task will be skipped when not explicitly selected. This will speed up the playbook.

Ansible playbook fails to lock apt

I took over a project that is running on Ansible for server provisioning and management. I'm fairly new to Ansible but thanks to the good documentation I'm getting my head around it.
Still I'm having an error which has the following output:
failed: [build] (item=[u'software-properties-common', u'python-pycurl', u'openssh-server', u'ufw', u'unattended-upgrades', u'vim', u'curl', u'git', u'ntp']) => {"failed": true, "item": ["software-properties-common", "python-pycurl", "openssh-server", "ufw", "unattended-upgrades", "vim", "curl", "git", "ntp"], "msg": "Failed to lock apt for exclusive operation"}
The playbook is run with sudo: yes so I don't understand why I'm getting this error (which looks like a permission error). Any idea how to trace this down?
- name: "Install very important packages"
apt: pkg={{ item }} update_cache=yes state=present
with_items:
- software-properties-common # for apt repository management
- python-pycurl # for apt repository management (Ansible support)
- openssh-server
- ufw
- unattended-upgrades
- vim
- curl
- git
- ntp
playbook:
- hosts: build.url.com
sudo: yes
roles:
- { role: postgresql, tags: postgresql }
- { role: ruby, tags: ruby }
- { role: build, tags: build }
I just had the same issue on a new VM. I tried many approaches, including retrying the apt commands, but in the end the only way to do this was by removing unattended upgrades.
I'm using raw commands here, since at this point the VM doesn't have Python installed, so I need to install that first, but I need a reliable apt for that.
Since it is a VM and I was testing the playbook by resetting it to a Snapshot, the system date was off, which forced me to use the date -s command in order to not have problems with the SSL certificate during apt commands. This date -s triggered an unattended upgrade.
So this snippet of a playbook is basically the part relevant to disabling unattended upgrades in a new system. They are the first commands I'm issuing on a new system.
- name: Disable timers for unattended upgrade, so that none will be triggered by the `date -s` call.
raw: systemctl disable --now {{item}}
with_items:
- 'apt-daily.timer'
- 'apt-daily-upgrade.timer'
- name: Reload systemctl daemon to apply the new changes
raw: systemctl daemon-reload
# Syncing time is only relevant for testing, because of the VM's outdated date.
#- name: Sync time
# raw: date -s "{{ lookup('pipe', 'date') }}"
- name: Wait for any possibly running unattended upgrade to finish
raw: systemd-run --property="After=apt-daily.service apt-daily-upgrade.service" --wait /bin/true
- name: Purge unattended upgrades
raw: apt-get -y purge unattended-upgrades
- name: Update apt cache
raw: apt-get -y update
- name: If needed, install Python
raw: test -e /usr/bin/python || apt-get -y install python
Anything else would cause apt commands to randomly fail because of locking issues caused by unattended upgrades.
This is a very common situation when provisioning Ubuntu (and likely some other distributions). You try to run Ansible while automatic updates are running in background (which is what happens right after setting up a new machine). As APT uses semaphore, Ansible gets kicked out.
The playbook is ok and the easiest way to verify is to run it later (after automatic update process finishes).
For a permanent resolution, you might want to:
use an OS image with automatic updates disabled
add an explicit loop in the Ansible playbook to repeat the failed task until it succeeds

Ansible apt module showing "item changed" when I don't think it did

I am trying to install Apache2 with Ansible. I have a role and handler for Apache.
My playbook (site.yml) contains:
---
- hosts: webservers
remote_user: ansrun
become: true
become_method: sudo
The Ansible role file contains:
---
- name: Install Apache 2
apt: name={{ item }} update_cache=yes state=present
with_items:
- apache2
when: ansible_distribution == "Ubuntu"
- name: Enable mod_rewrite
apache2_module: name=rewrite state=present
notify:
- reload apache2
Whenever I run the playbook, I get this message, but nothing has changed.
changed: [10.0.1.200] => (item=[u'apache2'])
I think this has something to do with the conditional.
You are running into a problem introduced to Ansible 2.2.0 (and fixed in 2.2.1).
With update_cache=yes the apt module was made to return changed-status whenever APT cache update occurred, not only when the actual package was upgraded.
You need to upgrade Ansible to version 2.2.1 (released officially on Jan 16th)
You need to do one of the following:
upgrade Ansible to at least 2.2.1 (currently in release candidate state and not available in PyPI, so you'd have to run Ansible from source);
downgrade Ansible to 2.1.3;
retain Ansible 2.2.0 and split the Install Apache 2 task into two:
one for cache update only (maybe with changed_when set to false),
one for the actual apache2 package installation (without update_cache=yes), calling the handler.

Why Ansible keeps giving me error "Could not find the requested service httpd: cannot check nor set state"?

I am doing a dry run on installing apache web server on a centos 7 box.
This is the webserver.yml file:
--- # Outline to Playbook Translation
- hosts: apacheWeb
user: aleatoire
sudo: yes
gather_facts: no
tasks:
- name: date/time stamp for when the playbook starts
raw: /bin/date > /home/aleatoire/playbook_start.log
- name: install the apache web server
yum: pkg=httpd state=latest
- name: start the web service
service: name=httpd state=started
- name: install client software - telnet
yum: pkg=telnet state=latest
- name: install client software - lynx
yum: pkg=lynx state=latest
- name: log all the packages installed on the system
raw: yum list installed > /home/aleatoire/installed.log
- name: date/time stamp for when the playbook ends
raw: /bin/date > /home/aleatoire/playbook_end.log
When I do a dry run with:
ansible-playbook webserver.yml --check
I keep getting this error:
fatal: [<ip_address>]: FAILED! => {"changed": false, "failed": true, "msg": "Could not find the requested service httpd: cannot check nor set state"}
to retry, use: --limit #/home/aleatoire/Outline/webserver.retry
I tried adding ignore_issues: true and that did not work either.
--check is not going to actually install the httpd package if it's not there yet. So then the service: call will fail if there is no httpd unit file installed yet.
You can use --syntax-check option instead.

Resources