Automating python deployment environments setup with ansible
Tags: ansible, devops, python
Published: 2020-08-26 13:18:00


## Prerequsites

#### to follow along with this post you would need the folowing installed on your machine

* [ansible](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-ubuntu-18-04)
* python3 (on your local machine and remote server).

 In this post i will show you how you can automate creating python deployment environment's using Ansible.

### But setting this up manually isn't a problem ?

say you have a web application that uses the flask framework, deploying this to an individual server manually wouldn't be a problem, scale this up to more than three applications with only slight variations in dependencies and things start to get pretty repetitive.This is where ansible comes in.

## What's this ansible thing anyway ?

Ansible is an open source automation tool that can be used for configuration management, application deployment and infrastructure provisioning,to mention a few.


## Ok lets do it then!

Start by creating the following folder structure.

```Bash
Directory_Name
├── ansible.cfg
├── inventory
├── requirements.txt
└── playbook.yml
``` 

Lets start with `ansible.cfg` this is where we would set configuration values that we want ansible to use when it runs.

`ansible.cfg`

```cfg
[defaults]
inventory = ./inventory
```

The above simply tells ansible to use the inventory file in the current directory.


### Whats an inventory file?

ansible uses this to determine what what machine you would like to run your playbooks against.

`inventory`

``` ini
[deployment server]
127.0.0.1
```

within the square brackets i specified the the name i would use to refer to a group of servers here i have just one but in practice `127.0.0.1` would be the ip address of the machines you want to run the playbooks.If you need to create a new group simply add another pair of square brackets and add the ip address of the targets machines below like above.If you would like to run this against your machine replace `127.0.0.1` with `127.0.0.1 ansible_connection=local`,which is what i did.


### Playbooks 

playbooks in ansible simply refer to where you define the tasks you want to execute on the remote machine, playbooks are written in Yaml which is a markup language.

`playbook.yml`

``` yaml
---
- hosts: all
  gather_facts: true
  tasks:
    - name: install dependencies from requirements.txt
      pip:
        requirements: requirements.txt
        chdir: .
        executable: pip3


    - name: additional dependency
        pip:
          name: gunicorn
          executable: pip3
```

we use `hosts` to indicate what group we want to run the playbook against here i used all to run against all the ip addresses  i have in my inventory, to run against a single group replace `all` with the name you placed within square brackets in the `inventory` ,ansible uses `gather_facts` to collect information about the target.

`tasks` is where we define what we actually want to do each task has a `name` which is used to make playbooks more readable and is also used in the output to indicate what task ansible is currently  executing.`pip3` is the ansible [module](https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html) we are using , when installing from a requirements.txt is i used `chdir` to tell ansible what path on my local machine the `requirements.txt` is located , in the second instance i pass the `name` of package i wish to install. you might want to install dependencies from a `requirements.txt` if you have specific version of your dependencies check out the ansible pip [docs](https://docs.ansible.com/ansible/latest/modules/pip_module.html) for more info.Now use `ansible-playbook playbook.yml`. Your output should look something like this 

```
ok: [127.0.0.1]

TASK [install dependencies requirements.txt] ***********************************
changed: [127.0.0.1]

TASK [additional dependency] ***************************************************
ok: [127.0.0.1]

PLAY RECAP *********************************************************************
127.0.0.1                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
```

`PLAY RECAP` is  a summary of the tasks that where executed, `ok` tells you the number of tasks that ran successfully , `changed` shows you how many tasks changed the state of the target machine in this case 1 because i have some of the dependencies installed. The rest are pretty self explanatory so i would not dive into them.

If you would like to take a look at the source files for this post you can find them in this [repository](https://github.com/s1ntaxe770r/ansible-demo.git)

If you're wondering where to go from here check out [this post](https://spacelift.io/blog/ansible-playbooks), that goes into more detail with Ansible tips and tricks 



#### In a future post i would show you how to deploy a simple web app using ansible, if you have any questions feel free to reach me on [twitter](https://twitter.com/s1ntaxe770r) or create an issue in the repo.