====Ansible automation====
Ansible is an automation tool, a secure shell frontend with expect like functionality. Due to it using
SSH it's a very simple service to utilise and requires only python to be installed on
each managed machine. SSH should to be configured using authorized keys and is not documented here.
It is recommended to develop the process manually before implementing it in Ansible to allow understanding
of any issues that may arise when using Ansible.
===Environment===
Kali Linux
===Operating System===
Windows 10 WSL1
===Install===
Ansible requires a minimum of Python2 version 2.7 or Python3 version 3.5. on the controller and hosts under control.
==Controller==
First install python3 pip as root and after ansible as the logged in user.
sudo -s
apt update
apt full-upgrade
apt install python3-pip
exit
Now add ~/.local/bin to your $PATH and install pip search
to discover ansible tools.
pip3 install pip-search --break-system-packages
pip_search ansible
First hit looks something like this:
📂 ansible │ 6.1.0 │ 12-07-2022 │ Radically simple IT automation
Install ansible locally (this can take time).
pip3 install ansible --break-system-packages
rehash
If ansible was already installed and needs updating
pip3 install --upgrade ansible --break-system-packages
Show version
ansible --version
ansible [core 2.13.1]
config file = None
configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/user/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
executable location = /home/user/.local/bin/ansible
python version = 3.10.5 (main, Jun 8 2022, 09:26:22) [GCC 11.3.0]
jinja version = 3.1.2
libyaml = True
Show options
ansible --help
usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
[--become-user BECOME_USER]
[-K | --become-password-file BECOME_PASSWORD_FILE] [-i INVENTORY]
[--list-hosts] [-l SUBSET] [-P POLL_INTERVAL] [-B SECONDS] [-o]
[-t TREE] [--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER]
[-c CONNECTION] [-T TIMEOUT] [--ssh-common-args SSH_COMMON_ARGS]
[--sftp-extra-args SFTP_EXTRA_ARGS] [--scp-extra-args SCP_EXTRA_ARGS]
[--ssh-extra-args SSH_EXTRA_ARGS]
[-k | --connection-password-file CONNECTION_PASSWORD_FILE] [-C]
[--syntax-check] [-D] [-e EXTRA_VARS] [--vault-id VAULT_IDS]
[--ask-vault-password | --vault-password-file VAULT_PASSWORD_FILES]
[-f FORKS] [-M MODULE_PATH] [--playbook-dir BASEDIR]
[--task-timeout TASK_TIMEOUT] [-a MODULE_ARGS] [-m MODULE_NAME]
pattern
Define and run a single task 'playbook' against a set of hosts
positional arguments:
pattern host pattern
options:
--ask-vault-password, --ask-vault-pass
ask for vault password
--become-password-file BECOME_PASSWORD_FILE, --become-pass-file BECOME_PASSWORD_FILE
Become password file
--connection-password-file CONNECTION_PASSWORD_FILE, --conn-pass-file CONNECTION_PASSWORD_FILE
Connection password file
--list-hosts outputs a list of matching hosts; does not execute anything
else
--playbook-dir BASEDIR
Since this tool does not use playbooks, use this as a
substitute playbook directory. This sets the relative path
for many features including roles/ group_vars/ etc.
--syntax-check perform a syntax check on the playbook, but do not execute
it
--task-timeout TASK_TIMEOUT
set task timeout limit in seconds, must be positive integer.
--vault-id VAULT_IDS the vault identity to use
--vault-password-file VAULT_PASSWORD_FILES, --vault-pass-file VAULT_PASSWORD_FILES
vault password file
--version show program's version number, config file location,
configured module search path, module location, executable
location and exit
-B SECONDS, --background SECONDS
run asynchronously, failing after X seconds (default=N/A)
-C, --check don't make any changes; instead, try to predict some of the
changes that may occur
-D, --diff when changing (small) files and templates, show the
differences in those files; works great with --check
-K, --ask-become-pass
ask for privilege escalation password
-M MODULE_PATH, --module-path MODULE_PATH
prepend colon-separated path(s) to module library (default=~
/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
)
-P POLL_INTERVAL, --poll POLL_INTERVAL
set the poll interval if using -B (default=15)
-a MODULE_ARGS, --args MODULE_ARGS
The action's options in space separated k=v format: -a
'opt1=val1 opt2=val2'
-e EXTRA_VARS, --extra-vars EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
filename prepend with @
-f FORKS, --forks FORKS
specify number of parallel processes to use (default=5)
-h, --help show this help message and exit
-i INVENTORY, --inventory INVENTORY, --inventory-file INVENTORY
specify inventory host path or comma separated host list.
--inventory-file is deprecated
-k, --ask-pass ask for connection password
-l SUBSET, --limit SUBSET
further limit selected hosts to an additional pattern
-m MODULE_NAME, --module-name MODULE_NAME
Name of the action to execute (default=command)
-o, --one-line condense output
-t TREE, --tree TREE log output to this directory
-v, --verbose Causes Ansible to print more debug messages. Adding multiple
-v will increase the verbosity, the builtin plugins
currently evaluate up to -vvvvvv. A reasonable level to
start is -vvv, connection debugging might require -vvvv.
Privilege Escalation Options:
control how and which user you become as on target hosts
--become-method BECOME_METHOD
privilege escalation method to use (default=sudo), use
`ansible-doc -t become -l` to list valid choices.
--become-user BECOME_USER
run operations as this user (default=root)
-b, --become run operations with become (does not imply password
prompting)
Connection Options:
control as whom and how to connect to hosts
--private-key PRIVATE_KEY_FILE, --key-file PRIVATE_KEY_FILE
use this file to authenticate the connection
--scp-extra-args SCP_EXTRA_ARGS
specify extra arguments to pass to scp only (e.g. -l)
--sftp-extra-args SFTP_EXTRA_ARGS
specify extra arguments to pass to sftp only (e.g. -f, -l)
--ssh-common-args SSH_COMMON_ARGS
specify common arguments to pass to sftp/scp/ssh (e.g.
ProxyCommand)
--ssh-extra-args SSH_EXTRA_ARGS
specify extra arguments to pass to ssh only (e.g. -R)
-T TIMEOUT, --timeout TIMEOUT
override the connection timeout in seconds (default=10)
-c CONNECTION, --connection CONNECTION
connection type to use (default=smart)
-u REMOTE_USER, --user REMOTE_USER
connect as this user (default=None)
Some actions do not make sense in Ad-Hoc (include, meta, etc)
==Managed host==
Install python3 on each host you wish to perform operations on
__Debian / Kali__
apt install python3 python3-openssl
__Red Hat / Oracle __
yum install python3 python3-pyOpenSSL
The user must also have access to super user via sudo.
===Configuration===
Generate default configuration
mkdir -p ~/.ansible
ansible-config init --disabled -t all > ~/.ansible.cfg
Create an inventory file of hosts and change entry in cfg file, eg
touch ~/.ansible/hosts
sed -i 's/;inventory=\/etc\/ansible\/hosts/inventory=~\/.ansible\/hosts/' ~/.ansible.cfg
Add some machines to the hosts file
[home]
pi1
pi2
pi3
Test
ansible --list-hosts home
hosts (3):
pi1
pi2
pi3
Ansible uses so-called "playbooks" which contain configuration parameters for the
supported modules.
Here is one to update debian.
__debian_update.yml__
---
- hosts: home
become: yes
tasks:
- name: UPDATE
ansible.builtin.apt:
update_cache: yes
upgrade: full
And, another to update REDHAT, Eg. Oracle Linux
__redhat_update.yml__
---
- hosts: VM_REDHAT
become: yes
tasks:
- name: UPDATE
yum:
name: '*'
state: latest
Running the ruleset is accomplished with ansible-playbook. In the following
example, the "junk" reported is the output from the TCSH time setting. Ansible uses
a regular ssh login terminal to perform the apt upgrade process.
ansible-playbook ~/.ansible/debian_update.yml
PLAY [home] ***************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
[WARNING]: Module invocation had junk after the JSON data: 0:02.07s
ok: [PiG]
[WARNING]: Module invocation had junk after the JSON data: 0:05.04s
ok: [PiD]
[WARNING]: Module invocation had junk after the JSON data: 0:05.12s
ok: [PiE]
[WARNING]: Module invocation had junk after the JSON data: 0:05.64s
ok: [PiH]
[WARNING]: Module invocation had junk after the JSON data: 0:04.10s
ok: [PiI]
[WARNING]: Module invocation had junk after the JSON data: 0:12.91s
ok: [PiF]
TASK [UPDATE] ************************************************************************************************************
[WARNING]: Module invocation had junk after the JSON data: 1:23.50s
changed: [PiH]
[WARNING]: Module invocation had junk after the JSON data: 0:26.67s
ok: [PiI]
[WARNING]: Module invocation had junk after the JSON data: 5:36.97s
changed: [PiE]
[WARNING]: Module invocation had junk after the JSON data: 6:02.16s
changed: [PiG]
[WARNING]: Module invocation had junk after the JSON data: 6:03.53s
changed: [PiD]
[WARNING]: Module invocation had junk after the JSON data: 17:49.68s
changed: [PiF]
PLAY RECAP ****************************************************************************************************************
PiD : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
PiE : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
PiF : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
PiG : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
PiH : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
PiI : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
18:09.41s
One way to fix the "junk" problem found above is to set the TERM variable to ANSIBLE as an SSH option and
then detect that in the profile at the remote end.
In .ansible.cfg
# (string) Common extra args for all SSH CLI tools.
ssh_common_args=-o SetEnv='TERM=ANSIBLE'
And in the CSH/TCSH profile, something like this:
if ($TERM == "ANSIBLE") then
unset time
else
set time = ( 0 "%Es" )
endif
If you want to see the remote host environment, you can do something like this:
ansible home -m command -a "env"
===Resources===
[[https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html|Ansible Inventory]]
[[https://docs.ansible.com/ansible/latest/collections/index_module.html|Ansible Modules]]