First steps with Ansible.
Tags: webdev, devops, ansible, python
Published: 2023-01-20 23:26:17

[Ansible](https://www.ansible.com/) is one of the most recent tools released by Red Hat and one of the best choices for Developers and DevOps engineers to automate almost everything inside a new server. It is free and open-source, and trust me, configuring remote servers has never been so easy.

In this tutorial, I intend to show you how to install and start to use this powerful tool.

## Installing Ansible
First, you will need an Ansible controller host to manage all your nodes. This host could be your localhost, don't worry, Ansible will work no matter which operating system you use. I am using Ubuntu, but the installation steps for any other os are almost the same.

Let's install Ansible using apt.

```
$ sudo apt install ansible
```

Once the installation finished, run

```
$ ansible --version
```

If the package installation was successful, you should see something like this.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qopp9qnzix9huh1ji44v.png)


## Ansible nodes
Now your ansible controller is working, pretty easy right?
Let's set up your nodes, open the `/etc/ansible/hosts` file with your preferred editor, you should see this template

```
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups
# Ex 1: Ungrouped hosts, specify before any group headers.
#green.example.com
#blue.example.com
#192.168.100.1
#192.168.100.10
# Ex 2: A collection of hosts belonging to the 'webservers' group#[webservers]
#alpha.example.org
#beta.example.org
#192.168.1.100
#192.168.1.110
# If you have multiple hosts following a pattern you can specify
# them like this:
#www[001:006].example.com# Ex 3: A collection of database servers in the 'dbservers' group
#[dbservers]
#
#db01.intranet.mydomain.net
#db02.intranet.mydomain.net
#10.25.1.56
#10.25.1.57# Here's another example of host ranges, this time there are no
# leading 0s:#db-[99:101]-node.example.com
```

You can add your hosts at the bottom of the file or delete all the content and replace it with your hosts. The only rule is to follow the syntax below.

```
# Linux host
# host_alias ansible_host=<host_ip_or_url> ansible_connection=ssh ansible_user=<host_user> ansible_ssh_pass=<ssh_password_for_user>
# Windows host
# host_alias ansible_host=<host_ip_or_url> ansible_connection=winrm ansible_user=<host_user> ansible_password=<password_for_user>
# I am adding two servers, both of them are Linux servers
web1 ansible_host=my.webserver.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Passw0rd
db1 ansible_host=my.databaseserver.com ansible_connection=ssh ansible_user=root ansible_ssh_server=Passw0rd
```

Now, add some groups for your servers. Groups let you run commands and scripts on multiple hosts simultaneously.

```
[web_nodes]
web1 ansible_host=my.webserver.com ansible_connection=ssh ansible_user=root ansible_ssh_pass=Passw0rd
[db_nodes]
db1 ansible_host=my.databaseserver.com ansible_connection=ssh ansible_user=root ansible_ssh_server=Passw0rd
```

Save your changes and close the file.

Ansible depends on sshpass package, install it running the following command

```
$ sudo apt install sshpass
```

The only remaining step is to connect to your hosts through ssh; this is for adding your host's fingerprints to the `~/.ssh/known_hosts` file.

```
$ ssh root@my.webserver.com
$ ssh root@my.databaseserver.com
```

Now, try your hosts by running:

```
$ # Ansible has an 'all' group which contains all your defined hosts
$ ansible all -m ping
```

If everything is going well, you will see a similar output


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3iipj9f15le9mr6d83ah.png)

## Running playbooks
Your hosts are ready to be used through Ansible. Please create a new folder in your home directory.
```
$ mdkir ~/ansible-tutorial
$ cd ~/ansible-tutorial
```
Ansible's scripts are just YAML files. If you have worked with YAML before, this step will be straightforward.
Open a new playbook.yml file and add the following lines

```
- name: My playbook
  hosts: web1
  tasks:
  - name: Runnig date
    command: date
```

- `name` is an alias for the playbook
- `hosts` defines the hosts to run the playbook, can be a group
- `tasks` is an array that holds the actions or modules to use

Save your changes and close the file, now run it with
`$ ansible-playbook playbook.yml`
You should see a similar output as below


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhwumywrcbzbhicrl4ko.png)


## A simple, real-life example

You learned some new things so far
- Install and configure an Ansible controller
- Add a new playbook
- Run it on your hosts

Now it is time to learn how we can use Ansible in a real-life scenario.
For this example, you are going to install and run an Nginx webserver.
Let's create a new playbook

```
$ vim nginx-playbook.yml
```

To start to write this playbook, add a name and the host where the Nginx should be running (remember the identation)

```
- name: 'Install and deploy nginx'
  hosts: web1
```
Now, add the tasks, in this case you will need to define two actions.
Install the latest Nginx version
Start Nginx server

```
tasks:
  - name: 'Install Nginx latest version'
    apt:
      name: nginx
      state: latest
```
This task looks for Nginx on the target host. If Ansible finds Nginx's latest version, the installation won't happen.

```
- name: 'Run Nginx'
    service:
      name: nginx
      state: started
```
And this task checks if the Nginx server is already running. If it is not, then the step is skipped.
Your complete nginx-playbook.yml should look like this

```
- name: 'Install and deploy nginx'
  hosts: web1
  tasks:
    - name: 'Install Nginx latest version'
      apt:
        name: nginx
        state: latest
    - name: 'Run Nginx'
      service:
        name: nginx
        state: started
```
Save your changes, and now, try it!
Since we are installing a package in your host, you will need to add the '-b' flag to the playbook command.

```
$ ansible-playbook nginx-playbook.yml -b 
$ # -b or --become grants root privileges to ansible user.
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2n2qgxp3dtwjo578bq93.png)


And finally let's check the browser!


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f8ry7njzete8r5z7jvdu.png)


## Conclusion
Ansible is a great ally; it makes it easy to install and deploy things in all your servers. Sure, this is just an introductory tutorial, but this tool has one module for everything you need to automate. You can find all always available [here](https://docs.ansible.com/ansible/2.8/modules/list_of_all_modules.html).


Thanks for reading. Every feedback, comment, or sharing is highly appreciated!