Understanding sample application
Throughout the book, we will give examples of how to deploy an application on the infrastructure created by the Ansible playbooks. We have written a simple phone book application using Python's flask framework (http://flask.pocoo.org). The phone book application listens on port 8080
and we can use any browser to use the phone book. The app has two variations, one uses SQLite as a database whereas the other one uses MySQL. The application code remains the same, we have just used different databases to demonstrate the application running in a single compute instance and it running across multiple instances or even different components of a cloud provider.
The application code can be obtained from:
- Phone book SQLite: https://github.com/ansible-cookbook/phonebook-sqlite
- Phone book MySQL: https://github.com/ansible-cookbook/phonebook-mysql

How to do it…
The application deployment can be done using Ansible. If we are going to deploy the application using SQLite then the following tasks for the phonebook role are good enough:
--- - name: install epel repository package: name: epel-release state: present - name: install dependencies package: name: "{{ item }}" state: present with_items: - git - python-pip - gcc - python-devel - name: install python libraries pip: name: "{{ item }}" state: present with_items: - flask - flask-sqlalchemy - flask-migrate - uwsgi - name: get the application code git: repo: [email protected]:ansible-cookbook/phonebook-sqlite.git dest: /opt/phone-book - name: upload systemd unit file copy: src: phone-book.service dest: /etc/systemd/system/phone-book.service - name: start phonebook systemd: state: started daemon_reload: yes name: phone-book enabled: yes
In the case of MySQL, we need to add some more tasks and information to work with Ansible:
--- - name: include secrets include_vars: secrets.yml - name: install epel repository package: name: epel-release state: present - name: install dependencies package: name: "{{ item }}" state: present with_items: - git - python-pip - gcc - python-devel - mysql-devel - name: install python libraries pip: name: "{{ item }}" state: present with_items: - flask - flask-sqlalchemy - flask-migrate - uwsgi - MySQL-python - name: get the application code git: repo: [email protected]:ansible-cookbook/phonebook-mysql.git dest: /opt/phone-book force: yes - name: upload systemd unit file copy: src: phone-book.service dest: /etc/systemd/system/phone-book.service - name: upload app config file template: src: config.py dest: /opt/phone-book/config.py - name: create phonebook database mysql_db: name: phonebook state: present login_host: "{{ mysql_host }}" login_user: root login_password: "{{ mysql_root_password }}" - name: create app user for phonebook database mysql_user: name: app password: "{{ mysql_app_password }}" priv: 'phonebook.*:ALL' host: "%" state: present login_host: "{{ mysql_host }}" login_user: root login_password: "{{ mysql_root_password }}" - name: start phonebook systemd: state: started daemon_reload: yes name: phone-book enabled: yes
Accordingly, we will create a secrets.yml
in vars
directory and encrypt it using ansible-vault
. The unencrypted data will look like this:
--- mysql_app_password: appSecretPassword mysql_root_password: secretPassword mysql_host: 35.199.168.191
The phone-book.service
will take care of initializing the database and running the uwsgi server for serving the application for both SQLite and MySQL based setups:
[Unit] Description=Simple Phone Book [Service] WorkingDirectory=/opt/phone-book ExecStartPre=/bin/bash /opt/phone-book/init.sh ExecStart=/usr/bin/uwsgi --http-socket 0.0.0.0:8080 --manage-script-name --mount /phonebook=app:app Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target
Throughout the coming chapters, we will use this role to deploy our phone book application.