[AWS] Lambda

Lambda is a FaaS (Function as a Service) product where you can upload your code and create functions. Functions are invoked by events and can be executed for up to 15 minutes.

AWS Lambda lets you run code – for virtually any type of application or backend service – without provisioning or managing servers. You pay only for the compute time you consume—there is no charge when your code is not running. You can set up your code to automatically trigger from other AWS services, or you can call it directly from any web or mobile app.


Features

  • Lambda is a serverless computing platform, which you can run code without managing server
  • Lambda is highly available and scalable – scales out (not up) automatically-.
  • Event-driven
    • Lambda functions are triggered by events or user requests.
    • Events can be triggered by many AWS Services such as S3, DynamoDB, SQS, CloudWatch, CodeCommit, etc…
    • For example, many Alexa skills are handled by Lambda triggered by your voice.
  • Stateless and Independent
    • Each event will trigger a single function.
    • Functions are stateless – each run is clean.
  • Execution Role is assumed by Lambda and temporary security credentials are available via STS.
  • You can specify the Environment variables, which can be retrieved through the event object.
  • Functions can trigger other functions. The architecture can be complicated. AWS X-ray can debug the function.
  • It provides built-in monitoring and logging via CloudWatch.

Limitations

  • Memory: 128MB ~ 10 GB
  • vCPU: is linked to RAM
    • up to 6 vCPU
  • Timeout: 15 minutes
  • Temporary Storage: 10 GB
  • Deployment Package size: 50 MB(zipped) or 250 MB (unzipped)
  • Concurrent Execution: 1,000 per region

Pricing Model

You are charged based on the duration and the number of requests.

  • Compute time
    • Pay Only when your code is running, rounded to the nearest 1ms.
  • The number of requests
    • Charged whenever the code starts execution (even the test invokes from the console)
    • The first 1 million requests per month is free.
  • The amount of memory

Lambda Function Configurations

  • You can import code to Lambda in 3 ways:
    • Uploading a zip file, uploading a file from S3, and editing inline code
  • Runtime & Handler
    • It Supports popular programming languages.
      • Node.js, .Net Core (C#/PowerShell), Java, Python, Ruby, and Go.
    • A handler accepts 2 inputs.
      • Event object (required)
        • differs depending on the event source
      • Context object (optional)
        • It contains the information of the execution environment.
    • In general, you need to treat your handler as stateless.
      • You can use other services to save states.
        • DynamoDB, ElasticCache, or S3
    • You can use the environment variables.
  • Permissions
    • You need to attach an appropriate role to do actions such as AWS API calls.
  • Networking
    • (optionally) You can define a VPC, a subnet, and security groups.
  • Resources
    • Memory Allocation
      • 128MB ~ 10 GB
      • CPU scales with memory
  • Timeout
    • The maximum timeout is 900 seconds (15 minutes)
  • Triggers
    • Attach events to trigger the function

Invocation Models

Lambda functions are triggered by events. There are 3 ways to invoke a lambda function.

  • Synchronous Invocation
  • Asynchronous Invocation
  • Polling Invocation

Synchronous Invocations

Lambda runs the function, waits for a response, and returns the result.

  • There is no built-in retries.

Sources

  • API Gateway, Cognito, CloudFormation, Alexa, CloudFront

AWS CLI command

aws lambda invoke `
 --function-name {f-name} `
 --cli-binary-format raw-in-base64-out `
 --payload '{ "key": "value" }' response.json

Asynchronous Invocations

For asynchronous invocation, Lambda places the event in an event queue and returns a success response without additional information.

  • Lambda service manages the internal event queue.
  • If your function returns an error, it will automatically retry the event two additional times over an increasing interval. After exhausting all retries, you can direct failed attempts to a dead-letter queue.
    • Developers do not control the Lambda queue.
    • You can modify the retry count (0-2).
    • You can modify the maximum amount of time that Lambda should retry.
  • To invoke a function asynchronously with the AWS CLI, use the invoke type “Event.”

Sources

The following AWS Services invoke Lambda functions asynchronously:

  • SNS, S3, EventBridge

Destinations

You can also configure Lambda to send an invocation record to another service upon success or failure:

  • SNS, SQS, EventBridge, or another Lambda Function

AWS CLI command

aws lambda invoke `
 --function-name {f-name} `
 --invocation-type Event ` 
 --cli-binary-format raw-in-base64-out `
 --payload '{ "key": "value" }' response.json

Polling Invocations

Lambda will poll streaming or queue services, retrieve any matching events, and invoke associated functions.  The process to configure event triggers is called “Event Source Mapping“.

Lambda service with Queues

  • polls the source service
    • SQS
  • retrieves multiple batches and launches a concurrent instance for each batch
    • For example, if 5 batches are polled, 5 concurrent instances are created
  • invokes a function synchronously with the batch of records in each instance
    • The records become invisible for the duration of the visibility timeout.
  • deletes a successfully processed batch of records off the queue
    • Retry Login: Lambda service will keep retrying a batch of records until the batch succeeds or the records expire.
  • scales Lambda concurrency up and down based on queue depth and error rates

Lambda service with Queues

  • polls the source services
    • Kinesis Data Stream, DynamoDB Streams
  • maintains the pointer on the stream
  • retrieves one batch of records from each shard
  • invokes one function per batch (shard)
  • will move to the next batch of records on the pointer position
  • will not scale concurrency
    • You need to increase or decrease the number of shards
  • If you do not handle error, a failed record will block the shard until it reaches the end of its retention period.

Lambda Lifecycle

Each invocation of a Lambda function runs in an ephemeral environment.

  1. Init Phase
    • Extension Init: starts all extensions
    • Runtime Init: bootstraps the runtime
    • Function Init: runs the function’s initialization code (static code)
  2. Invoke Phase
    • Invokes the function handler
  3. Shutdown Phase
    • Runtime Shutdown: alert the extensions and removes the environment
    • Extension Shutdown

Cold and Warm Starts

  • Cold Start
    • A new execution environment is required. Expect the latency.
    • Start the container and download the code
    • Prepares the runtime with specified memory and vCPU
  • Warm Start
    • An invocation gets routed to an existing environment (runtime).

Scaling and Concurrent Executions

Concurrency is the main configuration that affects the function’s performance and scalability.

  • Concurrency is the number of Lambda function invocations running at a given moment.
  • It is how Lambda can quickly scale horizontally.
  • Quota
    • Burst Quota (Hard-limit)
      • Each region has a burst limit that prevents concurrency from increasing too quickly.
    • Regional Concurrency Quota (Soft-limit)
      • The total number of invocations that can run all Lambda functions concurrently in a region.

Types of Concurrency

  • Unreserved Concurrency
    • the amount that is not allocated to any specific functions
    • The minimum is 100.
  • Reserved Concurrency
    • the guaranteed maximum number of concurrent invocations for a function (function-level)
      • Reserved concurrency applies across all versions of that function.
    • ensures that you can handle expected high volume for critical functions
    • No other functions can use that amount

Concurrency Limit

There is a limit to the number of concurrent executions across all functions in a given region per account. (Regional Quota)

  • The default is 1,000.
    • Reserved (0 ~ 900) + Unreserved (100 ~ 1,000) = 1,000
  • If you exceed the limit, you will get “TooManyRequestException” error (HTTP 429).
  • The remedy is to get the limit raised by AWS support.

Provisioned Concurrency

  • keeps your environment initialized and warm, and ready to respond in double-digit milliseconds.
  • minimizes cold start latency
  • only applies to a particular version of the function.

Permissions

Lambda permissions – AWS Lambda (amazon.com)

You need to consider 2 types of permissions.

Resource-based Policy

  • Source => Resource-based policy => Lambda Function
    • The permission to invoke the function
    • associated with a “push” event source such as API Gateway
    • allows the event source to take the lambda:InvokeFunction action

The following example policy allows S3 bucket to invoke the specific lambda function.

{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "lambda-0e8f27bd-1754-45ae-9814-e9d2996595b5",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:{region}:{account-id}:function:{function-name}",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "{account-id}"
        },
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:s3:::{bucket-name}"
        }
      }
    }
  ]
}

Execution Role

  • Lambda function => Execution role => Other services
    • The permission of the function to act upon other services or resources. It controls what the function is able to do.
    • IAM Policy
      • allows a function to do actions with resources
    • Trust Policy
      • allows Lambda to “AssumeRole” so that it can take that action for another service.

The following execution role allows the lambda function to access the DynamoDB table.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:DeleteItem",
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:Scan",
                "dynamodb:UpdateItem"
            ],
            "Resource": "arn:aws:dynamodb:{region}:{account-id}:table/*"
        }
    ]
}

Versions

You can create multiple versions of the code.

  • $LATEST points to the most recent code you updated (the last version).
  • You can access different versions of the same function using the ARN (Amazon Resource Name) or an alias.
# no version
arn:aws:lambda:{region}:{account}:function:{function-name}  

# versions - alias
arn:aws:lambda:{region}:{account}:function:{function-name}:$LATEST
arn:aws:lambda:{region}:{account}:function:{function-name}:Hotfix 

Enabling Lambda to access VPC resources

There might be some use cases in which you need to access the resource in a private subnet in your VPC from your lambda function, such as accessing EC2 instances.

Configuring a Lambda function to access resources in a VPC – AWS Lambda (amazon.com)

Lambda sets up ENIs (Elastic Network Interfaces) using an available IP address from your private subnet using:

  • Private subnet ID
  • Security Group ID” with required permissions

When you create a connection from the Lambda function to VPC subnets, a role is created with the following permissions by default.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DeleteNetworkInterface",
                "ec2:DescribeNetworkInterfaces"
            ],
            "Resource": "*"
        }
    ]
}

Monitoring and Logging

AWS Lambda monitors functions and reports metrics through Amazon CloudWatch.

Monitoring Graphs

You can check the following metrics in the function’s monitor tab as graphs:

  • Invocations
    • The number of times the function is run: success + failure
  • Duration
    • the running time of the function
    • The billed duration is the value of Duration rounded up to the nearest milliseconds.
  • Error Count and Success Rate (%)
  • Throttles
    • The number of failed runs due to concurrency limits.
  • Concurrent Executions
    • The number of function instances that are processing events.

Amazon CloudWatch Lambda Insights

  • CloudWatch Lambda Insights Insights collects, aggregates, and summarizes system-level metrics.
  • It also summarizes diagnostic information such as cold starts and Lambda worker shutdowns.

Best Practices

Lambda has the following characteristics.

  • Your function runs in an ephemeral environment. Expect the cold-start latency.
  • Your function runs in its own environment. Make your code stateless.

Environment Reuse – Prepare the cold start

  • Minimize the impact of cold starts
  • Make the deployment package as small as possible
  • Limit dependencies
  • Optimize the function initiation code
    • initialize global variables outside the handler
    • check whether the local cache (/tmp) has the data that you stored.
  • Check the background processes have completed
  • Use provisioned concurrency to take advantage of per-initialized environment
    • You can configure some portion of your function’s reserved concurrency as provisioned concurrency rather than on-demand concurrency.

Persist state data externally

  • Make your function stateless
  • Use external data stores like DynamoDB

For large or shared assets, use external storage

Manage database connections


Handling Lambda Errors

In general, there are 2 types of errors you need to be aware of.

Invocation Errors

  • The Lambda service cannot invoke the requested function.
  • The Lambda service returns a 400 or 500 error.
  • Issues with the event source
    • The source lacks permission to invoke a function.
    • The event message is not valid.
    • The message size is too big.
  • Throttling
    • The Lambda service does not have enough concurrency to invoke a new function.

Function Errors

  • A Lambda function is invoked but does not complete successfully.
    • The code has a bug.
  • The Lambda service returns a JSON response with a header named “X-Amz-Function-Error“, an error message, and other details.

You need to handle errors differently depending on the invocation type.

Synchronous Invocation

  • The event source (client) must handle all possible errors from Lambda.

Asynchronous Invocation

  • The event source (client) and the Lambda function share error handling.
  • The client needs to handle permission issues or invalid requests.
  • If the asynchronous event source successfully passes the request to Lambda, the source receives a 202 message indicating that it was successful.
  • Lambda service provides the retry mechanism before declaring failure.

Invocation via Polling

  • In general, a Lambda function handles errors.
  • Event sources have some configuration options to mitigate the risks.
  • Queue
    • Use the failure destination, such as the dead-letter queue
  • Streams
    • Use the bisect batch on error or checkpointing
    • Use an OnFailure destination

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s