Ansible is an open-source tool that enables the automation, configuration, and orchestration of infrastructure. It fully embraces the concept of Infrastructure as Code. We can build out our entire system in code, store all code in source control, do a roll-back or even share our code with other team members.
Key points to note:
- Ansible is written in Python
- Script commands use YAML syntax
- No need for server agents, sends commands to nodes via SSH, sequentially to each node. Each node runs commands in parallel.
Installation
Ansible is super easy to install. You need to install it on the control machine only [the machine from which you will be running the commands]. Ansible recommends using a Linux/Unix-based machine as a control machine, but it can work on Windows machines too (won’t be covering that in this post). Ensure that you have python on the machine.
# python3 -V
Python 3.7.2
# sudo pip3 install ansible
.
.
# ansible --version
ansible [core 2.11.0]
config file = none
configured module search path = ['/Users/<user>/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
ansible collection location = /Users/<user>/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.9.0 (default, Oct 27 2020, 14:15:17) [Clang 12.0.0 (clang-1200.0.32.21)]
jinja version = 2.11.2
libyaml = True
That’s it! It might take few minutes to complete.
Ansible Inventory – hosts file
Ansible reads information about machines to manage from the inventory file, which is by default here – /etc/ansible/hosts
. It is possible to pass a non-default inventory file by using the -i
option along with the ansible command or we can mention that in the ansible config file.
Eg: ansible -i hosts-dev --list-hosts all
Although it is possible to pass an IP address to an ad hoc command, you need inventory to take advantage of the full flexibility and repeatability of Ansible.
Sample hosts file:
# hosts-dev
[webservers]
app1 ansible_host=52.89.23.70
app2 ansible_host=50.11.50.8
[loadbalancers]
lb1 ansible_host=35.81.19.106
[local]
control ansible_connection=local
Ansible (global) Config file
You can use the Ansible config file in your Ansible directory to set global configurations which are common to all nodes.
Sample config file:
# ansible.cfg
[defaults]
inventory = ./config/hosts-dev # setting custom inventory
remote_user = ec2-user #for AWS instances
private_key_file = ./serverkey.pem #for AWS instances
host_key_checking = False
retry_file_enables = False
Sample Commands
# ansible -m ping all <-- tries to ssh in to all machines listed in the hosts file
# ansible -m ping webservers <-- tries to ssh in to all machines listed under the group webservers in the hosts file
# ansible -m shell -a "uname -a" webservers:loadbalancers <-- runs uname -a command in all the servers listed under the groups webservers and loadbalancers
Ansible Playbooks
Playbooks contain a list of tasks, like a to-do list for Ansible. They contain the steps which the user wants to execute on a particular machine. Playbooks are run sequentially.
Example 1: Ping all the servers in the hosts file
# ping.yml
---
- hosts: all
tasks:
- name: Ping all servers
action: ping
Example 2: run uname command on all the servers in the hosts file
# uname.yml
---
- hosts: webservers:loadbalancers
tasks:
- name: Get OS type
shell: uname
References
- Ansible Documentation: https://docs.ansible.com/ansible/latest/user_guide/index.html
- Ansible Modules: https://docs.ansible.com/ansible/4/collections/index_module.html
- Ansible Galaxy: https://galaxy.ansible.com/
- Using Variables in Playbooks: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
Will be adding the following dedicated pages soon:-
1. Ansible inventory file.
2. Ansible Playbooks.
3. Customizing Ansible config file.
4. Ansible commands
5. Ansible Roles
6. Ansible Galaxy