Ansible: How to add Linux modul command path (opkg not in path) - linux

My Linux box (busybox) using read-only filesystems mostly. I have option to install my programs different path like PATH=/opt/bin:/opt/sbin. The package manager also sitting in this folder (exec. file name: /opt/bin/opkg) .
When I want to use Ansible opkg module I got the following error:
"Failed to find required executable opkg in paths: /bin:/usr/bin:/bin:/usr/sbin:/sbin"
Question: How can I say to my Ansible to look for opkg package in different path?
Any ideas are welcome!
Thank you!

I found some useful link:
https://docs.ansible.com/ansible/latest/reference_appendices/faq.html
Ansible - Set environment path as inventory variable
And here is my example:
---
- hosts: CBOX-0001
gather_facts: True
gather_subset:
- "!all"
environment:
PATH: "/opt/bin:/opt/sbin:/usr/bin:/usr/sbin:{{ ansible_env.PATH }}"
collections:
- community.general
tasks:
- name: "install opkg packages"
opkg:
name: "{{ item }}"
state: present
with_items:
- screen
- mc
- rclone

Related

inventory file variables are not calling by with_items in ansible Zypper module

I have a inventory file with below details.This pkgs-list should be call by ansible module in main.yml.But its not calling.What am i doing wrong here?
[target:vars]
pkgs_list = vim cloudnetconfig
Main.yml has below module
- name: Install all packages
zypper:
name:"{{ item }}"
state:present
with_items: '{{ pkgs_list }}"
error says "No provider found".
It looks like you've made pkgs_list a string. To use compose data types (dicts and lists) it's better to use yaml inventory.
inventory.yaml
target:
hosts:
example:
vars:
pkgs_list: [vim, cloudnetconfig]

How to run a playbook task based on OS type in ansible?

I have written a playbook task in ansible. I am able to run the playbook on linux end.
- name: Set paths for go
blockinfile:
path: $HOME/.profile
backup: yes
state: present
block: |
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/go
export FABRIC_CFG_PATH=$HOME/.fabdep/config
- name: Load Env variables
shell: source $HOME/.profile
args:
executable: /bin/bash
register: source_result
become: yes
As in linux we have .profile in home directory but in Mac there is no .profile and .bash_profile in macOS.
So I want to check if os is Mac then path should be $HOME/.bash_profile and if os is linux based then it should look for $HOME/.profile.
I have tried adding
when: ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'precise'
But it does not work firstly and also it is length process. I want to get path based on os in a variable and use it.
Thanks
I found a solution this way. I added gather_facts:true at top of yaml file and it started working. I started using variable as ansible_distribution.
Thanks
An option would be to include_vars from files. See example below
- name: "OS specific vars (will overwrite /vars/main.yml)"
include_vars: "{{ item }}"
with_first_found:
- files:
- "{{ ansible_distribution }}-{{ ansible_distribution_release }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}.yml"
- "default.yml"
paths: "{{ playbook_dir }}/vars"
skip: true
- name: Set paths for go
blockinfile:
path: "$HOME/{{ my_profile_file }}"
[...]
In the playbooks' directory create directory vars and create files
# cat var/Ubuntu.yml
my_profile_file: ".profile"
# cat var/macOS.yml
my_profile_file: ".bash_profile"
If you have managed hosts with different OS, group them by OS in your inventory:
[Ubuntu]
ubu1
ubu2
[RHEL6]
RH6_1
[RHEL7]
RH7_1
RH7_2

Changing ansible loop due to v2.11 deprecation

I'm running a playbook which defined several packages to install via apt:
- name: Install utility packages common to all hosts
apt:
name: "{{ item }}"
state: present
autoclean: yes
with_items:
- aptitude
- jq
- curl
- git-core
- at
...
A recent ansible update on my system now renders this message concerning the playbook above:
[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: [u'aptitude',
u'jq', u'curl', u'git-core', u'at', u'heirloom-mailx', u'sudo-ldap', u'sysstat', u'vim', u'at', u'ntp',
u'stunnel', u'sysstat', u'arping', u'net-tools', u'lshw', u'screen', u'tmux', u'lsscsi']` and remove the loop.
If I'm understanding this correctly, Ansible now wants this list of packages as an array which leaves this:
name: [u'aptitude', u'jq', u'curl', u'git-core', u'at','heirloom-mailx', u'sudo-ldap', u'sysstat', u'vim', u'at', u'ntp',u'stunnel', u'sysstat', u'arping', u'net-tools', u'lshw', u'screen', u'tmux', u'lsscsi']
Is there a better way? Just seems like I'll be scrolling right forever in VIM trying to maintain this. Either that, or word wrap it and deal with a word-cloud of packages.
You can code the array in YAML style to make it more readable:
- name: Install utility packages common to all hosts
apt:
name:
- aptitude
- jq
- curl
- git-core
- at
state: present
autoclean: yes
I had this same question and it looks like each set of packages with the same states will have to be their own block. Looking at Ansible's documentation, they have a block for each state as an example so I took that example, cut up my packages based off their states and followed ignacio's example and it ended up working perfectly.
So basically it would look like this
- name: Install packages required for log-deployment
apt:
name:
- gcc
- python-devel
state: latest
autoclean: yes
- name: Install packages required for log-deployment
apt:
name:
- python
- mariadb
- mysql-devel
state: installed
Hope that makes sense and helps!
I came across this exact same problem , but with a much longer list of apps , held in a vars file. This is the code I implemented to get around that problem. The list of the apps is placed into the "apps" variable and Ansible iterates over that.
- name: Install default applications
apt:
name: "{{item}}"
state: latest
loop: "{{ apps }}"
when: ansible_distribution == 'Ubuntu' or ansible_distribution == 'Debian'
tags:
- instapps
The file holding the list of apps to install is in the Defaults directory in the role directory for this task - namely the "common" role directory.
roles
- common
- Defaults
- main.yml
For a record, you can have this written this way:
- name: Install utility packages common to all hosts
apt:
state: present
autoclean: yes
pkg: [
"aptitude",
"jq",
"curl",
"git-core",
"at",
]
however if you are upgrading existing roles to new apt's requirements, Ignacio's accepted answer is far better as all you need is just to add some indentation to already existing entries.

Ansible: ignoring errors in a loop

I need to install a number of packages on linux boxes. Some (few) of the packages may be missing for various reasons (OS version, essentially)
- vars:
pkgs:
- there_1
- not_there_1
- there_2
...
but I would like too manage them from a single playbook. So I cannot stick them all in a single
yum: state=latest name="{{pkgs}}"
Because missing packages would mess the transaction so that nothing gets installed.
However, the obvious (and slow) one by one install also fails, because the first missing package blows the entire loop out of the water, thusly:
- name Packages after not_there_1 are not installed
yum: state=latest name="{{item}}"
ignore_errors: yes
with_items: "{{ pkgs }}"
Is there a way to ignore errors within a loop in such a way that all items be given a chance? (i.e. install errors behave as a continue in the loop)
If you need to loop a set of tasks a a unit it would be -so- nice if we could use with_items on an error handling block right?
Until that feature comes around you can accomplish the same thing with include_tasks and with_items. Doing this should allow a block to handle failed packages, or you could even include some checks and package installs in the sub-tasks if you wanted.
First setup a sub-tasks.yml to contain your install tasks:
Sub-Tasks.yml
- name: Install package and handle errors
block:
- name Install package
yum: state=latest name="{{ package_name }}"
rescue:
- debug:
msg: "I caught an error with {{ package_name }}"
Then your playbook will setup a loop of these tasks:
- name: Install all packages ignoring errors
include_tasks: Sub-Tasks.yml
vars:
package_name: "{{ item }}"
with_items:
- "{{ pkgs }}"

install from remote location in ansible

I am new to ansible.I am trying to fetch a setup file from a remote server and trying to copy it on my mac and then run it if necessary.Here is my playbook.I tried get_url because i am running in a virtual box on mac..So I have ansible on my mac and linux on a virtual box on mac.So I can give commands in linux and not have to worry about mac os x syntax.So the issue i am facing is this.This is the error ansible is showing me.So please help in resolving this.Am i using the right command ,if not what can i do.
- name: download file
hosts: linux
user: root
vars_prompt:
- name: smb_username
prompt: "Enter smb share username"
- name: smb_password
prompt: "Enter smb share password"
private: yes
tasks:
- name: download file
command: smbclient "Actual url" {{ smb_password }} -U {{ smb_username }} -c "recurse;lcd /local/path;get archive.zip" creates=/local/path/archive.zip*
This isn't a playbook, playbooks start with
---
- hosts:
- hostA
tasks:
- name: ...
get_url: ...
Ansible has example playbooks, and one for get_url in particular: https://github.com/ansible/ansible-examples/blob/master/language_features/get_url.yml

Resources