From Dev to Prod - All you need to know to get your Flask application running on AWS
From Dev to Prod - All you need to know to get your Flask application running on AWS
Getting the right configurations, making sure it is secured, ensuring resource access through endpoints and having a pretty rendering, … all of them made easy thanks to AWS!
Asa machine-learning engineer, I never really faced the issue of putting my algorithms out there myself. Well, that was until recently, when I decided to start my multiple entrepreneurial journeys … Unfortunately, when you start, you do not have a DevOps or software engineering team. Those are experienced with the world in which customers are using those services, and they know how to bridge the last step to bring your product from zero to one.
Now, I have had to spend hours reading tutorials and documentation to learn the basics, and finally, put my own algorithms as world-wide available and independent containerized services. For obvious reasons of reproducibility, I went through the templating of those steps, and I am more than happy to share those templates with you! :) [The templates are hosted here.]
Prepare the battlefield!
This initialization step is crucial and dependent on your practices. Here I expose the way I do it, but feel free to be original. My only assumption so far is that you have a proper AWS account, and you know how to navigate in between services!
- Install and configure the AWS CLI: AWS Tutorial.
- Install and configure the AWS Elastic Beanstalk CLI: AWS Tutorial.
- Download the templates: You currently have three choices: You can either download each file from the folder template independently; you can clone the entire repository for project Challenger, which is where I host my templates; you can use subversion to download a specific folder through the following commands:
sudo apt install subversion
svn checkout https://github.com/Coricos/Challenger/trunk/templates/beanstalk
- Define your dev environment:
virtualenv -p python3 beanstalk
cd beanstalk
source bin/activate
pip install -r requirements.txt
- Build your flask server in
application.py
! Check out that everything is running properly by trying it on your local machine first, and make sure to encapsulate the server launch in the__main__
. Also, that is an AWS specific requirement, but the name of your application as to explicitly beapplication
…
It works! Now what?
Because I found out AWS Elastic Beanstalk to be the best service to run my applications, I am inherently willing to present it. Why? Mainly because what is running on a beanstalk instance can be spawned on any other similar service and cloud provider. That gives you unlimited flexibility (and I am not even talking about using Docker for even greater deployability).
This service consists of a basic container running on an EC2 instance, linked to an S3 bucket for storage. In our case, the application itself does not require a lot of computational power (we did not talk about deep learning so far), so we will opt for the t2.micro instance (single virtual core and 4 GB of RAM). From there, it will only be about configuration, because AWS made our lives easier: you do not have to think about subnets, security-groups, VPCs, IP gateways, NAT, … This is automatically created and defined when you spawn your instance. Nonetheless, for the ones needing to control those (working in VPC or with RDS), you can configure everything through
security.config
in the .ebextensions
folder. The critical configuration ends with the config.yml
file in the .elasticbeanstalk
folder:environment-defaults:
{flask-app}:
branch: null
repository: null
global:
application_name: {my-app}
default_ec2_keyname: {my-ec2-key}
default_region: {region}
profile: {my-profile}
workspace_type: Application
For that configuration section, there is not much to do: Give a fancy name to your application as well as to your service (~environment); Define its EC2 key name if you need so, or use default otherwise; Select the region in which you want to spawn the instance; Chose your user profile; Use the
Application
load balancer (that’s my advice).
From there, you can already access and visualize your application running online, under a name such as {flask-app}.{id}.{zone}.aws.com. However, this lacks something: encryption during information transfer. And you may not be me, but I really dislike using websites or endpoints that do not use HTTPS…
Get the princess in the fortress!
Unfortunately, your instance cannot use HTTPS without having SSL certificates. Usually, people would work with OpenSSL, which is pretty straightforward but in our case, AWS makes it easy once again with their Certificate Manager service. If you want to make it even fancier, buy a domain name through the Route 53 service. You can then create your own certificate either with AWS for your beanstalk, either relative to your newly acquired domain name (looks way more pro this way, I assure you). Now, two objects have to be configured to redirect the requests: a
Canonical Name
, such as {cname}.domain-name that takes as value your EB instance; an Alias
, such as {alias}.domain-name for your EB instance as well. With those two records, you will be good to go!Please, use HTTPS!
What you miss is the messenger: the specific redirection of HTTPS requests to your instance. That messenger is called a listener, with a straight-forward configuration: direct HTTPS from the outside world to the HTTP on your instance. (Available in
listener.config
!)option_settings:
aws:elb:listener:443:
InstancePort: 80
ListenerEnabled: true
InstanceProtocol: HTTP
ListenerProtocol: HTTPS
SSLCertificateId: {certificate}
But that’s not all! To make sure your instance accepts HTTPS you have to configure the server: that is what
https.config
does for you! ;)Deploy Deploy Deploy!
Once you have figured out your Flask application, how to fill all missing configuration settings, how to get your SSL certificate, it is time to deploy! (No need to init, we have built the configuration files for that purpose.)
eb create flask-app
Want More? Here you are!
Here are a few things I did not want to integrate into the previous tutorial but are equally important in terms of the next steps:
- Use environment variables! Remember to be paranoic when you are working in production settings ;) My way of doing it usually is to fill a
environment.json
file with my variables, and deploy them withdeploy-env.sh prod
on the Elastic Beanstalk instance. - If you work with headers (e.g.
Flask-JWT
), just make sure to addheaders.config
to your.ebextensions
folder. - If you work with websockets (e.g.
Flask-sockets
), you will have to work in a Docker image and usewebsocket.config
. I will probably have to do another templating for that part (just ping me in the meanwhile if that is what you are looking for), as it turned out it took me more than hours to figure it out …
Comments