====== Ansible ======
===== Installing =====
RHEL has ansible-core, podman, and ansible-navigator in the OS repositories.
Ubuntu needs a PPA:
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y
It can also be installed with Python
sudo apt install python3-pip -y
pip3 install ansible
===== Inventory and Config =====
The config is read from: ANSIBLE_CONFIG, ./ansible.cfg, ~/ansible.cfg, /etc/ansible/ansible.cfg
Ansible will not automatically load a config file from the current working directory if the directory is world-writable.
[defaults]
inventory = ./ansible_hosts # relative to path of ansible.cfg
nocows = True
interpreter_python = /usr/bin/python3
gathering = False
forks = 2
strategy = free
host_key_checking = False
[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
The default inventory path is /etc/ansible/hosts
genpurpose1host.localdomain # ungrouped
[web]
webserver1 ansible_host=webserver1.localdomain ansible_port=2022 ansible_user=webadmin
localhost ansible_connection=local
[worker]
worker1
[app:children]
web
worker
[all:vars]
ansible_connection=ssh
ansible_ssh_user=myuser
ansible_ssh_private_key_file=my_ssh_key
#ansible_ssh_pass=mypass
#ansible_become_pass=mypass
# Before Ansible 2.0, ansible_user was ansible_ssh_user
===== Executing =====
For ad-hoc execution:
ansible localhost -m ansible.builtin.gather_facts # Test
ansible -i inventory all -m shell -a 'echo "A"' # Execute a shell command
ansible -a 'some_command' # The module defaults to "command" (instead of "shell")
ansible -i inventory all -m shell -a 'echo "A"' --limit server1 # To run only on server 1
# -f 5 # To run 5 tasks at a time
For playbook execution:
ansible-playbook playbook1.yaml
===== Playbooks =====
---
- name: Play 1
become: true
hosts: all
tasks:
- name: Task 1
yum_repository:
name: epel
description: epel yum repo
baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
gpgcheck: no
- name: Task 2
dnf:
name: httpd
state: latest # present|absent|latest
- name: Task 2
dnf:
name:
- net-tools
- bind-utils
- telnet
- nmap
- vim-enhanced
- sysstat
- tuned
- numactl
- name: Task 3
dnf: name=http://example.com/some_package.rpm
- name: Task 4
apt_repository:
repo: deb http://archive.canonical.com/ubuntu hardy partner
state: present
- name: Task 5
apt:
name: foo
update_cache: yes
state: present
- name: Task 6
apt:
deb: https://example.com/some_package.deb
- name: Task 7
copy:
src: file1
dest: /tmp/file1
remote_src: true
- name: Task 8
template:
src: file1.j2
dest: /tmp/file1
vars:
var1: 1
- name: Task 8
shell: |
command1
command2
- name: Task 7
file:
path: /tmp/dir1
state: directory
owner: root
group: root
mode: "0777"
- name: Task 8
sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: true
state: present
reload: true
- name: Task 8
selinux:
policy: targeted
state: permissive
- name: Task 8
service:
name: firewalld
state: stopped # started|stopped|reloaded|restarted
enabled: no
- name: Task 8
get_url:
url: http://example.com
dest: /tmp/file1
environment:
http_proxy: https://example.com:8080
https_proxy: https://example.com:8080
- name: Task 6
local_action: echo "Hello"
- name: Task 6
script: /tmp/script1
- name: Task 6
lineinfile:
path: /tmp/file1
regexp: '^db=$'
line: db=localhost
# Tasks to get the output from one command and use as conditional for another command
- name: Check ping
delegate_to: srv1
shell: ping -c 1 somehost
register: reachableping
ignore_errors: true
- name: Do something
delegate_to: srv1
shell: ./run_cmd_1
ignore_errors: true
when: "'100.0% packet loss' in reachableping.stdout"
# Variables can be used for an entire block
- name: Demonstrate environment variable in block
hosts: localhost
connection: local
gather_facts: false
vars:
motd: Hello World
tasks:
- block:
- name: Print variable
shell: "echo $motd"
register: theoutput
- debug: var=theoutput.stdout
environment:
motd: "{{ motd }}"
===== Ansible Navigator =====
Ansible Navigator uses podman to create an EE environment to run the Ansible playbooks and provides a text user interface to navigate through the documentation, inventory, and execution results.
Install Ansible Navigator with:
pip3 install ansible-dev-tools ansible-navigator --user
# or
dnf install \
--enablerepo=ansible-automation-platform-2.2-for-rhel-8-x86_64-rpms \
ansible-navigator
Use it with:
ansible-navigator run playbook1.yaml
ansible-navigator doc service # Type ":{{ examples }}" to scroll to the example section of the doc
ansible-navigator doc service -m stdout # Getting output to stdout lets you use standard tools to search
===== Common Ansible Problems =====
ERROR: Ansible requires the locale encoding to be UTF-8; Detected ISO8859-1.
Set the following environment variables within the shell before running ansible / ansible-playbook
LANG="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
===== Also See =====
* [[http://miro.borodziuk.eu/index.php/2020/03/09/ansible-delegation/|Ansible Delegation]]
* [[http://miro.borodziuk.eu/index.php/2020/02/13/ansible-vault/|Ansible Vault]]
* [[http://miro.borodziuk.eu/index.php/2020/02/12/ansible-galaxy/|Ansible Galaxy]]
* [[http://miro.borodziuk.eu/index.php/2020/03/22/ansible-paralellism/|Ansible Parallelism]]
* [[https://www.redhat.com/sysadmin/faster-ansible-playbook-execution|8 Ways to Speed Up Your Ansible Playbooks]]
* [[https://www.redhat.com/sysadmin/faster-ansible-modules|5 Ways to Make Your Ansible Modules Work Faster]]