There are three ways to build a container image for a Ruby Lambda function:
This page explains how to build, test, and deploy container images for Lambda.
AWS base images for RubyAWS provides the following base images for Ruby:
Amazon ECR repository: gallery.ecr.aws/lambda/ruby
Using an AWS base image for RubyTo complete the steps in this section, you must have the following:
To create a container image for RubyCreate a directory for the project, and then switch to that directory.
mkdir example
cd example
Create a new file called Gemfile
. This is where you list your application's required RubyGems packages. The AWS SDK for Ruby is available from RubyGems. You should choose specific AWS service gems to install. For example, to use the Ruby gem for Lambda, your Gemfile should look like this:
source 'https://rubygems.org'
gem 'aws-sdk-lambda'
Alternatively, the aws-sdk gem contains every available AWS service gem. This gem is very large. We recommend that you use it only if you depend on many AWS services.
Install the dependencies specified in the Gemfile using bundle install.
bundle install
Create a new file called lambda_function.rb
. You can add the following sample function code to the file for testing, or use your own.
module LambdaFunction
class Handler
def self.process(event:,context:)
"Hello from Lambda!"
end
end
end
Create a new Dockerfile. The following is an example Dockerfile that uses an AWS base image. This Dockerfiles uses the following configuration:
Set the FROM
property to the URI of the base image.
Use the COPY command to copy the function code and runtime dependencies to {LAMBDA_TASK_ROOT}
, a Lambda-defined environment variable.
Set the CMD
argument to the Lambda function handler.
Note that the example Dockerfile does not include a USER instruction. When you deploy a container image to Lambda, Lambda automatically defines a default Linux user with least-privileged permissions. This is different from standard Docker behavior which defaults to the root
user when no USER
instruction is provided.
FROM public.ecr.aws/lambda/ruby:3.4
# Copy Gemfile and Gemfile.lock
COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/
# Install Bundler and the specified gems
RUN gem install bundler:2.4.20 && \
bundle config set --local path 'vendor/bundle' && \
bundle install
# Copy function code
COPY lambda_function.rb
${LAMBDA_TASK_ROOT}/
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "lambda_function.LambdaFunction::Handler.process
" ]
Build the Docker image with the docker build command. The following example names the image docker-image
and gives it the test
tag. To make your image compatible with Lambda, you must use the --provenance=false
option.
docker buildx build --platform linux/amd64 --provenance=false -t docker-image
:test
.
Note
The command specifies the --platform linux/amd64
option to ensure that your container is compatible with the Lambda execution environment regardless of the architecture of your build machine. If you intend to create a Lambda function using the ARM64 instruction set architecture, be sure to change the command to use the --platform linux/arm64
option instead.
Start the Docker image with the docker run command. In this example, docker-image
is the image name and test
is the tag.
docker run --platform linux/amd64 -p 9000:8080 docker-image
:test
This command runs the image as a container and creates a local endpoint at localhost:9000/2015-03-31/functions/function/invocations
.
If you built the Docker image for the ARM64 instruction set architecture, be sure to use the --platform linux/
option instead of arm64
--platform linux/
.amd64
From a new terminal window, post an event to the local endpoint.
In Linux and macOS, run the following curl
command:
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
This command invokes the function with an empty event and returns a response. If you're using your own function code rather than the sample function code, you might want to invoke the function with a JSON payload. Example:
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}
'
In PowerShell, run the following Invoke-WebRequest
command:
Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
This command invokes the function with an empty event and returns a response. If you're using your own function code rather than the sample function code, you might want to invoke the function with a JSON payload. Example:
Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}
' -ContentType "application/json"
Get the container ID.
docker ps
Use the docker kill command to stop the container. In this command, replace 3766c4ab331c
with the container ID from the previous step.
docker kill 3766c4ab331c
Run the get-login-password command to authenticate the Docker CLI to your Amazon ECR registry.
Set the --region
value to the AWS Region where you want to create the Amazon ECR repository.
Replace 111122223333
with your AWS account ID.
aws ecr get-login-password --region us-east-1
| docker login --username AWS --password-stdin 111122223333
.dkr.ecr.us-east-1
.amazonaws.com
Create a repository in Amazon ECR using the create-repository command.
aws ecr create-repository --repository-name hello-world
--region us-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
Note
The Amazon ECR repository must be in the same AWS Region as the Lambda function.
If successful, you see a response like this:
{
"repository": {
"repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
"registryId": "111122223333",
"repositoryName": "hello-world",
"repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
"createdAt": "2023-03-09T10:39:01+00:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": true
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
}
Copy the repositoryUri
from the output in the previous step.
Run the docker tag command to tag your local image into your Amazon ECR repository as the latest version. In this command:
docker-image:test
is the name and tag of your Docker image. This is the image name and tag that you specified in the docker build
command.
Replace <ECRrepositoryUri>
with the repositoryUri
that you copied. Make sure to include :latest
at the end of the URI.
docker tag docker-image:test <ECRrepositoryUri>
:latest
Example:
docker tag docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest
Run the docker push command to deploy your local image to the Amazon ECR repository. Make sure to include :latest
at the end of the repository URI.
docker push 111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest
Create an execution role for the function, if you don't already have one. You need the Amazon Resource Name (ARN) of the role in the next step.
Create the Lambda function. For ImageUri
, specify the repository URI from earlier. Make sure to include :latest
at the end of the URI.
aws lambda create-function \
--function-name hello-world
\
--package-type Image \
--code ImageUri=111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest \
--role arn:aws:iam::111122223333:role/lambda-ex
Note
You can create a function using an image in a different AWS account, as long as the image is in the same Region as the Lambda function. For more information, see Amazon ECR cross-account permissions.
Invoke the function.
aws lambda invoke --function-name hello-world
response.json
You should see a response like this:
{
"ExecutedVersion": "$LATEST",
"StatusCode": 200
}
To see the output of the function, check the response.json
file.
To update the function code, you must build the image again, upload the new image to the Amazon ECR repository, and then use the update-function-code command to deploy the image to the Lambda function.
Lambda resolves the image tag to a specific image digest. This means that if you point the image tag that was used to deploy the function to a new image in Amazon ECR, Lambda doesn't automatically update the function to use the new image.
To deploy the new image to the same Lambda function, you must use the update-function-code command, even if the image tag in Amazon ECR remains the same. In the following example, the --publish
option creates a new version of the function using the updated container image.
aws lambda update-function-code \
--function-name hello-world
\
--image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\
--publish
Using an alternative base image with the runtime interface client
If you use an OS-only base image or an alternative base image, you must include the runtime interface client in your image. The runtime interface client extends the Runtime API, which manages the interaction between Lambda and your function code.
Install the Lambda runtime interface client for Ruby using the RubyGems.org package manager:
gem install aws_lambda_ric
You can also download the Ruby runtime interface client from GitHub.
The following example demonstrates how to build a container image for Ruby using a non-AWS base image. The example Dockerfile uses an official Ruby base image. The Dockerfile includes the runtime interface client.
To complete the steps in this section, you must have the following:
To create a container image for Ruby using an alternative base imageCreate a directory for the project, and then switch to that directory.
mkdir example
cd example
Create a new file called Gemfile
. This is where you list your application's required RubyGems packages. The AWS SDK for Ruby is available from RubyGems. You should choose specific AWS service gems to install. For example, to use the Ruby gem for Lambda, your Gemfile should look like this:
source 'https://rubygems.org'
gem 'aws-sdk-lambda'
Alternatively, the aws-sdk gem contains every available AWS service gem. This gem is very large. We recommend that you use it only if you depend on many AWS services.
Install the dependencies specified in the Gemfile using bundle install.
bundle install
Create a new file called lambda_function.rb
. You can add the following sample function code to the file for testing, or use your own.
module LambdaFunction
class Handler
def self.process(event:,context:)
"Hello from Lambda!"
end
end
end
Create a new Dockerfile. The following Dockerfile uses a Ruby base image instead of an AWS base image. The Dockerfile includes the runtime interface client for Ruby, which makes the image compatible with Lambda. Alternatively, you can add the runtime interface client to your application's Gemfile.
Set the FROM
property to the Ruby base image.
Create a directory for the function code and an environment variable that points to that directory. In this example, the directory is /var/task
, which mirrors the Lambda execution environment. However, you can choose any directory for the function code because the Dockerfile doesn't use an AWS base image.
Set the ENTRYPOINT
to the module that you want the Docker container to run when it starts. In this case, the module is the runtime interface client.
Set the CMD
argument to the Lambda function handler.
Note that the example Dockerfile does not include a USER instruction. When you deploy a container image to Lambda, Lambda automatically defines a default Linux user with least-privileged permissions. This is different from standard Docker behavior which defaults to the root
user when no USER
instruction is provided.
FROM ruby:2.7
# Install the runtime interface client for Ruby
RUN gem install aws_lambda_ric
# Add the runtime interface client to the PATH
ENV PATH="/usr/local/bundle/bin:${PATH}"
# Create a directory for the Lambda function
ENV LAMBDA_TASK_ROOT=/var/task
RUN mkdir -p ${LAMBDA_TASK_ROOT}
WORKDIR ${LAMBDA_TASK_ROOT}
# Copy Gemfile and Gemfile.lock
COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/
# Install Bundler and the specified gems
RUN gem install bundler:2.4.20 && \
bundle config set --local path 'vendor/bundle' && \
bundle install
# Copy function code
COPY lambda_function.rb
${LAMBDA_TASK_ROOT}/
# Set runtime interface client as default command for the container runtime
ENTRYPOINT [ "aws_lambda_ric
" ]
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "lambda_function.LambdaFunction::Handler.process" ]
Build the Docker image with the docker build command. The following example names the image docker-image
and gives it the test
tag. To make your image compatible with Lambda, you must use the --provenance=false
option.
docker buildx build --platform linux/amd64 --provenance=false -t docker-image
:test
.
Note
The command specifies the --platform linux/amd64
option to ensure that your container is compatible with the Lambda execution environment regardless of the architecture of your build machine. If you intend to create a Lambda function using the ARM64 instruction set architecture, be sure to change the command to use the --platform linux/arm64
option instead.
Use the runtime interface emulator to locally test the image. You can build the emulator into your image or use the following procedure to install it on your local machine.
To install and run the runtime interface emulator on your local machineFrom your project directory, run the following command to download the runtime interface emulator (x86-64 architecture) from GitHub and install it on your local machine.
mkdir -p ~/.aws-lambda-rie && \
curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
chmod +x ~/.aws-lambda-rie/aws-lambda-rie
To install the arm64 emulator, replace the GitHub repository URL in the previous command with the following:
https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
$dirPath = "$HOME\.aws-lambda-rie"
if (-not (Test-Path $dirPath)) {
New-Item -Path $dirPath -ItemType Directory
}
$downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
$destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
To install the arm64 emulator, replace the $downloadLink
with the following:
https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
Start the Docker image with the docker run command. Note the following:
docker-image
is the image name and test
is the tag.
aws_lambda_ric lambda_function.LambdaFunction::Handler.process
is the ENTRYPOINT
followed by the CMD
from your Dockerfile.
docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
--entrypoint /aws-lambda/aws-lambda-rie \
docker-image:test
\
aws_lambda_ric lambda_function.LambdaFunction::Handler.process
docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
--entrypoint /aws-lambda/aws-lambda-rie `
docker-image:test
`
aws_lambda_ric lambda_function.LambdaFunction::Handler.process
This command runs the image as a container and creates a local endpoint at localhost:9000/2015-03-31/functions/function/invocations
.
If you built the Docker image for the ARM64 instruction set architecture, be sure to use the --platform linux/
option instead of arm64
--platform linux/
.amd64
Post an event to the local endpoint.
In Linux and macOS, run the following curl
command:
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
This command invokes the function with an empty event and returns a response. If you're using your own function code rather than the sample function code, you might want to invoke the function with a JSON payload. Example:
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}
'
In PowerShell, run the following Invoke-WebRequest
command:
Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
This command invokes the function with an empty event and returns a response. If you're using your own function code rather than the sample function code, you might want to invoke the function with a JSON payload. Example:
Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}
' -ContentType "application/json"
Get the container ID.
docker ps
Use the docker kill command to stop the container. In this command, replace 3766c4ab331c
with the container ID from the previous step.
docker kill 3766c4ab331c
Run the get-login-password command to authenticate the Docker CLI to your Amazon ECR registry.
Set the --region
value to the AWS Region where you want to create the Amazon ECR repository.
Replace 111122223333
with your AWS account ID.
aws ecr get-login-password --region us-east-1
| docker login --username AWS --password-stdin 111122223333
.dkr.ecr.us-east-1
.amazonaws.com
Create a repository in Amazon ECR using the create-repository command.
aws ecr create-repository --repository-name hello-world
--region us-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
Note
The Amazon ECR repository must be in the same AWS Region as the Lambda function.
If successful, you see a response like this:
{
"repository": {
"repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
"registryId": "111122223333",
"repositoryName": "hello-world",
"repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
"createdAt": "2023-03-09T10:39:01+00:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": true
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
}
Copy the repositoryUri
from the output in the previous step.
Run the docker tag command to tag your local image into your Amazon ECR repository as the latest version. In this command:
docker-image:test
is the name and tag of your Docker image. This is the image name and tag that you specified in the docker build
command.
Replace <ECRrepositoryUri>
with the repositoryUri
that you copied. Make sure to include :latest
at the end of the URI.
docker tag docker-image:test <ECRrepositoryUri>
:latest
Example:
docker tag docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest
Run the docker push command to deploy your local image to the Amazon ECR repository. Make sure to include :latest
at the end of the repository URI.
docker push 111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest
Create an execution role for the function, if you don't already have one. You need the Amazon Resource Name (ARN) of the role in the next step.
Create the Lambda function. For ImageUri
, specify the repository URI from earlier. Make sure to include :latest
at the end of the URI.
aws lambda create-function \
--function-name hello-world
\
--package-type Image \
--code ImageUri=111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest \
--role arn:aws:iam::111122223333:role/lambda-ex
Note
You can create a function using an image in a different AWS account, as long as the image is in the same Region as the Lambda function. For more information, see Amazon ECR cross-account permissions.
Invoke the function.
aws lambda invoke --function-name hello-world
response.json
You should see a response like this:
{
"ExecutedVersion": "$LATEST",
"StatusCode": 200
}
To see the output of the function, check the response.json
file.
To update the function code, you must build the image again, upload the new image to the Amazon ECR repository, and then use the update-function-code command to deploy the image to the Lambda function.
Lambda resolves the image tag to a specific image digest. This means that if you point the image tag that was used to deploy the function to a new image in Amazon ECR, Lambda doesn't automatically update the function to use the new image.
To deploy the new image to the same Lambda function, you must use the update-function-code command, even if the image tag in Amazon ECR remains the same. In the following example, the --publish
option creates a new version of the function using the updated container image.
aws lambda update-function-code \
--function-name hello-world
\
--image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\
--publish
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4