Ansible
Introduction
Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code.
It is used to deploy and maintain many servers at once, from the command line.
- Control Node = Admin Computer
- Host Node = Remote Server
How To Install and Configure Ansible on Ubuntu 20.04
Requirements
Python 2.6+ or Python 3.5+
Installation
sudo apt remove ansible python3 -m pip install ansible echo "export PATH=$PATH:$HOME/.local/bin" >> ~/.bashrc source ~/.bashrc ansible-galaxy collection install community.docker
Configuration
Add your hosts...
sudo nano /etc/ansible/hosts
[servers] myserver ansible_host=123.456.789.0 [all:vars] ansible_python_interpreter=/usr/bin/python3
Check the config...
ansible-inventory --list -y
all: children: servers: hosts: myserver: ansible_host: 123.456.789.0 ansible_python_interpreter: /usr/bin/python3 ungrouped: {}
Check the config with hosts file specified...
ansible-inventory --list -y -i ./inventory/hosts
Testing
List Hosts
./inventory/hosts
[servers] server1 ansible_connection=ssh ansible_user=username1 domain.uk ansible_connection=ssh ansible_user=username2 nas ansible_connection=ssh ansible_user=username3
ansible -i ./inventory/hosts servers --list-hosts hosts (3): server1 domain.uk nas
Ping
ansible -i ./inventory/hosts servers -m ping ansible -i ./inventory/hosts server1.mydomain.com -m ping
Echo
Get all hosts to output a word on the command line...
ansible all -a "/bin/echo hello" -i ./inventory/hosts
Uptime
Uptime for a single host...
ansible hostname -m command -a "uptime" -i ./inventory/hosts
Uptime for all hosts in a group...
ansible groupname -m command -a "uptime" -i ./inventory/hosts
Uptime for all hosts...
ansible all -m command -a "uptime" -i ./inventory/hosts
AWS SSH Key
ansible all -m ping -u ubuntu --private-key=~/.ssh/myserver.pem
myserver | SUCCESS => { "changed": false, "ping": "pong" }
Commands
You can perform one off commands on a single host or multiple hosts.
Hostname
ansible all -u ubuntu --private-key=~/.ssh/myserver.pem -a "hostname -f"
Update Package Cache
ansible all -u ubuntu --private-key=~/.ssh/myserver.pem -a "sudo apt-get update"
Playbooks
Playbooks are YAML text files which contain commands and options in a text file, just like a docker compose file.
The file contains 'modules' which perform different tasks.
Examples
See if hosts are alive by using only Gather Facts
99_gather.yml
- name: gather facts become: true hosts: all
... and run it on all but 1 host (by using the limit option with an exclamation mark (!host) (!host1:!host2)...
ansible-playbook -i ~/Bin/ansible-homelab/inventory/hosts ~/Bin/ansible-homelab/playbooks/ubuntu/99_gather.yml --limit '!server1'
Update Package List and Upgrade System
Create hosts file...
./inventory/hosts
[servers] server1 ansible_connection=ssh ansible_user=user1 server2 ansible_connection=ssh ansible_user=user2 server3 ansible_connection=ssh ansible_user=user3
Check the list of hosts is readable..
ansible -i ./inventory/hosts all --list-hosts
Create the playbook file...
./playbooks/apt.yml
- hosts: "*" become: yes tasks: - name: apt apt: update_cache: yes upgrade: 'yes'
Run the playbook command...
ansible-playbook ./playbooks/apt.yml -i ./inventory/hosts
To run this playbook on a single host or multiple hosts, you would use the -l (limit) option at the end of the command line...
ansible-playbook ./playbooks/apt.yml -i ./inventory/hosts -l server1 ansible-playbook ./playbooks/apt.yml -i ./inventory/hosts -l server1,server2
Create single directory using the 'file' module
Create the playbook...
nano mkdir.yml
- hosts: all tasks: - name: Ansible file module create directory file: path: ~/backups state: directory
Run the playbook (dry run)...
ansible-playbook -C mkdir.yml
Run the playbook...
ansible-playbook mkdir.yml
Create multiple directories using the 'file' module
Create the playbook...
nano mkdirs.yml
- hosts: all tasks: - name: Ansible create multiple directories with_items file: path: ~/backups/{{item}} state: directory with_items: - 'mysql' - 'repository' - 'config'
Run the playbook...
ansible-playbook mkdirs.yml
https://linuxhint.com/create-directory-ansible/
Install Apache web server software and start it on a Red Hat based system
- name: Playbook hosts: webservers become: yes become_user: root tasks: - name: ensure apache is at the latest version yum: name: httpd state: latest - name: ensure apache is running service: name: httpd state: started
Touch a file based on the date of another file
- hosts: alpine become: yes tasks: - name: Get stats of a file ansible.builtin.stat: path: /usr register: usr - name: Print a debug message ansible.builtin.debug: msg: "Path exists and is a directory" when: usr.stat.isdir is defined and usr.stat.isdir - name: Print a debug message ansible.builtin.debug: msg: "ctime is {{ usr.stat.ctime }}" - name: touch file /root/misc/system_installed file: path: /root/misc/system_installed state: touch modification_time: '{{ "%Y%m%d%H%M.%S" | strftime(usr.stat.ctime) }}'
Variables
Standard variables
{{ ansible_facts["eth0"]["ipv4"]["address"] }}
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
Custom variables
Example 1 - run the WordPress command line tool to install or update the software...
ansible-playbook wp.yml --extra-vars "major=true installcli=true"
wp.yml
- name: Install WordPress Cli register: wpclidonwloaded become: yes when: installcli is defined get_url: url: https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar dest: "{{ wpclipath }}" mode: '0755' owner: "{{ wpcliuser }}" group: "{{ wpcligroup }}" - name: Update WordPress Core (Major version) command: "{{ wpclipath }} core update" when: major is defined args: chdir: '{{ projects[inventory_hostname].blog_folder }}'
Example 2 - create a folder from a one-off command line custom variable...
ansible-playbook website.yml --extra-vars "domain=mybusiness.com"
website.yml
- name: create directory for web site file: path: "/var/www/{{ domain }}" state: directory