Why you should learn Ansible

Introduction

Hi everyone ! It’s been a while since I have write something here.
I think that my last post was in 2017 !

So today, I wanted to write you a little article about Ansible

Ansible is one of my favorite tool, I use it for automation in my current job but you can use Ansible to automate a lot of things !

image

Here are some example of things you can automate with Ansible :

  • Automate a new installation of Arch on your new laptop
  • Easily deploy a Web server on the cloud
  • Create reusable server for hacking
  • Create a Red teams infrastructure
  • etc …

Install Ansible

Ansible is a tool written in Python, to install ansible you will need to install Python and pip

Debian :
sudo apt install python3 python3-pip

Or Arch :
pacman -S python3 python3-pip

If you have python and pip install you can install Ansible with the following command :

pip3 install --user ansible

When the installation is done, you can test that ansible is correctly installed with the following commands :

ansible -m ping 127.0.0.1

You should have the following output :

ansible -m ping 127.0.0.1
[WARNING]: No inventory was parsed, only implicit localhost is available
127.0.0.1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Great ! You run your first Ansible command.

ansible -m ping 127.0.0.1 will just do a ping to 127.0.0.1

But I can run ping 127.0.0.1 to do that !

Well, it’s time to run more useful module

Ansible ad-hoc command

Ansible have two “mode” :

  • ad-hoc command
  • playbook

Ansible ad-hoc command can run single module on multiple host

Ansible playbooks are yaml files with multiple tasks that should be executed on a given host or group of hosts

Let’s look at how ansible ad-hoc command work first

Creating an Inventory file

Let’s pretend we want to install an nginx server on 4 Raspberry pi in our network :

We have 4 Raspberry pi

raspberry1: 10.0.0.1
raspberry2: 10.0.0.2
raspberry3: 10.0.0.3
raspberry4: 10.0.0.4

The user to log into our raspberry pi is pi and we have our ssh key in the authorize_hosts

You can use : ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected] to copy your key in the authorized_keys

So let’s create a new file named inventory.ini with the following content :

[Raspberry] # This line is the name we give to our group of host
10.0.0.1 # This is one of our Raspberry Host ip
10.0.0.2
10.0.0.3
10.0.0.4

[Raspberry:vars] # We can assign variable to ansible
ansible_user=pi # Here the username to connect to our raspberry

PS: Inventory file can be written in .ini or .yml, to keep this tutorial simple I have decided to write the inventory in .ini

So now that we have our inventory file we can try to run the last command we used against our Raspberry group

ansible -m ping -i inventory.ini Raspberry

you will have the following output :

 ansible -m ping -i inventory.ini Raspberry
10.0.0.1 | SUCCESS => {
  "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.2 | SUCCESS =>  {
  "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.3 | SUCCESS => {
  "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.4 | SUCCESS =>  {
  "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

Now, we know that we can reach all 4 Raspberry pi, let’s install nginx :

ansible -m apt -a "name=nginx state=present" -i inventory.ini Raspberry --become

So here we use the apt module : https://docs.ansible.com/ansible/latest/modules/apt_module.html

we give extra args to apt

name: is the name of the package we want to install here: nginx
state: is the state of the package, here we want to have nginx present on our raspberry
–become: is use to escalate to root to install nginx

When you run the command for the first time, the output will be

192.168.1.34 | CHANGED => {
  ...
}

If you run the command multiple time, the output will always be

192.168.1.34 | SUCCESS => {
    "cache_update_time": 1586104797,
    "cache_updated": false,
    "changed": false
}

Because nginx is already install, ansible will not try to reinstall nginx if the package is in the state you set before

if you want to uninstall nginx just replace present by absent.

Ansible playbook

Now that we have run some easy command to install nginx on our raspberry let’s make our first playbook

An Ansible playbook is a set of action use to run automate task, you can use all the module you used before in the ad-hoc command

let’s make a new directory

mkdir my-playbook

Create a new inventory file inside your new folder with the following content :

[localhost]
127.0.0.1

Now, let’s write an ansible playbook to install useful tools for CTF or HackTheBox machine

create a new file : install-hacker-tools.yml

---
- hosts: localhost 
  connection: local
  tasks:
    - name: Install hacker tools # Here is the name of our task 
      apt: # We use Apt module here 
        name: "{{ item }}" # Here we want to loop on multiple package
        state: present # We want all our package present on our system
      with_items: # Here is the block use to run loops
        - nmap
        - golang
        - git
    - name: Install Gobuster 
      shell: go get github.com/OJ/gobuster # Here we use shell module to run inline command

This file will install nmap, golang, git and gobuster on your local machine

you can run this playbook with :

ansible-playbook install-hacker-tools.yml -i inventory.ini -b

Now all the tools are installed on your machine

With some modification on the playbook and on your inventory, you can run this playbook on a group of hosts

If we have the following inventory :

[Raspberry]
10.0.0.1
10.0.0.2

[WebServer]
10.20.40.1
10.20.40.5

And the following playbook

---
- hosts: all
  tasks:
    - name: Install hacker tools
      apt:
        name: "{{ item }}"
        state: present
      with_items:
        - nmap
        - golang
        - git
    - name: Install Gobuster
      shell: go get github.com/OJ/gobuster

We can run the playbook only on our Raspberry group with the following command:

ansible-playbook install-hacker-tools.yml -i inventory.ini -b --limit Raspberry

Now you can play a little bit with ansible and automate cool things !

If you have question about ansible tweet me at L3akM3_0d4y !

9 Likes

Hi L3akM3-0day,
That’s a good introduction to how to use ansible.
What would you say to people who might read this and think “yeah, I can do all of that with a shell script once ssh is properly set up”?
Is there a good use case where you look at it and say “that is something I’d like to do, and if I don’t use ansible I’ll have to do a lot more work”?
Cheers

1 Like

Everything I can do with Ansible can be done with a simple python script or bash script.

If there is one thing I love about Ansible is it’s simplicity and the fact that you can write roles for different service.

If you need to automate the installation of a Webserver and a Database

you just need to write a playbooks like this :

- hosts: all
  roles:
    - webserver
    - Database

It’s easy to write and you can clearly see what this playbook will do.

It will Install a Webserver and Database role on all hosts specified in an inventory.

Another cool thing about Ansible is that you can run Ansible 1, 2 or 100 time and the result will always be the same.

Of course you can do that in bash but you need a little bit more work.

I think Ansible is somethings useful to learn for hacker, sysadmin and devs

I like to use Ansible and Terraform to deploy quick infrastructure on Digital Ocean

If I need to test a new Web Stack, I Can write a playbook to deploy the server on my Digital Ocean account, do all the test I need to do and stop it whenever I want so I can save a little bit of money when I don’t use the server

Hope I was clear ! :slight_smile:

4 Likes

wow
it’s so cool ,thank you to share this useful things.

1 Like

No problem ! I am here to share :grin:

1 Like

This is really cool - I’m actually working on a Packer image right now which does something very similar.

I just use the shell-inline feature (so its basically just a bash script) and I find that works pretty well for me in terms of speed of builds, but you do miss that modularity that you do get with ansible.

We should work together on my project, I call it “Axiom” :stuck_out_tongue: Hit me up on Discord.

1 Like

I have heard of Ansible here and there. I’m glad I came across this article.
Could you share the config files which you’ve actively used on your server in DigitalOcean?

1 Like

That was a good introduction, thank you .