Introduction
The most common way to run an AWS Lambda function from outside AWS is through an AWS API Gateway. The API Gateway is accessible via a standard http post. This post could come from a website or an external service like Slack.
Setting up the Lambda function
The easiest way I've found to create a Lambda function and an API Gateway and connect them is with Serverless.
Serverless
Serverless is a framework that allows you to simply define the behavior of a Lambda function with a YAML configuration file and the Lambda function code. A single or group of Lambda functions that work together are referred to as a service
.
Installation
Installation of serverless is quite simple:
npm install -g serverless
Basic Setup
To begin your service, you'll use the create
command:
serverless create --template aws-python --path myService
This will create a new folder for your service called myService
or whatever you specified in the serverless create
command. Within that folder, you will find two files that have been preconfigured, handler.py
and serverless.yml
.
Configuring our Lambda function with an API Gateway
The Lambda function, along with its trigger are defined in the serverless.yml
file. This file has three main sections, service
, provider
, and function
.
Service
The service
section simply defines the name of your service, so you should see a line in your generated serverless.yml
file:
service: myService
Provider
The next section in the serverless.yml
file is the provider
section. In your generated serverless.yml
file you should see the following:
provider:
name: aws
runtime: python2.7
There are a number of other configuration options in the provider
section. For example, you might want to specify a region, with:
region: us-west-2
And if your Lambda function will be using any other AWS features, you will probably need to specify iamRoleStatements
that give your Lambda function access to those AWS features. For example, to give full access to AWS SNS, you might include:
iamRoleStatements:
- Effect: "Allow"
Action:
- "sns:*"
Resource: "arn:aws:sns:us-west-2:*:*"
Functions
The last main section of the serverless.yml
file is the functions
section. This section defines the name of the function, the python function that is called, any environment variables, and the events that trigger the Lambda function.
For example, to define a function named deploy
, triggered by an AWS API Gateway, with an environment variable SLACK_TOKEN
defined, you might include:
functions:
deploy:
handler: handler.deploy
environment:
MY_ENV: gIkuvaNzQIHg97ATvDxqgjtO
events:
- http:
path: deploy
method: post
For security purposes, you can avoid saving credentials in your code by using local environment variables. For example, you could replace the environment
subsection with:
environment:
MY_ENV: ${env:MY_ENV}
This would look for a local environment variable defined as MY_ENV
.
Writing the Lambda function
Now that our Lambda function has been configured, we are ready to write the code to handle the incoming http post. We've defined the handler to be handler.deploy
which translates to the deploy
function within the handler.py
file.
We start with the following:
import urlparse
def deploy(event, context):
data = event['body']
args = dict(urlparse.parse_qsl(data))
parameter1 = args.get('parameter1', "")
parameter2 = args.get('parameter2', "")
The function deploy
will be called when the Lambda function is triggered, and the parameters event
and context
will be passed in. You can retrieve the data that was posted from the event parameter:
data = event['body']
This can then be broken down into the individual posted parameters with:
args = dict(urlparse.parse_qsl(data))
After the parameters have been processed, you'll want to return the results to the caller. This will need to be in a form that the caller can process. It can be useful to generalize the formatting of the return data:
def get_response(text):
response = {
"statusCode": 200,
"body": text
}
return response
You could then return a text response from your deploy
function with:
return get_response("This is my return text.")
Dealing with Python modules
If you need to use external Python modules you have a couple choices. If it's just a single file module, you can just drop it into your project folder next to handler.py
. Serverless will install it automatically. You could do the same with a folder or group of folders containing code, but if you are dealing with more complex modules, the easiest thing to do is use the serverless module serverless-python-requirements, following their directions for installing and using. One note on installation of this module is that you probably want to install it globally, in which case you would install it with:
npm install -g serverless-python-requirements
rather than their suggested:
npm install --save serverless-python-requirements
which will install it in the lambda function project directory.
Deploying the Lambda function and API Gateway
Deploying your Lambda function and API Gateway is very easy with Serverless. Simply run:
serverless deploy
This will return the URL of the API Gateway that it created.
Comments