Ansible In Action

Ahmad Farag
5 min readAug 1, 2018

--

Ansible + Real World App

“Colorful software or web code on a computer monitor” by Markus Spiske on Unsplash

What Is Ansible?

is an open source software that automates software provisioning, configuration management, and application deployment.

The Keys Features of Ansible

Agentless

There is no software or agent to be installed on the client that communicates back to the server.

Idempotent

No matter how many times you call the operation, the result will be the same.

Simple and extensible

Ansible is written in Python and uses YAML for playbook language, both of which are considered relatively easy to learn.

Get Started

Installing and Running Ansible

# ubuntu 
sudo apt-get install ansible
#mac-OS
brew install ansible

For other OS check this link

Ansible Architecture

Modules

small programs that do some work on the server, so for example instead of running this command

sudo apt-get install htop

we can use apt module and install htop

- name: Install htop
apt: name=htop

Using module give you the ability to know if it’s installed or not.

Plugins

Plugins are pieces of code that augment Ansible’s core functionality. Ansible ships with a number of handy plugins, and you can easily write your own.

Host inventories

To provide a list of hosts, we need to provide an inventory list. This is in the form of a hosts file.

In its simplest form, our hosts file could contain a single line:

35.178.45.231  ansible_ssh_user=ubuntu

Playbooks

Ansible playbooks are a way to send commands to remote computers in a scripted way. Instead of using Ansible commands individually to remotely configure computers from the command line, you can configure entire complex environments by passing a script to one or more systems.

group_vars

file contains set of variables for example db username and password.

roles

Roles are a way to group multiple tasks together into one container to do the automation in very effective manner with clean directory structures

handlers

Handlers are lists of tasks, not really any different from regular tasks, that are referenced by a globally unique name, and are notified by notifiers. If nothing notifies a handler, it will not run. Regardless of how many tasks notify a handler, it will run only once, after all of the tasks complete in a particular play.

Tags

If you have a large playbook it may become useful to be able to run a specific part of the configuration without running the whole playbook.

Creating ubuntu Lightsail instance

Go to Lightsail Dashboard and click create Instance
Choose your favourite OS
Choose Add launch script which run once you created your instance , Don’t forget to get ssh-key

Installing Ansible prerequisites on our VPS

sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt-get update
sudo apt-get install -y python2.7 python3 python-pip
Add this sh commands to install Ansible requirements
Now you have your lighsail image up and running

Now we have our instance up and running lets start build our Ansible Project.

Adding instance ssh-key to git access keys

you have to add your server id_rsa.pub to your github ssh keys by login to your instance

Building our hosts and ansible.cfg

hosts.ini

ansible.cfg

Define a Role in Ansible

so i am using Ping module to just verify my host is working then i am going to update all packages and install two modules git and htop

Define a Handler

Installing PHP Modules

so to trigger handler in ansible we have to use notify: Restart PHP-FPM, handlers names should be unique — i have defined php as a tag so for example if you wanna run only this task from your play book you can run only this task by running your command with — tags=”php” which will only execute this task

Installing Nginx

Adding Nginx default config file

vars.yml

it’s recommended approach to use ansible-vault to encrypt and decrypt your vars

How to use Ansible-vault

Create vault secret file which contains encryption key which encrypts your var

touch .vault_pass.txt
echo 'YOUR_CONFIG_PASS' > .vault_pass.txt

Encrypt your vars

ansible-vault encrypt group_vars/vars.yml --vault-password-file .vault_pass.txt

Decrypt your vars

ansible-vault decrypt group_vars/vars.yml --vault-password-file .vault_pass.txt

Creating MySql DB, UserName and Password

mysql_user and mysql_pass are defined inside vars.yml

Clone our code base

repo_git_url and app_work_dir are defined inside vars.yml

Generating .env

Ansible uses Jinja2 templating to enable dynamic expressions and access to variables, lets create Template env.conf file

Lets define role to move this template to our application dir

Creating PlayBook

as we see i defines aws as host for this playbook, and sudo yes give you the ability to execute command as sudo user, we have vars_files where we store our vars ,we have set of roles each role does specific task and finally we have handlers which contain all project handlers

Run Your Playbook

#ansible-playbook playbookName
ansible-playbook code-deploy.yml
# run with specific tags
ansible-playbook playbook.yml --tags="env-files,php"
#if you are using ansible-valut
ansible-playbook code-deploy.yml --vault-password-file .vault_pass.txt

The Complete Project structure

├── ansible.cfg
├── code-deploy.yml
├── files
│ └── dump.sql
├── group_vars
│ └── vars.yml
├── handlers
│ └── main.yml
├── hosts.ini
├── logs
│ └── ansible-log.log
├── roles
│ ├── bootstrap-app
│ │ └── tasks
│ │ └── main.yml
│ ├── code-deploy
│ │ ├── tasks
│ │ │ ├── config-files.yml
│ │ │ └── main.yml
│ │ └── templates
│ │ └── env.conf
│ ├── misc
│ │ └── tasks
│ │ └── main.yml
│ ├── mysql
│ │ └── tasks
│ │ ├── config.yml
│ │ └── main.yml
│ ├── nginx
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ └── nginx.conf
│ ├── php
│ │ └── tasks
│ │ └── main.yml
│ └── redis
│ └── tasks
│ └── main.yml
├── scripts
│ ├── install_composer.sh
│ └── startup.sh
└── site.yml

Github Repo which contains the Complete Source Code.

This website up and running using this code base.

--

--