I’m going to demonstrate how to make a Flask app serverless without locking you into any tooling or cloud platforms. It doesn’t require any application code changes or serverless so you can continue to develop locally like you always have. frameworks Ideally you should re-architect your application into small discrete functions to take full advantage of serverless. However, if you want to migrate a legacy application or just a quick way to get started with serverless then this is a good approach to take. 1. Create Flask Application2. Make the Application Serverless3. Package Application into Zip for Lambda4. Deploy with Terraform 1. Create Flask Application We are going to create a Flask application for 3.6+. Python Setup First create a virtual environment and install dependencies. $ python3 -m venv env $ source env/bin/activate$ pip install flask flask-lambda-python36 http-prompt Application Code Add the code below which will create a Flask Application with impeccable music taste. $ tree -L 4.├── app│ ├── api│ │ ├── __init__.py│ │ └── resources.py│ └── __init__.py└── run.py # app/api/resources.pyfrom flask import Blueprintfrom flask import request, jsonify api = Blueprint(‘api’, __name__) .route(‘/artists’, methods=(‘GET’, ‘POST’))def handle_artists():if request.method == 'POST':return 'ok' @api return jsonify([{'name': 'enya'}]) # app/api/__init__.pyfrom .resources import api # app/__init__.pydef create_app(Flask):app = Flask(__name__)from .api import api as api_blueprintapp.register_blueprint(api_blueprint) return app # run.pyfrom flask import Flaskfrom app import create_app http_server = create_app(Flask) Complete application code available at the . example repository Run the App Run the app in local development mode. $ FLASK_DEBUG=1 FLASK_APP=run.py flask run Test the App In another terminal window manually test the API. $ http-prompt localhost:5000 > get artists http://localhost:5000 HTTP/1.0 200 OKContent-Length: 31Content-Type: application/jsonDate: Thu, 12 Apr 2018 19:15:56 GMTServer: Werkzeug/0.14.1 Python/3.6.5 [{"name": "enya"}] 2. Make the Application Serverless Up to this point this is just another Flask application. Time to make it serverless. Add another file called to the root of the project. run-lambda.py # run-lambda.pyfrom flask_lambda import FlaskLambdafrom app import create_app http_server = create_app(FlaskLambda) That’s it! Your application is now ready be run on AWS Lambda. The trick here is using instead of normal Flask. FlaskLambda converts the payload that AWS feeds your Lambda function into the format that Flask expects. FlaskLambda This adaptor pattern is the same one that uses. Personally I prefer not to introduce any extra tooling dependencies and instead opt for Terraform or for deployment. zappa AWS Serverless Application Model (SAM) Be aware that FlaskLambda only supports Python <= 3.5. I’ve created a that adds support for Python 3.6+ which you installed earlier with . fork pip install flask-lambda-python36 3. Package the Application into a Zip for Lambda In order to deploy your application you need to package your application into a zip. The following script which will bundle your application code and dependencies. # bundlelambda.sh#!/usr/bin/env bash OUTPUT_ZIP="$PWD/terraform/flask-app.zip"ARCHIVE_TMP="/tmp/lambda-bundle-tmp.zip" addToZip() {local exclude_packages="setuptools pip easy_install"zip -r9 s"$ARCHIVE_TMP" \--exclude ./*.pyc \--exclude "$exclude_packages" \-- "${@}"}addDependencies() {local packages_dir=()packages_dir+=($(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))env_packages=$(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=1))")if [[ "$env_packages" != "${packages_dir[0]}" ]]; thenpackages_dir+=($env_packages)fifor (( i=0; i<${#packages_dir[@]}; i++ )); do[[ -d "${packages_dir[$i]}" ]] && cd "${packages_dir[$i]}" && addToZip -- *done} rm "$ARCHIVE_TMP" "$OUTPUT_ZIP"addDependenciesaddToZip app ./*.pymv "$ARCHIVE_TMP" "$OUTPUT_ZIP" This is a simplified version of . the script in the example repository Save and run the script to create a zip bundle at . terraform/flask-app.zip $ chmod +x bundlelambda.sh$ ./bundlelambda.sh Ensure you run this on a Linux platform to ensure compatibility with the Lambda runtime environment. 4. Deploy With Terraform Terraform Config We will use the terraform module to handle deployment. Create the Terraform configuration file at and update the with your AWS account ID. [lambda-api-gateway](https://registry.terraform.io/modules/techjacker/lambda-api-gateway/aws/1.0.2) terraform/main.tf account_id # terraform/main.tfmodule "lambda_api_gateway" {source = " :techjacker/terraform-aws-lambda-api-gateway" git@github.com # tagsproject = "todo-mvc"service = "acme-corp"owner = "Roadrunner"costcenter = "acme-abc" # vpcvpc_cidr = "10.0.0.0/16"public_subnets_cidr = ["10.0.1.0/24", "10.0.2.0/24"]private_subnets_cidr = ["10.0.3.0/24", "10.0.4.0/24"]nat_cidr = ["10.0.5.0/24", "10.0.6.0/24"]igw_cidr = "10.0.8.0/24"azs = ["eu-west-1a", "eu-west-1b"] # lambdalambda_zip_path = "flask-app.zip"lambda_handler = "run_lambda.http_server"lambda_runtime = "python3.6"lambda_function_name = "HttpWebserver" # API gatewayregion = "eu-west-1"account_id = "123456789"} The key value here is which instructs AWS Lambda to use the file as the entrypoint to our app. lambda_handler run_lambda.py Deploy $ cd terraform$ terraform apply When complete, Terraform should output the API URL which you can use to manually test the deployment succeeded. $ http-prompt $(terraform output api_url)GET artists HTTP/1.0 200 OKContent-Length: 31Content-Type: application/jsonDate: Thu, 12 Apr 2018 19:15:56 GMTServer: Werkzeug/0.14.1 Python/3.6.5 [{"name": "enya"}] Conclusion We took an existing Flask application and turned it serverless with just three lines of code! By using the adaptor pattern we have given ourselves the freedom to easily swap serverless cloud providers in the future. We could even switch to a container based deployment without having to change any of the application code. Benefits of this approach: Develop locally like you always have (no need for emulators) Complete visibility into and control over your infrastructure Avoids cloud vendor lock-in Avoids application code framework lock-in Future posts will cover , Azure Functions and Google Cloud Functions deployments. AWS Serverless Application Model (SAM) Full code for this tutorial available on . github Originally published at andrewgriffithsonline.com . Andrew Griffiths is a freelance developer specialising in building and deploying applications in Golang, Python and JavaScript using Serverless platforms.