Ansible

Release and maintenance / latest versions
# stable
https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#release-status
# devel
https://docs.ansible.com/ansible/devel/modules/list_of_all_modules.html

Ansible playbook repository
https://github.com/panticz/ansible

Install Ansible
http://www.panticz.de/install-ansible

Configuration
https://gist.github.com/wbcurry/f38bc6d8d1ee4a70ee2c
https://docs.ansible.com/ansible/2.4/intro_configuration.html#remote-tmp
https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings-locations
https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

# include order
./ansible.cfg
~/.ansible.cfg
/etc/ansible/ansible.cfg
 
[defaults]
retry_files_enabled = False
stdout_callback = debug
bin_ansible_callbacks = True
ansible_python_interpreter = /usr/bin/python
host_key_checking = False
inventory = hosts
forks = 99
retry_files_enabled = false
roles_path = ./my_roles
pipelining = True
scp_if_ssh = True
max_fail_percentage = 0
 
[privilege_escalation]
become=True
 
 
cat <<EOF>> ~/.bashrc
export ANSIBLE_VAULT_PASSWORD_FILE=~/.ansible/.vault_pass
export ANSIBLE_STDOUT_CALLBACK=debug
export ANSIBLE_HOST_KEY_CHECKING=false
# export ANSIBLE_DEBUG=True
# export ANSIBLE_LOG_PATH=/var/log/ansible.log
# export ANSIBLE_PYTHON_INTERPRETER=/usr/bin/python3
EOF
 
DISPLAY_SKIPPED_HOSTS=0

Callback plugin

# test me
nixy, dense, or debug.
export ANSIBLE_STDOUT_CALLBACK=debug

Configuration

[defaults]
log_path=/var/log/ansible.log
#stdout_callback = yaml
stdout_callback = debug
# inventory = ./inventory
host_key_checking = False
retry_files_enabled = False
 
[ssh_connection]
retries=999999

Ansible syntax (YAML)
http://docs.ansible.com/ansible/YAMLSyntax.html

Configuration files
http://docs.ansible.com/ansible/intro_configuration.html#host-key-checking

/etc/ansible/ansible.cfg - global default configuration
~/.ansible.cfg - local global configuration
/etc/ansible/hosts - default inventory file

Ignore host key

sed -i 's|#host_key_checking = False|host_key_checking = False|g' /etc/ansible/ansible.cfg
 
# /etc/ansible/ansible.cfg or ~/.ansible.cfg file:
[defaults]
host_key_checking = False
 
# variable:
export ANSIBLE_HOST_KEY_CHECKING=False
 
# command line:
ansible-playbook -e 'host_key_checking=False' yourplaybook.yml
ansible-playbook -i myhost, all -a 'uname -a'
 
# set log file
export ANSIBLE_LOG_PATH=~/ansible.log 
 
# format debug output
export ANSIBLE_STDOUT_CALLBACK=debug

Copy SSH key to clients and install required applications

for HOST in $(cat /etc/ansible/hosts | grep -v "[\[|#]" | grep -v '^$' | sort -u); do
    ssh-copy-id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa.pub root@${HOST}
    ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${HOST} apt-get install -y sudo python
done

Run command for specific host

ansible-playbook /etc/ansible/playbooks/example.yml --limit www.example.com

import vs. include

import - statements are pre-processed at the time playbooks are parsed
include - statements are processed as they encountered during the execution of the playbook

Structure

site.yml
webservers.yml
fooservers.yml
roles/
   common/
     files/
     templates/
     tasks/
     handlers/
     vars/
     defaults/
     meta/
   webservers/
     files/
     templates/
     tasks/
     handlers/
     vars/
     defaults/
     meta/

Default with condition

my_var: "{{ 'foo' if my_condition else '' }}"
is_env_dev: '{% if (my_env == "dev") %}True{% else %}False{% endif %}'

Documentation

ansible-doc -l
ansible-doc apt -s

http://docs.ansible.com/ansible/test_strategies.html
http://docs.ansible.com/ansible/intro_adhoc.html
http://docs.ansible.com/ansible/playbooks_conditionals.html
http://docs.ansible.com/ansible/playbooks_roles.html

Modules
http://docs.ansible.com/ansible/lxc_container_module.html
http://docs.ansible.com/ansible/git_module.html
http://docs.ansible.com/ansible/apt_module.html
http://docs.ansible.com/ansible/cron_module.html
http://docs.ansible.com/ansible/list_of_database_modules.html

Variables
http://docs.ansible.com/ansible/playbooks_variables.html
# scopes
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-scopes
# Playbook environment variables
https://docs.debops.org/en/master/debops-playbooks/custom-environment.html

# ssh

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null
ssh_args = -o ForwardAgent=yes
 
# install python manual
https://www.toptechskills.com/ansible-tutorials-courses/how-to-fix-usr-bin-python-not-found-error-tutorial/
ansible host_name -i inventory_name -m raw -a "apt-get update && apt-get install -y python-minimal"
 
# configure valut
apg -a1 -m32 -n1 > ~/.ansible/.vault_pass.txt
echo "export ANSIBLE_VAULT_PASSWORD_FILE=~/.ansible/.vault_pass.txt" >> ~/.bashrc
# check vars
find *_vars -type f -exec cat {} \;
 
# check encryption
find -name "*.enc.*" -exec cat {} \;
 
# find encrypted values
find -name *.enc.* -exec ansible-vault view {} \; | grep foo
 
ansible-vault encrypt ~/ansible/host_vars/www.example.com.yml.enc
# https://dantehranian.wordpress.com/2015/07/24/managing-secrets-with-ansible-vault-the-missing-guide-part-1-of-2/

Lists vs. Dictionaries
https://everythingshouldbevirtual.com/automation/ansible-defining-variables-as-dictionaries/

# append values to list
https://blog.crisp.se/2016/10/20/maxwenzin/how-to-append-to-lists-in-ansible

vars:
    list_a:
      - name: user1
        comment: "User 1"
      - name: user2
        comment: "User 2"
    list_b:
      - name: user3
        comment: "User 3"
    # list_user_all: "{{ list_a + list_b }}"
  tasks:
    - name: Merge two lists
      set_fact:
        list_user_all: "{{ list_a + list_a }}"
 
    - name: Print merged lists
      debug:
        var: all_users

manage OpenWRT with Ansible

opkg install python-light openssh-sftp-server
opkg install python-light python-codecs python-logging python-openssl
opkg install python

Ansible command line options
https://liquidat.wordpress.com/2016/02/29/useful-options-ansible-cli/
ansible-playbook --syntax-check www.example.com.yml
ansible-playbook --list-hosts www.example.com.yml
ansible-playbook --list-tasks www.example.com.yml

Create customized module
http://blog.toast38coza.me/custom-ansible-module-hello-world/

nmcli module - NetworkManager command line tool
https://github.com/alcamie101/ansible-nmcli#examplesnmcli

LXC module
https://github.com/ansible/ansible-modules-extras/tree/devel/cloud/lxc
# Update lxc_container module to latest version
wget -q https://raw.githubusercontent.com/ansible/ansible-modules-extras/devel/cloud/lxc/lxc_container.py -O /usr/lib/python2.7/dist-packages/ansible/modules/cloud/lxc/lxc_container.py

shebang / execute playbook as script

#!/usr/bin/env ansible-playbook

Virtenv

ansible --version | grep "python version"
 
virtualenv ansible
source ./ansible/bin/activate
pip install ansible
 
virtualenv -p python3 ansible
source ./ansible/bin/activate
pip install ansible

Start job from step

ansible-playbook roles/hadoop_primary/tasks/main.yml ---start-at-task='start service 1'
# gradually
ansible-playbook roles/hadoop_primary/tasks/main.yml --start-at-task='start service 1' --step

Use python3
https://docs.ansible.com/ansible/2.4/python_3_support.html

ansible xxx -e 'ansible_python_interpreter=/usr/bin/python3'
 
# /etc/ansible/ansible.cfg
[defaults]
...
ansible_python_interpreter = /usr/bin/python

Configure pyton interpreter

- hosts: all
  tasks:
    - name: install pip
      apt:
        name: python-pip
      vars:
        ansible_python_interpreter: /usr/bin/python3
 
# in the scope of a playbook
- hosts: test_server
  vars:
    ansible_python_interpreter: /usr/bin/python2
  tasks:
    - name: install pip
      apt:
        name: python-pip
 
# for role
  roles:
    - role: my_role_1
      ansible_python_interpreter: /usr/bin/python3

Show formated output

export ANSIBLE_STDOUT_CALLBACK=debug
ansible-playbook --ask-become-pass ~/dev/ansible/pakonb.yml

Install Ansible in pyenv

http://www.panticz.de/index.php/pyenv
pyenv install 3.12.0
#sudo apt install python3-tk -y 
pyenv virtualenv 3.12.0 ansible
pyenv activate ansible 
python3.12 -m pip install --upgrade pip
pip install ansible openstacksdk

Fix / cleanup pyenv

rm -r /usr/local/lib/python2.7/dist-packages/ansible*

Start at task

ansible-playbook playbook.yml --start-at-task="install packages"

Create SHA512 password

openssl passwd -6

Jinja2 live parser
http://jinja.quantprogramming.com/

Configure python interpreter

# env var
export ANSIBLE_PYTHON_INTERPRETER=/usr/bin/python3
 
# /etc/ansible/ansible.cfg
[defaults]
...
ansible_python_interpreter = /usr/bin/python
 
# parameter on command line
ansible my-playbook.yml -e 'ansible_python_interpreter=/usr/bin/python2'

https://sleeplessbeastie.eu/2020/02/07/how-to-instruct-ansible-to-use-specific-version-of-python/

  hosts:
    debian10_python_default:
      ansible_host: 192.168.50.221
python_interpreter_test_defined:
  vars:
    ansible_python_interpreter: /usr/bin/python3
  hosts:
    debian10_python_defined:
      ansible_host: 192.168.50.221
      ansible_python_interpreter: /usr/bin/python2
    debian10_python_auto_legacy:
      ansible_host: 192.168.50.221
      ansible_python_interpreter: auto_legacy

debug

tasks:
  - debug:
      var: ansible_python_interpreter
    tags: always
  - debug:
      var: ansible_python_version
    tags: always

Override / extra vars from command line parameter

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
ansible-playbook release.yml--extra-vars '{"foo":"bar","var2":["one","two","three"]}'

Role

# role when condition
- hosts: webservers
  roles:
    - { role: some_role, when: "ansible_os_family == 'RedHat'" }

Run command / shell tasks in check "-C" mode (check_mode: no)

- command: lshw -json -c bus
  register: lshw_json
  changed_when: false      
  check_mode: no
  tags: always

Include vars

- hosts: all
  remote_user: root
  vars:
    favcolor: blue
  vars_files:
    - /vars/external_vars.yml

Variables include order

role defaults
inventory file or script group vars
inventory group_vars/all
playbook group_vars/all
inventory group_vars/*
playbook group_vars/*
inventory file or script host vars
inventory host_vars/*
playbook host_vars/*
host facts
play vars
play vars_prompt
play vars_files
role vars (defined in role/vars/main.yml)
block vars (only for tasks in block)
task vars (only for the task)
role (and include_role) params
include params
include_vars
set_facts / registered vars
extra vars

Define variabe by condition
https://serverfault.com/questions/907164/ansible-conditionally-define-variables-in-vars-file-if-a-certain-condition-is-m

# vars/main.yml
is_env_dev: '{% if (os_env == "dev") %}True{% else %}False{% endif %}'

Override / defining variables at runtime
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
ansible-playbook arcade.yml --extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
ansible-playbook release.yml --extra-vars "@some_file.json"

Json filter
https://blog.networktocode.com/post/ansible-filtering-json-query/
https://docs.ansible.com/ansible/latest/collections/community/general/docsite/filter_guide_selecting_json_data.html

Links
https://leucos.github.io/ansible-files-layout
https://galaxy.ansible.com/list#/roles
https://serversforhackers.com/an-ansible-tutorial
https://sysadmincasts.com/episodes/43-19-minutes-with-ansible-part-1-4
https://gist.github.com/andreicristianpetcu/b892338de279af9dac067891579cad7d
https://everythingshouldbevirtual.com/tags/#ansible
https://ansibledaily.com/
https://www.puzzle.ch/de/blog/articles/2020/01/22/10-dinge-ueber-ansible-die-du-vielleicht-noch-nicht-kanntest