Ansible Part 1 - Introduction to Ansible
Start using Ansible, the easy IT Automation Tool by Redhat
MEDIUM X-POST: This blog is cross-posted on Medium. If you are a Medium member and want to read on Medium please click here LINK
What is Ansible?
Ansible is an IT automation tool that allows you to use configuration as code to manage your servers (physical and virtual).
It is open-source, easy to use and made by RedHat.
If you have any questions, comments or issues with the tutorial please post a comment.
What's included in this tutorial?
In this walk through you will be introduced to the basic concepts of Ansible and run, not one, but two playbooks!
You will learn:
- How to ping your target host.
- How to write a basic inventory and playbook
- How to install a service (nginx) on a target host
- How to modify that service and restart it
Dependencies
- This tutorial assumes you have the following set up:
- A Control Host (must be linux)
- One or more Target Hosts (to follow this tutorial they must be linux)
- The Public IP Address of each Target Host (or a private connection)
- The SSH key to access each Target Host
- You can follow the steps in this blog to help you get prepared. Preparing for Ansible
Tutorial
A basic Ansible playbook execution requires the following components:
- An inventory which provides connection information to your target hosts.
- A playbook which has the tasks you want to run.
You can also run modules directly from the command line which can be useful for certain tasks.
Step 1 - Set up Inventory
Inventories are used to define target machines. You can specify groups and names defined in inventories as targets in your playbooks.
Create the below inventory file in your user directory
1
2
3
4
mkdir ~/intro-to-ansible
nano ~/intro-to-ansible/inventory.yml
# copy in the example inventory
Use this example inventory file, be sure to replace the sections with your information.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
test_group:
hosts:
node1:
ansible_host: <insert_ip>
vars:
ansible_ssh_private_key_file: <path_to_private_key_file>
ansible_user: <user_you_set_up_on_vm>
ansible_python_interpreter: /usr/bin/python3
alternative_group:
hosts:
node1:
This inventory file defines:
- a single target host:
node1
- the connection information to allow the control host to connect to the target host
- two groups
test_group
andalternative_group
Groups allow you to easily target different sets of hosts for different purposes
Step 2 - Test you can reach your target hosts
First we are going to test you can ping your target host. We are going to do this by directly calling the ping module.
Modules are units of code that perform actions on the target machine. They can be used on the CLI or more typically in tasks.
This command tests you can ping all hosts specified in the inventory file.
1
2
HOST_GROUP=test_group
ansible $HOST_GROUP -m ping -i ~/intro-to-ansible/inventory.yml
This command tests you can ping a specific host in the inventory file.
1
2
HOST=node1
ansible $HOST -m ping -i ~/intro-to-ansible/inventory.yml
EXPECTED OUTPUT: you should see ansible output in your cli with a response of PONG to your PING!
Step 3 - Set up your first playbook
Playbooks are the instructions to be carried out by ansible. They contains plays which are in turns comprised of a set of tasks. Playbooks are written in YAML.
Create the first playbook in your directory
1
nano ~/intro-to-ansible/myFirstPlaybook.yml
Populate the playbook file with the below yaml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
---
- name: My first playbook
hosts: test_group
become: true
gather_facts: true
tasks:
- name: Update apt
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
- name: Install Nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Start Nginx
ansible.builtin.service:
name: nginx
state: started
- name: Visit the NGINX homepage
ansible.builtin.uri:
url: http://localhost
status_code: 200
return_content: true
register: output
- name: Print the output of the homepage
ansible.builtin.debug:
var: output
This playbook:
- Installs nginx
- Starts the service
- Performs a get on the local address for the service
- Prints out the results
You can see in this playbook several important features:
- hosts: defines the target of the playbook
- tasks: sets the list of tasks for the play.
- arguments: in each task you can see key: value pairs which are arguments for the task. These can be required or optional variables and alter the command.
Step 4 - Run your first playbook
- Run the playbook you created
1
ansible-playbook -i ~/intro-to-ansible/inventory.yml ~/intro-to-ansible/myFirstPlaybook.yml
EXPECTED OUTPUT: you should see a play recap saying things have succeeded.
Step 5 - See nginx deployed to your target host
Go to your browser and enter the public ip of your machine - you should now see the NGINX home page
EXPECTED OUTPUT: A generic nginx homepage
Step 6 - Test Ansible Idempotency
Ansible aims to be an Idempotent tool which means that you can run it multiple times and it should not make any changes beyond the first application as long as the state has not changed.
Run the first playbook again and you should see that the output has changed=0
. This shows Ansible’s idempotency.
1
ansible-playbook -i ~/intro-to-ansible/inventory.yml ~/intro-to-ansible/myFirstPlaybook.yml
EXPECTED OUTPUT: you should see a play recap where the number of changes is 0.
Step 7 - Run second playbook
In this second playbook we are going to update the home page of the nginx deployment.
This will involve copying over an updated index page, templating in a value and restarting the service.
Templates are used in Ansible to enable dynamic configuration and inputting into documents. Ansible uses Jinja2 for templating.
- Create the playbook in your directory
1
nano ~/intro-to-ansible/mySecondPlaybook.yml
- Populate the playbook file with the below yaml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
---
- name: My second playbook
hosts: alternative_group
gather_facts: true
tasks:
- name: Copy over the template
ansible.builtin.template:
src: ./index.html.j2
dest: /var/www/html/index.nginx-debian.html
become: true
vars:
my_name: "Jack"
- name: Restart Nginx
ansible.builtin.service:
name: nginx
state: restarted
become: true
- name: Print number of processor cores
ansible.builtin.debug:
var: ansible_processor_cores
- name: Print number of processor cores
ansible.builtin.debug:
var: ansible_facts['processor_cores']
- name: Print hostname
ansible.builtin.debug:
msg: "This computer is called: "
- name: Visit the NGINX homepage
ansible.builtin.uri:
url: http://localhost
status_code: 200
return_content: true
register: output
- name: Print the output of the homepage
ansible.builtin.debug:
var: output
3. Create the new index page in your directory
The page needs to be in the same directory as your playbook or you need to alter the referencing in the playbook.
1
nano ~/intro-to-ansible/index.html.j2
4. Populate the page with the below code, adding in your name:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to {{ my_name }}'s nginx!</h1>
<p>If you see this page, I have successfully edited the nginx web server using Ansible.</p>
</body>
</html>
5. Run the playbook
1
ansible-playbook -i ~/intro-to-ansible/inventory.yml ~/intro-to-ansible/mySecondPlaybook.yml
EXPECTED OUTPUT: You should see the playbook run successfully and if you visit the IP address of the VM then you should see the updated home page of NGINX.
Step 8 - Cleanup
- Go and delete any VMs you created for the lesson - see section 4 of Preparing for Ansible
- If you have exposed any VMs on the public internet, then consider removing the connection if it is no longer required.