I am having an issue learning Ansible and getting feedback from it.
Here is the code I am running
clear && sudo ansible-playbook patching.yml -u stackoverflow -k --ask-become-pass -v
Here is my patching.yml file
---
- hosts: all
gather_facts: no
become: yes
tasks:
- name: Patching
apt: update_cache=yes force_apt_get=yes
- name: Proof of Patching
shell: apt -q -y --ignore-hold --allow-change-held-packages --allow-unauthenticated -s dist-upgrade | /bin/grep ^Inst | wc -l
register: output
- debug: var=output
What I am trying to accomplish is one to learn Ansible and two to patch my various Linux machines with some sort of feedback that they have patched I am getting this feedback after reading stack overflow for some time. It is long and un-human-friendly I would like it to be just a # or even better hostname: #.
Thank You
-Jared
Related
I used the below code in my playbook to remove the rpm
- name: query rpm
shell: "rpm -qa | grep -i rscd"
args:
warn: false
register: rpmblade
- debug: msg="{{ rpmblade.stdout}}"
- name: remove bladelogic rpm
shell: "rpm -e {{ rpmblade.stdout }}"
when: rpmblade.stdout == "BladeLogic_RSCD_Agent-8.9.04-292.x86_64" or rpmblade.stdout == "BladeLogic_RSCD_Agent-21.02.01-211.x86_64"
but what I required was irrespective of whatever the version as long as I see the "BladeLogic_RSCD_Agent" I want to uninstall that package. Is there a way to do it?
Is there a way to run Cisco NX-OS Bash shell commands in Ansible without a task going in to the config mode?
I just want to get the below command output but keep failing.
bash-4.3# smartctl -a /dev/sda | egrep 'Model|Firmware|Hours'
Device Model: Micron_M600_MTFDDAT064MBF
Firmware Version: MC04
9 Power_On_Hours 0x0032 100 100 000 Old_age Always - 17014
What I've used is below playbook.
- name: running the bash commands
ios_command:
commands:
- conf t
- feature bash
- run bash sudo su
- smartctl -a /dev/sda | egrep 'Model|Firmware|Hours'
register: uptime
- name: output the result
debug:
msg: uptime
- name: run the last command
ios_command:
commands: smartctl -a /dev/sda | egrep 'Model|Firmware|Hours'
register: uptime
- name: write to the file
ansible.builtin.template:
src: ./templates/9k_uptime.j2
dest: ./9k_uptime/9k_uptime.txt
newline_sequence: '\r\n'
(** I'm not proficient in Ansible. Just barely know how to get outputs for bulk devices)
Any help is much appreciated. Thank you!
As I will have a similar use case and probably some more in the future, I've setup a short test on a RHEL 7.9 environment.
As far as I understand for Cisco Nexus Series NX-OS and Bash are other modules recommended and which come from the Community Collections. An installation of them is necessary before
ansible-galaxy collection install cisco.nxos # --ignore-certs
Process install dependency map
Starting collection install process
Installing ... to '/home/${USER}/.ansible/collections/ansible_collections/community/cisco ...'
as well adding the collection path to the library path.
vi ansible.cfg
...
[defaults]
library = /usr/share/ansible/plugins/modules:~/.ansible/plugins/modules:~/.ansible/collections/ansible_collections/
...
Now it is possible to run commands on the remote device
# Usage of command module
# Doc: https://docs.ansible.com/ansible/latest/collections/cisco/nxos/nxos_command_module.html
- name: Run command on remote device
cisco.nxos.nxos_command:
commands: show version
register: results
- name: Show results
debug:
msg: "{{ results.stdout_lines }}"
or gathering device information, in example the configuration.
# Gather device information
# Doc: https://docs.ansible.com/ansible/latest/collections/cisco/nxos/nxos_facts_module.html
- name: Gather only the config and default facts
cisco.nxos.nxos_facts:
gather_subset:
- config
- name: Show facts
debug:
msg: "{{ ansible_facts }}"
If only interested in Kernel uptime the following
commands: show version | i uptime
would be enough.
I would like to run a set of raw commands (to install python) if a given
operating system on the target host is OpenBSD
I have to run these checks as pre_tasks (because to run anything as a task Python must already be present on the target system)
What I do not understand is, whether any OS characteristics variables are available in pre_task stage (like ansible_os_family)
- name: Check for Python
raw: test -e /usr/bin/python
changed_when: false
failed_when: false
register: check_python
- name: Install Python on OpenBSD
# raw: test -e /usr/bin/apt && (apt -y update && apt install -y python-minimal) || (yum -y install python libselinux-python)
raw: pkg_add -r python%3
when: check_python.rc != 0
when: ansible_os_family == "OpenBSD" # <-- problem here
I seem to get a problem when trying to use ansible_os_family
Is there a way to enable the pre_tasks without me writing my own os family checks?
PS. I used the above python installation code, following recommendation here:
[1] https://relativkreativ.at/articles/how-to-install-python-with-ansible
Following your latest comments, as said earlier by #Vladimir and myself, you will not be able to use ansible's facts variables to detect the OS on hosts without python since it is impossible to gather facts (i.e. play the setup module). You need to do that job on your own for this first step.
I don't have a BSD system I can access. So the below is totally untested for your platform. But I believe it should work, or at least put you on track. Check the content of /etc/os-release on your system to adapt the regex if needed. The one I wrote gave a correct result on Ubuntu, Debian, Centos, RHEL and on RedHat UBI and Alpine docker images.
---
- name: Fix hosts with no python at all
hosts: all
gather_facts: false
tasks:
- name: Perform a dirty OS detection if python is not installed
raw: |-
if which python > /dev/null || which python3 > /dev/null; then
echo installed
else
sed -n "s/^NAME=\"\(.*\)\"/\\1/p" /etc/os-release
fi
changed_when: false
register: dirty_detect
- name: Print message when already installed
debug:
msg: Host {{ inventory_hostname }} already has python. Next will skip.
when: dirty_detect.stdout_lines[0] == 'installed'
- name: Install python on openbsd if needed
raw: |-
pkg_add -r python%3
become: true
when: dirty_detect.stdout_lines[0] == 'OpenBSD'
- name: Install python on Ubuntu if needed
raw: |-
apt install -y python3
become: true
when: dirty_detect.stdout_lines[0] == 'Ubuntu'
- name: Back to normal life with ansible
hosts: all
tasks:
- name: Now we gathered facts and we can use all facts vars
debug:
msg: Host {{ inventory_hostname }} is running {{ ansible_os_familly }}
- name: We might have left hosts with python 2.7 only above, make sure python3 is installed
package:
name: python3
become: true
Q: "Is there a way to enable the pre_tasks without me writing my own os family checks?"
A: No. It is not. Python is needed to collect the facts.
See the verbose output. For example the output of connecting FreeBSD 12 remote host from the Ubuntu controller
shell> ansible --version
ansible 2.9.6
...
python version = 3.8.2 (default, Apr 27 2020, 15:53:34) [GCC 9.3.0]
shell> ansible test_01 -m setup -vvv
ESTABLISH SSH CONNECTION FOR USER: admin
SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="admin"' -o ConnectTimeout=30 -o ControlPath=/export/home/admin.config/.ansible/cp/5a3ab05cf7 test_01 '/bin/sh -c '"'"'/usr/local/bin/python3.7 && sleep 0'"'"''
Without Python installed the module will crash
(127, b'', b'/bin/sh: /usr/bin/python: not found\n')
Failed to connect to the host via ssh: /bin/sh: /usr/bin/python: not found
[WARNING]: No python interpreters found for host test_01 (tried ['/usr/bin/python',
'python3.7', 'python3.6', 'python3.5', 'python2.7', 'python2.6', '/usr/libexec/platform-
python', '/usr/bin/python3', 'python'])
test_01 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"module_stderr": "/bin/sh: /usr/bin/python: not found\n",
"module_stdout": "",
"msg": "The module failed to execute correctly, you probably need to set the interpreter.\nSee stdout/stderr for the exact error",
"rc": 127
}
I have an Ansible role which I'm trying to migrate to macOS.
The following step fails:
- name: get go user details
command: sh -c 'echo $HOME'
become: true
become_user: "{{ go_user }}"
become_flags: -Hi
changed_when: false
register: go_user_check
The error emitted is:
TASK [default : get go user details] *******************************************
fatal: [127.0.0.1]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: /var/tmp/ansible-tmp-1533765311.28-97292171123102/: Operation not permitted\nchown: /var/tmp/ansible-tmp-1533765311.28-97292171123102/command.py: Operation not permitted\n}). For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"}
This same step works just fine on all the Linux distributions
I'm testing against. When I execute sudo -Hiu username sh -c 'echo $HOME', I get what I would expect: /Users/travis.
When I execute the following:
ansible -i 127.0.0.1, -c local --become --become-user travis \
-m command -a 'sh -c "echo $HOME"' all
I get exactly what I'd expect, /Users/travis.
I'm reading the documentation linked to by Ansible but I'm not seeing a workaround.
Is there a different way I should be executing this on OSX?
I was able to get it to proceed with the following modification:
diff --git a/tasks/discover/go.yml b/tasks/discover/go.yml
index 090ce7d..f0c2b89 100644
--- a/tasks/discover/go.yml
+++ b/tasks/discover/go.yml
## -3,9 +3,10 ##
command: sh -c 'echo $HOME'
become: true
become_user: "{{ go_user }}"
- become_flags: -Hi
changed_when: false
register: go_user_check
+ vars:
+ ansible_ssh_pipelining: true
- name: set go user home
set_fact: go_user_home="{{ go_user_check.stdout_lines[0] }}"
Pipelining appears to dodge the file modification that is failing. Unfortunately, I don't have the answer as to why it's failing, so other answers are still welcome as I'd like to get to what is actually happening.
There appear to be a lot of caveats to using Ansible on macOS, so I will probably have to have my tasks diverge completely based on whether it's Linux or macOS.
I want to install MongoDB via Ansible playbook, I am following the instruction in:
https://www.howtoforge.com/tutorial/install-mongodb-on-ubuntu-16.04/
For the step about "Step 2 - Create source list file MongoDB"
I should use:
echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
while it get the ubuntu version with the following command:
$(lsb_release -sc)
How can I do it via yml file and run it via ansible palybook?
I used the below yml command but it is not working and gives me error since I use shell command "$(lsb_release -sc)" inside my script
- name: Create source list file MongoDB
sudo: yes
lineinfile: >
line="deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.2 multiverse"
dest=/etc/apt/sources.list.d/mongodb-org-3.2.list
state=present
create=yes
There is apt_repository module in Ansible:
- apt_repository:
repo: deb http://repo.mongodb.org/apt/ubuntu {{ ansible_distribution_release | lower }}/mongodb-org/3.2 multiverse
state: present
You can register the result of one task, including its stdout, as a variable then use it in later tasks:
- name: Work out the distribution
command: lsb_release -sc
register: result
- name: Create source list file MongoDB
sudo: yes
lineinfile: >
line="deb http://repo.mongodb.org/apt/ubuntu {{ result.stdout }}/mongodb-org/3.2 multiverse"
dest=/etc/apt/sources.list.d/mongodb-org-3.2.list
state=present
create=yes