Ansible is a tool for automating provisioning, configuration, and deployment across multiple hosts via SSH.
Installing Ansible on Ubuntu 20.04
sudo apt update -y sudo apt install ansible -y
Installing Ansible on CentOS 8
yum update -y yum install epel-release -y yum install ansible -y
Add the hosts at the end of /etc/ansible/hosts:
[servers] 192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 [servers:vars] ansible_user=root
Create and transfer the root SSH key:
ansible all --list-hosts ssh-keygen -t rsa -C "[email protected]" ssh-copy-id 192.168.1.1 ssh-copy-id 192.168.1.2 ssh-copy-id 192.168.1.3 ssh-copy-id 192.168.1.4
Running simple commands with Ansible:
ansible-inventory --list -y ansible servers -m ping ansible servers -a "apt update" ansible servers -a "apt upgrade -y" ansible all -m ping -u root
Check the full list of modules in the Ansible documentation [Link].
PLAYBOOK
nano playbook1.yaml
A playbook is made up of one or more plays, and each play contains one or more tasks.
Use the template below and customize as needed:
---
- name: PLAYBOOK ONE
hosts: servers
remote_user: root
become: true
pre_tasks:
- name: APT UPDATE
apt:
update_cache: yes
when: ansible_distribution == "Ubuntu"
tasks:
- name: INSTALL LOCATE
apt:
name: locate
state: latest
- name: COPY FILE
tags: webserver,apache
copy:
src: /data/site.html
dest: /var/www/html/index.html
owner: root
group: root
mode: 0644
- name: START SERVICE
service:
name: cron
state: started
- name: REMOVE LOCATE
apt:
name: locate
state: absent
when: ansible_distribution in ["Debian","Ubuntu"]
- name: INSTALL UNZIP
package:
name: unzip
- name: DOWNLOAD AND EXTRACT A ZIP
src: https://example.com/file.zip
dest: /root
remote_src: yes
mode: 0755
owner: root
group: root
- name: START SERVICE
service:
name: httpd
state: started
enabled: yes
- name: CHANGE VARIABLE DATA IN FILE
lineinfile:
path: /etc/nginx/nginx.conf
regexp: '^server_name'
line: server_name example.com;
register: webserver_admin_email
- name: RESTART IF CONFIG CHANGED ABOVE
service:
name: nginx
state: restarted
when: webserver_admin_email.changed
- name: PLAYBOOK TWO - USERS MANAGEMENT
hosts: all
become: true
tasks:
- name: CREATE USER
user:
name: username
groups: groupname
- name: ADD SSH KEY
user:
name: username
key: "copy and paste the key here"
Dry-run first, then execute the playbook:
ansible-playbook playbook1.yaml --check ansible-playbook playbook1.yaml
Check mode can also be set directly inside a play:
check_mode: yes OR check_mode: no
Other useful commands:
ansible all -m gather_facts ansible all -m gather_facts --limit 192.168.1.1 ansible all -m apt -a update_cache=true --become --ask-become-pass ansible all -m apt -a name=locate --become --ask-become-pass ansible all -m apt -a "name=locate state=latest" --become --ask-become-pass ansible all -m apt -a upgrade=dist --become --ask-become-pass
ROLES
A playbook can be split into sections called roles to make it easier to manage.
- name: ROLES THAT APPLY TO SERVERS hosts: servers become: true roles: - base_role - server_role - name: ROLES THAT APPLY TO WORKSTATIONS hosts: workstations become: true roles: - base_role - workstation_role
HANDLERS
- name: CHANGE VARIABLE DATA IN FILE
lineinfile:
path: /etc/nginx/nginx.conf
regexp: '^server_name'
line: server_name example.com;
notify: restart_nginx
File structure for roles with tasks and handlers:
roles/ base_role/ tasks/main.yml handlers/main.yml server_role/ tasks/main.yml handlers/main.yml workstation_role/ tasks/main.yml handlers/main.yml
PLAYBOOK OPTIMIZATION
Use callback plugins to identify tasks that may be slowing down the playbook.
In ansible.cfg, add:
[defaults]
inventory = ./hosts
callbacks_enabled = timer, profile_tasks, profile_roles
The forks setting controls how many tasks run in parallel.
In ansible.cfg, add the desired number:
[defaults] inventory = ./hosts forks=25
Or set it at runtime:
ansible-playbook playbookName.yaml --forks 25
Reuse established SSH connections for a set period to reduce overhead:
[ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=30s
In a controlled environment, you can disable host SSH key checking to improve performance:
[defaults] host_key_checking = False
To allow tasks to run across servers without waiting for all hosts to finish each step:
--- - name: PLAYBOOK hosts: all strategy: free
PULL
Instead of pushing configuration from a manager host, Ansible can pull a configuration file from a Git repository and run it locally:
ansible-pull -U http://example.com/file.git
BONUS
Ansible has no built-in graphical interface, but pairing it with Ansible Semaphore greatly improves the user experience [Link].