The main goal of this project was to utilise a number of different technologies to deploy an application that met certain key requirements. These Key Requirements were:
Using Python to Develop 4 Micro-Services with a RESTful architecture
Services 2, 3 and 4 should have dual implementations
The result of Service 4 should be stored in a MySQL Database
Docker should be used to containerise the 4 Micro-Services
Docker Swarm must be used to deploy the containers over a minimum of 2 nodes
Ansible must be used to configure the environment of the Nodes prior to the application being deployed
A CI/CD Pipeline using Jenkins will automate the entire process of Build/Test/Deploy
My proposal was to create a Random Cryptocurrency to Fiat Currency Converter (e.g. Bitcoin to Euro). My inital proposal is to have 4 services as follows:
Service 1: This will be the front end of my application, and Flask will be used to create this. My database will store the resulting crypto/fiat/price pair that is generated from Service 4, in a MySQL Database on GCP. Only a single index.html page will be used to display the information. Options will be present on Service 1 to enable dual implementation for Services 2, 3 and 4.
Service 2: Generates a random fiat currency to return to Service 4. The Fiat Currencies used in the application will be stored as csv files seperated into groups.
Service 3: Generates a random crypto currency to return to Service 4. The Cryptocurrencys used in the application will be stored as csv files seperated into groups.
Service 4: Returns to Service 1 a price based off of the fiat and crypto currency returned from Service 2 and 3. This services uses an External API to pull live market data provided by CryptoCompare. The mode of Service 4 e.g. (Crypto to Fiat or Fiat to Crypto conversion) is used to determine how to process the conversion using the External API. All Data is formatted and returned to Service 1.
Shown above is an initial Wireframe diagram of my Flask Application (Service 1)
Trello, a web-based Kanban board, was used to plan the project while implementing Agile methodology, such as specifying a product and sprint backlog. The project was to be split into 2 sprints
I utilised MosCoW Prioritisation to give each requirement of the project an importance, so that I can use this to sort the order I should prioritise completing them in. I used a colour labelling method to do this and you can see an example of this below for my Initial Trello Board:
The main aims in Sprint 1 were to create the 4 micro services and ensure they work together, as well as gain experience using Docker, Docker Swarm and Docker Swarm as early as possible so that the micro-services can be containerised. This is reflected in the Initial Sprint 1 board below:
All changes during Sprint 1 were explained above. The main aims in Sprint 2 were to create a Ansible Playbook to configure the VM's that would be used in the Swarm, build a Jenkins Pipeline to Build the compose file, conduct testing on the micro-services and deploy the application to multiple seperate VM's. Shown Below is the Trello Board by the Start of Sprint 2:
All changes during Sprint 2 were explained above. The Trello board by the end of the Final Sprint is show below:
By the end of Sprint 2 the key requirements as well as some optional requirements were implemented. However All 'Could Have' labelled features were not implemented due to time constraints, however these would be considered in a future sprint. This will be discussed later in the README.
Issue passing parameters between services for dual implementation. Get requests using JSON learnt to implement basic requests
Had issues with setting up Docker Swarm as Worker Nodes could not pull down image. Fixed by Making Docker Repo Public
Had issue where exposing API key as well as DB info needed to be prevented. An Environment File was made and used to store the environment variables so that it can be used on multiple VM's
SSH keys are needed to be used for Ansible to execute all instruction in Playbook on other VM's. SSH keys were securely transferred to relevant folders as well as Jenkins Test VM
Multiple minor issues with Docker Swarm, however these were fixed by checking the logs of the service or container and identifying potential causes e.g. missing dependecy, Database not on etc
The initial ERD Diagram for my project is shown below. The database consists of a single table called currencylist, in which the pair and price returned to Service 1 is stored.
The inital ERD was sufficient for a single implementation of Service 4, however to introduce a second implementaion a change to the ERD structure was required. The Main change came in adding a new table to store the results for the two different modes of operation - Crypto to Fiat and Fiat to Crypto, in 2 different tables. This is so that Price Column can have adjusted decimal parameters for storing the results.
The Final ERD Diagram used therefore, is shown below:
Shown Below is the Docker Swarm architecture for the application. The Swarm Architecture consists of 2 GCP VM Instances, in which one VM instance is configured to be a Manager Node, and the other a Worker Node. An Overlay network is used to deploy the swarm so that the applications can communicate with each other from different VM's. There are a total of 5 Docker Containers used. 4 Containers are for the actual developed service, while the 5th container is an Nginx Image, which is acting as a Reverse Proxy to forward port 80 web traffic to port 5000 of the Flask App and vice versa. Services 2, 3 and 4 are replicated twice, while Service 1 and Nginx are only Replicated once.
The Pipeline used for deployment is represented as a diagram shown below. The Entire Pipeline utilises 3 GCP VM instances. 1 is used as the Jenkins Test Server, 1 is used for developing the application as well as being the Master node in the swarm, and a spare VN instance is utilised to act as a worker node. All VM instances have access to the GCP SQL Database so that the flask application can retrieve and store data wherever the container may be.
After Implementing all feature and building the Final Flask Micro-service, an updated Wireframe diagram was produced to show the evolution of the page during the project. The final wireframe includes features for a dual implementation, as well as introduces a read from the 2nd table. This is shown below:
Testing is composed of 2 parts, URL testing to ensure the site is up and running, and Database testing which mimics the entry of a pair into the database.
In the URL Test, the local swarm is pinged and an assert of 200 is made which demonstrates the site is up and running, with a connection established.
The Database Testing loop consists of the following, and is repeated for both tables in the database:
Test Data is inserted into the table and an assert is made to check number of records has increased by 1
Test Data is read from table and an assert is made to check the data read back is equivalent to the data to be inserted.
Test Data is updated with different values and an assert is made after reading the values back, to ensure they match the updated test data.
Test Data deleted and the table is reset to its original state before the tests were conducted. An assert is made to ensure the number of records has decreased by 1.
The coverage report is shown below:
The coverage is 99% because none of the routes are being tested, the database functionality of the routes are being mimicked in the testing.py file
Setup SSH keys for the 3 VM's and store in a config file in a .ssh folder
Install Jenkins on one GCP VM Instance to be used as a Jenkins Test Server. Expose TCP port 8080 in firewall rules
Add Jenkins to sudoers group
Setup Jenkins pipeline with Webhooks
Copy over .ssh folder to root of jenkins directory as well as Ansible Playbook + inventory and keys.env files to working directory in Jenkins for Pipeline. e.g. var/lib/jenkins/workspace/currencyswarm
Add required Docker Swarm ports to Firewall Rules of all VM's: TCP 2376, 2377 and 7946, UDP 4789, and 7946.
Request build on Jenkins Pipeline.
Scripts should install all dependencies needed for Jenkins to run Swarm stack on Jenkins VM. Ansible Playbook will configure deployment VM's with software needed to ensure application Runs.