This is an old revision of the document!
Table of Contents
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
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"