Ansible: 'shell' not executing - ansible

I'm trying to run a shell command to install a package downloaded from my local Artifactory repository, as I don't have access to download it straight from the internet.
When I run the command directly on the node as such
rpm -ivh kubectl-1.1.1.x86_64.rpm --nodigest --nofiledigest
It works perfectly.
But then put in Ansible playbook as such
- name: Install Kubectl
shell: rpm -ivh kubectl-1.1.1.x86_64.rpm --nodigest --nofiledigest
Nothing happens.
It doesn't error.. It just doesn't install.
I've tried the command and ansible.builtin.shell module as well, but nothing works.
Is there a way to do this please?

There are different topics in your question.
Regarding
to install a package downloaded from my local Artifactory repository, as I don't have access to download it straight from the internet.
you can use different approaches.
1. Direct download
- name: Make sure package becomes installed from internal repository
yum:
name: https://{{ REPOSITORY_URL }}/artifactory/kube/kubectl-{{ KUBE_VERSION }}.x86_64.rpm
state: present
2. Configure local repository
The next one is to provide a .repo template file like
[KUBE]
name = Kubectl - $basearch
baseurl = https://{{ REPOSITORY_URL }}/artifactory/kube/
username = {{ API_USER }}
password = {{ API_KEY }}
sslverify = 1
enabled = 1
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-KUBE
and to perform
- name: Make sure package becomes installed from internal repository
yum:
name: kubectl
state: present
This is possible because JFrog Artifactory can provide local RPM repositories if configured correctly. For more information you research the documentation there since it is almost only about proper configuration.
Regarding
Nothing happens. It doesn't error.. It just doesn't install.
you can use several task to split up your steps, make them idempotent and get an better insight how they are working.
3. shell, rpm and debug
- name: Make sure destination folder for package download (/opt/packages) exists
file:
path: "/opt/packages/"
state: directory
- name: Download RPM to remote hosts
get_url:
url: "https://{{ REPOSTORY_URL }}/artifactory/kube/kubectl-{{ KUBE_VERSION }}.x86_64.rpm"
dest: "/opt/packages/kubectl-{{ KUBE_VERSION }}.x86_64.rpm"
- name: Check package content
shell:
cmd: "rpm -qlp /opt/packages/kubectl-{{ KUBE_VERSION }}.x86_64.rpm"
register: rpm_qlp
- name: STDOUT rpm_qlp
debug:
msg: "{{ rpm_qlp.stdout.split('\n')[:-1] }}"
- name: Install RPM using 'command: rpm -ivh'
shell:
cmd: "rpm -ivh /opt/packages/kubectl-{{ KUBE_VERSION }}.x86_64.rpm"
register: rpm_ivh
- name: STDOUT rpm_ivh
debug:
msg: "{{ rpm_ivh.stdout.split('\n')[:-1] }}"
Depending on the RPM package, environment and configuration, all may just work good.

Try use command module and register the output i use it to install oci8 by pecl for oracle database on linux

Related

Adding NewRelic PHP agent via Ansible

I've been trying to install NewRelic agent for PHP on Amazon Linux 2 the "ansible way", but I cannot get it to work with either rpm_key or yum_repository. I've also tried just copying the repo file to /etc/yum.repos.d/newrelic.repo, but it's supposed to use a GPG key and the only one I found is 548C16BF.gpg and at that point I felt this was getting to hacky.
My current setup is:
- name: add the new relic repository
# noqa 303
command: rpm -Uvh http://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm
but that doesn't sit well with ansible-lint (hence the rule exception).
Am I missing something here or maybe my preconception of what the "ansible-way" would be is incorrect. Asking for a friend (with a lot of Ansible experience).
To add the GPG key:
- name: Adding RPM key
rpm_key:
state: present
key: https://download.newrelic.com/548C16BF.gpg
and Add the repository:
- name: Add repository
yum_repository:
name: rewrelic
description: Newrelic YUM repo
baseurl: http://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm
Finally install the yum:
- name: install Rewrelic
yum:
name: rewrelic
state: present

Install rpm after copy, with ansible

I have an ansible playbook which will copy a file into a location on a remote server. It works fine. In this case, the file is an rpm. This is the way it works:
---
- hosts: my_host
tasks:
- name: mkdir /tmp/RPMS
file: path=/tmp/RPMS state=directory
- name: copy RPMs to /tmp/RPMS
copy:
src: "{{ item }}"
dest: /tmp/RPMS
mode: 0755
with_items:
[any_rpm-x86_64.rpm]
register: rpms_copied
Now, with the file successfully on the remote server, I need to start some new logic that will install the rpm that sits in /tmp/RPMS. I have run many different versions of the below (So this code is added onto the above block):
- name: install rpm from file
yum:
name: /tmp/RPMS/any_rpm-x86_64.rpm
state: present
become: true
I don't know if the formatting is incorrect, or if this is not the way. Can anyone advise as to how I can get the rpm in the directory /tmp/RPMS installed using a new few lines in the existing playbook?
Thanks.
I did not find this anywhere else, and it genuinely took me all of my working day to get to this point. For anyone else struggling:
- name: Install my package from a file on server
shell: rpm -ivh /tmp/RPMS/*.rpm
async: 1800
poll: 0
become_method: sudo
become: yes
become_user: root

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 yum disablerepo does not work if repo is not installed

I have a number of different Centos7 servers running. I like to use ansible to update them all at once.
As one of my servers has an additional repository enabled, which I do not want to update. I've added to the playbook the option to disable this repo. This works as expected.
However, on my other servers, I did not install and enable this repo. When using the disablerepo in my ansible playbook, I get an error: repository not found.
How do I solve this in the ansible-playbook? Is it possible to add an condition like, if repo installed; then disablerepo; else do nothing?
Is it possible to ignore these errors?
ansible-playbook:
---
- hosts: [all]
tasks:
- name: update all packages to lastest version
yum:
name: '*'
state: latest
disablerepo: sernet-samba-4.2
you can put ignore_errors: yes as in the link from the comment, or you can put when, only if certain package is installed, sure you have to register them to variables first, I'm thinking something like:
- name: check if installed
shell: rpm -qa sernet-samba-4.2
register: is_installed
- name: update all packages to lastest version
yum:
name: '*'
state: latest
disablerepo: sernet-samba-4.2
when: is_installed.rc == 1
Warning: Untested.
After a day of research in internet and experiments finally found a solution that worked. Try to use wildcard.. then it will not fail when repo is missing.
yum:
name: ''
state: latest
disablerepo: sernet-samba

Install local RPM with regex or glob filename using Ansible

I am trying to write an ansible playbook which installs some RPMs for me after they have been copied to a known location by a Jenkins job. The problem is, I'm not sure how to get the name of the RPM to install without hard coding it.
Here is what I have now:
- hosts: localhost
roles:
- { role: some_role, artifacts: "{{ rpm_path }}/prefix_.*.rpm" }
In this case, rpm_path would be something like:
"/home/jenkins/workspace/rpm_install/artifacts"
The role that is called in this example handles the yum install part:
- name: Install RPMs
yum: name={{item}} state=present
with_items:
- "{{ artifacts }}"
I'd rather not have to hard code RPM names since they come from Jenkins and they are always different. But is there a way either through the yum module, or when I call the role where the regular expression or glob can be interpreted so the full path (rpm name included) is handed to yum?
You should use with_fileglob insted of with_items, something like
- name: Install RPMs
yum: name="{{item}}" state=present
with_fileglob:
- "{{ artifacts }}"

Resources