How much does a lambda cost

When I published Lambda that is called regularly like a cron task someone asked me how much would it cost (a fair question taking into account you pay per use, not per infrastructure). With lambda you pay for two things: a request/invocation and the time times memory used.

For that particular case (1 request per minute) the monthly cost would be:

Unit cost Cost
60 requests/hour * 24 hours/day * 31 days/month
44640 requests $0.0000002 $0.0089280
0.1 seconds minimum charge per execution * 44640 requests * 0.128GB of memory
558 GB-s $0.00001667 $0.00930186
Total $0.01822986

Note: This assumes that the free tier (1M requests and 400,000 GB-seconds) has been exhausted. So, on the worst case it’s an expense of $0.02/month.

Want to get python/AWS tips on your email? Just subscribe!

Lambda that is called regularly like a cron task

Do you want to run a task/function regularly, but don’t want to pay an EC2 instance just to run cron? Or don’t want to set it up and manage the instance?

You can use AWS lambdas (and zappa) for that. As an example, let’s create and deploy a function that prints Hello World! in the logs once a minute.

First install zappa: pip install zappa.

Second, build the function that will be called and save it on a file called event_test.py:

def process_event(event, context):
    print('Hello World!')

Then create the zappa_settings.json file:

{
    "event_hello": {
       "project_name": "event-hello",
       "runtime": "python3.6",
       "events": [{
           "function": "event_test.process_event", // The function to execute
           "expression": "rate(1 minute)"          // When to execute it (in cron or rate format)
       }],
       "apigateway_enabled": false,                // We don't need a web access to the lambda
       "s3_bucket": "<CHANGE_THIS>"                // bucket for deploy
    }
}

Then deploy it and enable the events with:

$ zappa deploy event_hello
Calling deploy for stage event_hello..
Creating event-hello-event-hello-ZappaLambdaExecutionRole IAM Role..
Creating zappa-permissions policy on event-hello-event-hello-ZappaLambdaExecutionRole IAM Role.
Downloading and installing dependencies..
 - sqlite==python36: Using precompiled lambda package
Packaging project as zip.
Uploading event-hello-event-hello-1540029016.zip (5.0MiB)..
100%|█████████████████████████████████████████████████████████████████████████████████| 5.24M/5.24M [00:02<00:00, 1.60MB/s]
Scheduling..
Scheduled event-hello-event-hello-event_test.process_event with expression rate(1 minute)!
Scheduled 25a24ee2d25a447b827d55fd774ecf9a586a4-handler.keep_warm_callback with expression rate(4 minutes)!
Deployment complete!

And now you can see that every minute you get a new ‘Hello World!’ in the logs – you can check with $ zappa tail.

Note: the keep_warm reference is to a default zappa event. You can check what it does in the README.

If you want to stop the events but keep the lambda deployed, do:

$ zappa unschedule event_hello
Calling unschedule for stage event_hello..
Unscheduling..
Unscheduled 25a24ee2d25a447b827d55fd774ecf9a586a4-handler.keep_warm_callback.
Unscheduled event-hello-event-hello-event_test.process_event.

And to reenable them, do:

$ zappa schedule event_hello
Calling schedule for stage event_hello..
Scheduling..
Scheduled event-hello-event-hello-event_test.process_event with expression rate(1 minute)!
Scheduled 25a24ee2d25a447b827d55fd774ecf9a586a4-handler.keep_warm_callback with expression rate(4 minutes)!

Have fun!

Want to get python/AWS tips on your email? Just subscribe!

Where to get help for Zappa?

Stuck with zappa? Assuming you’re looking for help about the python lambda library and not the singer, then the following should help.

The main documentation is the project’s README: https://github.com/Miserlou/Zappa/blob/master/README.md – check the links section for particular integrations (ex: django, flask, alexa skills).

If you think you found a bug, raise it in github issues: https://github.com/Miserlou/Zappa/issues. If you already have a fix, create a pull-request: https://github.com/Miserlou/Zappa/pulls.

If you want a new feature (or actually have implemented it), also raise it in github issues: https://github.com/Miserlou/Zappa/issues. If you already have the code, create a pull-request: https://github.com/Miserlou/Zappa/pulls.

If you are looking for support/discussions/answers to doubts, the best resource is the slack channel: https://slack.zappa.io/ – if you’re looking for paid support, ask in the #support channel, otherwise #general or #aws are usually fine.

Hope this gets you unstuck!

Want to get python/AWS tips on your email? Just subscribe!

Zappa, the packager

Are you having problems with packaging your dependencies for a Lambda? You’ve done the AWS lambda python tutorials but now need to deal with something more complex? Do you just want to build a package to upload in the console or with terraform?

Zappa is a great tool to handle everything from publishing your code to have it integrated with other AWS services with the minimum modifications possible. That results in sometimes ignoring that you can use for some smaller roles, like just packaging a lambda in a zip file that you can then use on the console and/or terraform.

So, let’s imagine you have your code in a file called myfunction.py doing something like:

def lambda_handler(event, context):
    print('Hello World!')

To package it do the following:

1) Create a virtual environment for your function: python3 -m venv ve for python 3.6.

2) Activate the virtual environment: . ve/bin/activate (on Mac OS X or GNU/Linux) or ve/Scripts/Activate (on Windows). 3) Install zappa and other dependencies you need with pip install <dependency>. 4) Create a zappa_settings.json with the following content:

{
    "dev": {
        "lambda_handler": "myfunction.lambda_handler",
        "runtime": "python3.6"
     }
}

5) Run zappa package dev.

6) And that’s it, with that zappa has created a zip file that you can now upload to AWS.

Want to get python/AWS tips on your email? Just subscribe!

Provided role cannot be assumed by principal ‘events.amazonaws.com’.

You did a zappa deploy and it failed with An error occurred (ValidationException) when calling the PutRule operation: Provided role <your lambda role> cannot be assumed by principal 'events.amazonaws.com'.?

You tried to create a lambda with a new handmade role only to be greeted by this cryptic error message. Or you tried to use an already existing role with lambda.

Translating the message: it means you haven’t authorized the events (events.amazonaws.com) service to assume the role, so lambdas can’t use it. So, how do we add that authorization?

  • Go to https://console.aws.amazon.com/iam/
  • Click roles on the left.
  • Click the role you want to use for lambda.
  • Click the tab trust relationships.
  • Click the button Edit trust relationship.
  • If this lambda is only to be used by lambda, you can just replace the policy by:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "",
                "Effect": "Allow",
                "Principal": {
                    "Service": [
                        "apigateway.amazonaws.com",
                        "lambda.amazonaws.com",
                        "events.amazonaws.com"
                    ]
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    
  • If not, just make sure you have events.amazonaws.com as a Service in the Statement that allows to AssumeRole:

            {
              "Sid": "",
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "apigateway.amazonaws.com",
                  "lambda.amazonaws.com",
                  "events.amazonaws.com"
                ]
              },
              "Action": "sts:AssumeRole"
            }
    
  • Click Update trust policy.

In the end you should see something like this:

Trust relationships for lambda

Want to get python/AWS tips on your email? Just subscribe!

The role defined for the function cannot be assumed by Lambda

You did a zappa deploy and it failed with InvalidParameterValueException: An error occurred (InvalidParameterValueException) when calling the CreateFunction operation: The role defined for the function cannot be assumed by Lambda?

You tried to create a lambda with a new handmade role only to be greeted by this cryptic error message. Or you tried to use an already existing role with lambda.

Translating the message: it means you haven’t authorized the lambda service to assume the role, so lambdas can’t use it. So, how do we add that authorization?

  • Go to https://console.aws.amazon.com/iam/
  • Click roles on the left.
  • Click the role you want to use for lambda.
  • Click the tab trust relationships.
  • Click the button Edit trust relationship.
  • If this lambda is only to be used by lambda, you can just replace the policy by:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "apigateway.amazonaws.com",
                    "lambda.amazonaws.com",
                    "events.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
  • If not, just make sure you add to the Statement list the statement:
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "Service": [
              "apigateway.amazonaws.com",
              "lambda.amazonaws.com",
              "events.amazonaws.com"
            ]
          },
          "Action": "sts:AssumeRole"
        }

  • Click Update trust policy.

In the end you should see something like this:

Trust relationships for lambda

Want to get python/AWS tips on your email? Just subscribe!

zappa-sentry, automatic integration of zappa and sentry

Want to know when something goes wrong in a lambda? Tired of replicating all your alarm setup for each lambda?

If you just want a simple setup on each lambda that guarantees that you get alerts with enough information to be actionable, zappa-sentry is for you.

You’ll need a sentry project DSN. If you don’t have one or don’t even have an account you can create one for free at https://sentry.io/

How to use?

First, install the zappa-sentry in your lambda’s virtual environment with: pip install zappa-sentry (if you’re using a requirements.txt to manage dependencies don’t forget to add zappa-sentry to it).

Next, setup your sentry DSN as the value of environment variable SENTRY_DSN, either on the zappa_setting.json file or in any of the other methods on https://github.com/miserlou/zappa/#setting-environment-variables

Then you can setup the zappa_sentry.unhandled_exceptions handler.

Example:

{
    "dev": {
        ...
        "environment_variables": {
            "SENTRY_DSN": "https://*key*:*pass*@sentry.io/*project*",
            ...
        },
        "exception_handler": "zappa_sentry.unhandled_exceptions",
        ...
    },
    ...
}

And that’s all. Deploy your zappa function and you should see any errors appearing on sentry.

Want to get python/AWS tips on your email? Just subscribe!