- NAME
- SYNOPSIS
- DESCRIPTION
- COMMANDS
- OPTIONS
- CONFIGURATION
- WORKFLOW
- MAKEFILE VARIABLES
- MAKEFILE TARGETS
- REQUIRED IAM PERMISSIONS
- OPTIONAL DEPENDENCIES
- SEE ALSO
- AUTHOR
- LICENSE
Amazon::Lambda::Runtime::Builder - Project scaffolding and environment checker for Perl Lambda container images
# Scaffold a new project in the current directory
alr-builder install
# Scaffold into a specific directory
alr-builder install --install-dir /path/to/my-lambda
# Verify tools and IAM permissions before your first build
alr-builder check
# Validate lambda.env (or lambda.yaml) against this Lambda's requirements
alr-builder check-env-file
# Migrate an existing lambda.env to lambda.yaml
alr-builder generate-yaml
Amazon::Lambda::Runtime::Builder is the companion deployment tool for
Amazon::Lambda::Runtime. It handles everything outside of the Perl
runtime itself: scaffolding a new project directory, verifying your build
environment, and documenting the full build and deploy workflow.
It provides four commands via the alr-builder CLI:
- install - copies the project scaffold (Dockerfile, Makefile, handler template, cpanfile, and test fixtures) into a target directory.
- check - verifies that required system tools are present on
your
PATHand, if the optional IAM modules are installed, confirms that your AWS credentials have sufficient permissions to build and deploy. - check-env-file - validates
lambda.env(orlambda.yaml, if present) against this Lambda's configuration requirements, reporting missing required values, customized values, and values using defaults. - generate-yaml - migrates an existing, hand-written
lambda.envto a minimallambda.yaml, the starting point for the generate-on-demand workflow described in "CONFIGURATION".
alr-builder install [--install-dir DIR]
Copies the project scaffold from the distribution's share/ directory
into the target directory (defaults to the current working directory).
Creates the directory if it does not exist.
The following files are installed:
Dockerfile- multi-stage build usingdebian:trixie-slim. The builder stage installs Perl, build tools, and yourcpanfiledependencies via Carton. The runtime stage is a minimal image containing only the Perl interpreter, runtime libraries, and your handler.LambdaHandler.pm.in- handler template with stub implementations for SQS, SNS, S3, and EventBridge events, plus a streaming response example for Function URL invocations. Rename or copy this file and customize it for your Lambda.Makefile(installed asMakefile.build, renamed on install)- provides targets for the complete build and deployment workflow. See "WORKFLOW" and "MAKEFILE TARGETS".
cpanfile- starting point for your Perl dependencies. Add modules here.- Test fixture makefiles -
sqs-test.mk,sns-test.mk,s3-test.mk,eventbridge-test.mk,streaming-test.mk- provide targets for creating and testing each event source trigger. payload.json,payload-sns.json- sample invocation payloads formake invokeandmake test-sns.ecr-create-repo.mk- creates the ECR repository if it does not already exist.policies- IAM managed policy ARNs to attach to the Lambda execution role. Add one ARN per line; lines beginning with#are comments.
alr-builder check
Verifies that your environment is ready to build and deploy. Checks two things:
Required system tools - docker and make must be on your
PATH. curl is checked as an optional tool. Missing required
tools are reported as errors.
IAM permissions - if Amazon::API::IAM, Amazon::API::STS, and
Amazon::Credentials are installed, calls SimulatePrincipalPolicy
using your current credentials to confirm your IAM identity has the
permissions required to build and deploy. See "REQUIRED IAM PERMISSIONS"
for the full list.
If the IAM modules are not installed, tool checks still run but permission checking is skipped with a warning.
alr-builder check-env-file
Validates the project's configuration against this Lambda's requirements
(see "CONFIGURATION"). Reads lambda.env if present - an absent
lambda.env is treated as "nothing configured yet", useful for seeing
the full set of required and defaulted values for a brand-new project -
and reports three groups:
- MISSING (required) - required values with no default that are
not set.
image.handler(HANDLER_CLASS) is required for every trigger type;trigger.bucket(BUCKET_NAME) is additionally required for thes3-sqstrigger type. - Customized - values present in
lambda.envthat differ from theirlambda-mapping.ymldefault, or have no default at all. - Using defaults - values not set in
lambda.env, and the default that applies in their place.
Exits non-zero if any required values are missing.
alr-builder generate-yaml
Migrates an existing lambda.env to lambda.yaml. Requires
lambda.env to exist and lambda.yaml to not already exist - this is a
one-time migration step, not something to re-run once lambda.yaml is
your source of truth (see "CONFIGURATION").
Performs the same validation as check-env-file first; if any required
values are missing, no lambda.yaml is written and the missing fields
are reported instead. Otherwise, writes a minimal lambda.yaml
containing only values that differ from their defaults (plus any field
with no default, such as trigger.bucket/trigger.prefix) - fields
matching their default are omitted, since Makefile.mk applies the same
defaults via lambda-mapping.yml.
-
--install-dir|-iDIRTarget directory for
install. Defaults to the current working directory. -
--log-level|-lLEVELLog verbosity. Accepts Log4perl level names:
trace,debug,info(default),warn,error,fatal. -
--help|-hDisplay usage information.
Your Lambda's configuration - function name, memory, timeout, trigger
details, and so on - lives in lambda.env, a flat KEY = value file
that Makefile.mk reads via -include lambda.env. Every field has a
corresponding entry in lambda-mapping.yml (installed as part of this
distribution), which also defines each field's default.
lambda.env can be managed in either of two ways:
- Hand-written - edit
lambda.envdirectly. This is the original, and still fully supported, workflow. Runalr-builder check-env-fileto verify it againstlambda-mapping.yml's requirements. - Generated from lambda.yaml - write a
lambda.yamldescribing only the values that matter for your Lambda; everything else comes fromlambda-mapping.yml's defaults.alr-builderregenerateslambda.envfromlambda.yamlautomatically wheneverlambda.yamlis newer thanlambda.env, or whenlambda-mapping.yml's mapping version has changed sincelambda.envwas last generated. A generatedlambda.envbegins with a header noting it is generated; hand edits to it are overwritten the next timelambda.yamlchanges.
To move an existing lambda.env to the lambda.yaml workflow, run
alr-builder generate-yaml once.
For the s3-sqs trigger type (currently the only supported type):
image:
repo: ... # ECR repository name (REPO_NAME)
handler: ... # Perl handler class (HANDLER_CLASS) - required
lambda:
name: ... # function name (FUNCTION_NAME)
timeout: ... # seconds (TIMEOUT)
memory: ... # MB (MEMORY)
concurrency: ... # reserved concurrency (CONCURRENCY)
role:
name: ... # IAM role name (ROLE_NAME)
profile: ... # named policy profile (ROLE_PROFILE)
trigger:
type: s3-sqs
bucket: ... # source S3 bucket (BUCKET_NAME) - required
prefix: ... # key prefix filter (KEY_PREFIX)
event: ... # S3 event type (S3_EVENT)
queue:
name: ... # SQS queue name (QUEUE_NAME)
batch_size: ... # (BATCH_SIZE)
visibility_timeout: ... # seconds (VISIBILITY_TIMEOUT)
retention: ... # seconds (RETENTION)
receive_count: ... # max receives before DLQ (RECEIVE_COUNT)
partial_batch_response: ... # true/false (PARTIAL_BATCH_RESPONSE)
dlq:
name: ... # DLQ name (DLQ_NAME)
retention: ... # seconds (DLQ_RETENTION)
image.handler is required for every trigger type; trigger.bucket is
additionally required for s3-sqs. Every other field may be omitted, in
which case lambda-mapping.yml's default applies. See "MAKEFILE
TARGETS" for how role.profile is applied.
The typical workflow for a new Lambda function:
-
Scaffold the project:
alr-builder install --install-dir my-lambda cd my-lambda -
Verify your environment:
alr-builder check -
Implement your handler - edit
LambdaHandler.pm.inor create your own handler module. Add dependencies tocpanfile. -
Build a CPAN distribution -
installprovides a template handler module (LambdaHandler.pm.in); turn it into a standard CPAN distribution (with its ownMETA.json/Makefile.PLor equivalent) using whatever tooling you prefer, then runmake distto produce a distribution tarball.make imageresolvesDIST_TARBALLto the most recent$(DIST_NAME)-*.tar.gzin$(BUILDER_HOME), whereDIST_NAMEcomes from that distribution'sMETA.json. -
First-time deployment - builds the image, pushes to ECR, creates the IAM role and Lambda function:
make lambda-function -
Test:
make invoke -
Deploy subsequent changes:
make update-function
make image requires a CPAN distribution tarball
($(DIST_NAME)-*.tar.gz) to already exist in $(BUILDER_HOME) -
see Workflow step 4.
Lambda runs your handler inside an OCI-compliant container image. The
image must contain a Perl interpreter, your CPAN dependencies,
Amazon::Lambda::Runtime, the bootstrap entrypoint, the plambda.pl
driver, and your handler module.
The installed Dockerfile handles all of this. Build with:
make image
The key Dockerfile directives that wire everything together:
ARG LAMBDA_MODULE=LambdaHandler.pm
COPY ${LAMBDA_MODULE} /usr/src/app/local/lib/perl5
ENV PERL5LIB=/usr/src/app/local/lib/perl5
ENV LAMBDA_MODULE=${LAMBDA_MODULE}
ENTRYPOINT ["/usr/local/bin/bootstrap"]
ENV LAMBDA_MODULE tells bootstrap which handler to load.
Set LAMBDA_MODULE at build time to use a different handler module:
make image LAMBDA_MODULE=MyHandler.pm
Once the image is built it must be pushed to ECR and the Lambda function created or updated.
For a first-time deployment, a single target runs the full dependency chain automatically:
make lambda-function
This runs: ecr-repo => deploy => lambda-role => lambda-policies
=> lambda-function. Each step is idempotent - re-running is always safe.
Sentinel files track completed steps so make skips what already exists.
To deploy a code change:
make update-function
This rebuilds the image, pushes to ECR using the image digest (never
:latest), and updates the Lambda function code.
The installed Makefile already includes all five trigger makefiles, so all trigger targets are available immediately. Use whichever targets apply to your Lambda:
make lambda-sqs-trigger QUEUE_NAME=my-queue
make lambda-s3-trigger BUCKET_NAME=my-bucket
make lambda-eventbridge-trigger
make lambda-function-url
make test-streaming
See "MAKEFILE TARGETS" for the full list of targets provided by each trigger makefile and the variables that control their behavior.
The policies file controls which IAM managed policies are attached
to the Lambda execution role. Add one policy ARN per line:
# required - CloudWatch logging
arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
# uncomment for SQS trigger
# arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
# uncomment for S3 read access
# arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Apply changes at any time:
make update-policies
Note: receiving an event from a service does not automatically grant
your handler permission to call that service's APIs. An S3 trigger allows
Lambda to invoke your function - it does not allow your function to read
or write S3 objects. For broad access, add or uncomment the appropriate
managed policy ARN in the policies file and run make update-policies.
For access to a specific resource - a particular bucket, queue, or topic -
create a custom IAM policy that scopes the permissions to that resource ARN
and attach it to the execution role (ROLE_NAME) via the AWS console or
CLI, then add its ARN to the policies file so make update-policies
keeps it attached on subsequent deployments.
For s3-sqs configuration (function name, memory, timeout, queue
settings, and so on), see "CONFIGURATION" and lambda-mapping.yml.
The variables below are either tool-level (apply regardless of trigger
type) or specific to trigger types not yet covered by lambda.yaml.
-
AWS_PROFILEAWS profile. Default:
default -
REGIONAWS region. Default:
us-east-1 -
PERL_LAMBDADocker image name (local). Default:
perl-lambda -
LAMBDA_MODULEYour handler module filename. Default:
LambdaHandler.pm -
PAYLOADPayload file for
make invoke. Default:payload.json -
AWS_ACCOUNTAWS account ID. Resolved automatically via
alr-helper get-accountif not set. Set it explicitly to avoid the STS call:export AWS_ACCOUNT=$(alr-helper get-account) -
RULE_NAMEEventBridge rule name. Default:
lambda-handler-test -
SCHEDULE_EXPRESSIONEventBridge schedule. Default:
rate(1 minute) -
INVOKE_MODELambda Function URL invoke mode. Default:
RESPONSE_STREAM
-
lambda-functionFirst-time deployment. Runs the full dependency chain: ECR repository, IAM role, policies, image build, push, and function creation. Run once per function.
-
update-functionDeploy a code change. Rebuilds the image, pushes to ECR, and updates the Lambda function code.
-
invokeTest the function with
$(PAYLOAD)and print the response. -
cleanRemove local sentinel files. AWS resources are not affected.
-
update-policiesRe-attach IAM policies to the execution role. If
ROLE_PROFILEis set (inlambda.env/lambda.yaml), attaches the policies listed for that profile inprofiles.yml; otherwise, attaches the policies listed in thepoliciesfile. -
lambda-configurationUpdates the function's memory and timeout from
lambda.env(MEMORY,TIMEOUT) viaUpdateFunctionConfiguration. Useful for applying a configuration-only change without rebuilding the image.
-
lambda-sqs-triggerCreates an SQS queue (
QUEUE_NAME) and attaches it as an event source. RequiresAWSLambdaSQSQueueExecutionRolein thepoliciesfile. A component oflambda-sqs-pipeline; run that instead unless you specifically need just the queue/event-source step. -
lambda-sqs-pipelineRuns the full
s3-sqstrigger setup: creates the SQS queue and DLQ, configures the S3-to-SQS event source mapping, sets reserved concurrency (CONCURRENCY), applieslambda-configuration(MEMORY/TIMEOUT), and sets the event source mapping'sFunctionResponseTypesaccording toPARTIAL_BATCH_RESPONSE. This is the target to run - or re-run after editinglambda.yaml/lambda.env- fors3-sqsprojects. -
lambda-s3-triggerConfigures S3 bucket notifications to invoke the Lambda on
S3_EVENTevents. -
lambda-eventbridge-triggerRegisters the Lambda as the target of an EventBridge scheduled rule.
-
enable-eventbridge-rule/disable-eventbridge-ruleEnables or disables the EventBridge rule without deleting infrastructure. Use
disable-eventbridge-ruleafter testing to stop scheduled invocations. -
delete-eventbridge-ruleRemoves targets and deletes the rule. Targets must be removed before the rule can be deleted.
-
lambda-function-urlCreates a Lambda Function URL with
auth-type NONEandInvokeMode=$(INVOKE_MODE). -
test-streamingInvokes the Function URL with
curl -sNto test streaming responses.
Called automatically as dependencies - you should not need to invoke these directly:
image - builds the Docker image.
ecr-repo - creates the ECR repository if it does not exist.
deploy - logs in to ECR and pushes the image using the image digest.
lambda-role - creates the IAM execution role if it does not exist.
lambda-policies - attaches policies to the execution role, either from
profiles.yml (if ROLE_PROFILE is set) or the policies file.
lambda-concurrency - sets reserved concurrency (CONCURRENCY) via
PutFunctionConcurrency.
lambda-sqs-response-types - sets the SQS event source mapping's
FunctionResponseTypes according to PARTIAL_BATCH_RESPONSE.
policy-document - generates the IAM assume-role trust policy JSON.
The check command verifies these permissions via
SimulatePrincipalPolicy. You will need them to run the full build and
deploy workflow.
ecr:CreateRepository ecr:DescribeRepositories
ecr:GetAuthorizationToken ecr:BatchCheckLayerAvailability
ecr:PutImage ecr:InitiateLayerUpload
ecr:UploadLayerPart ecr:CompleteLayerUpload
ecr:PutLifecyclePolicy ecr:GetLifecyclePolicy
iam:GetRole iam:CreateRole
iam:AttachRolePolicy iam:PassRole
iam:ListAttachedRolePolicies
Note: iam:PassRole is frequently overlooked. Its absence produces
a confusing InvalidParameterValueException stating the role cannot be
assumed by Lambda even though the role exists and appears correct.
lambda:GetFunction lambda:CreateFunction
lambda:UpdateFunctionCode lambda:UpdateFunctionConfiguration
lambda:GetFunctionConfiguration lambda:InvokeFunction
lambda:CreateEventSourceMapping lambda:ListEventSourceMappings
lambda:GetPolicy lambda:AddPermission
lambda:RemovePermission lambda:CreateFunctionUrlConfig
lambda:GetFunctionUrlConfig lambda:DeleteFunctionUrlConfig
sqs:ListQueues sqs:CreateQueue
sns:ListTopics sns:CreateTopic
sns:Subscribe sns:GetTopicAttributes
s3:CreateBucket s3:ListBuckets
s3:PutBucketNotificationConfiguration
events:DescribeRule events:PutRule
events:PutTargets events:RemoveTargets
events:DeleteRule events:EnableRule
events:DisableRule
sts:GetCallerIdentity
AWSLambdaBasicExecutionRole covers CloudWatch logging only. Any AWS
APIs your handler calls directly require additional policies in the
policies file. For example, a handler that reads S3 objects needs
AmazonS3ReadOnlyAccess even if its trigger is an S3 event notification
- the trigger and the API access are governed by separate policies.
IAM permission checking in check requires:
These are not hard dependencies - the tool is fully functional without
them, but check will only verify system tools.
Amazon::Lambda::Runtime - the runtime library your handler inherits from
Amazon::Credentials - credential provider used for IAM permission checking
Amazon::API::IAM, Amazon::API::STS - AWS API clients used by check
Rob Lauer - rlauer@treasurersbriefcase.com
(c) Copyright 2019-2026 Robert C. Lauer. All rights reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.