Functions
Functions are Stacktape's abstraction for AWS Lambda, a serverless compute service that lets you run code without managing servers. You can write code in multiple languages and trigger it to run in response to events like HTTP requests, file uploads to an S3 bucket, or messages in an SQS queue.
This allows you to build and deploy web applications, process data, and automate workflows while only paying for the compute time you use.
Example function
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.ts
Stacktape configuration for a basic Lambda function.
// Stacktape will automatically package any library for youimport anyLibrary from 'any-library';import { initializeDatabaseConnection } from './database';// Everything outside of the handler function will be executed only once (on every cold-start).// You can execute any code that should be "cached" here (such as initializing a database connection)const myDatabaseConnection = initializeDatabaseConnection();// handler will be executed on every function invocationconst handler = async (event, context) => {// This log will be published to a CloudWatch log groupconsole.log(event, context);const posts = myDatabaseConnection.query('SELECT * FROM posts');return { result: posts };};export default handler;
Example function code written in TypeScript.
Under the hood
Stacktape Functions are built on top of AWS Lambda, a production-ready, pay-per-request service suitable for a wide range of use cases.
When to use
Lambda functions are a great choice for many applications, including HTTP APIs, scheduled tasks, and event-driven integrations. However, they are not suitable for long-running processes or tasks that require fine-grained control over the execution environment.
Advantages
- Pay-per-use: You are billed only for the compute time you consume, rounded to the nearest millisecond.
- Massive & fast scaling: Functions can scale to thousands of parallel executions in milliseconds.
- High availability: AWS Lambda automatically runs your function in multiple Availability Zones to ensure high availability.
- Secure by default: The underlying environment is securely managed by AWS.
- Lots of integrations: Functions can be triggered by a wide variety of services.
Disadvantages
- Limited execution time: A function can run for a maximum of 15 minutes.
- Limited configuration: You can only configure memory (from 128MB to 10GB), and CPU power scales proportionally.
- More expensive for certain tasks: For continuous or predictable workloads, batch jobs or container workloads can be more cost-effective.
- Cold starts: The first invocation of a function after a period of inactivity can experience a slight delay.
Packaging
In the packaging
section, you specify the path to your code and how it should be built. For more details, see the packaging documentation.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tstimeout: 10memory: 2048
Computing resources
The function's execution environment is fully managed. You can set the memory
from 128MB to 10,240MB. CPU power is allocated proportionally to the memory, with 1,797MB corresponding to one virtual CPU and a maximum of six vCPUs at 10,240MB.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsmemory: 1024
Runtime
- Stacktape automatically detects the function's language and uses the latest runtime version associated with that language.
- Example: uses
nodejs22.x
for all files ending with.js
and.ts
. - For the list of all available lambda runtimes, refer to AWS docs.
Timeout
Sets the maximum execution time for the function in seconds. The default is 3 seconds, and the maximum is 900 seconds (15 minutes).
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tstimeout: 300
Environment variables
Most commonly used types of environment variables:
- Static - string, number or boolean (will be stringified).
- Result of a custom directive.
- Referenced property of another resource (using $ResourceParam directive). To learn more, refer to referencing parameters guide. If you are using environment variables to inject information about resources into your script, see also property connectTo which simplifies this process.
- Value of a secret (using $Secret directive).
environment:- name: STATIC_ENV_VARvalue: my-env-var- name: DYNAMICALLY_SET_ENV_VARvalue: $MyCustomDirective('input-for-my-directive')- name: DB_HOSTvalue: $ResourceParam('myDatabase', 'host')- name: DB_PASSWORDvalue: $Secret('dbSecret.password')
Logging
Any output to stdout
or stderr
is captured and stored in an AWS CloudWatch log group. You can view logs through the Stacktape Console, the stacktape stack-info
command, or by streaming them with the stacktape logs
command.
To manage costs, you can configure retentionDays
to automatically delete old logs.
Forwarding logs
You can forward logs to third-party services. For more information, see the Log Forwarding documentation.
Storage
Each function has access to 512MB of temporary, ephemeral storage at /tmp
. This storage is not shared between concurrent executions but can be used for caching data within a single execution environment. For persistent storage, use Buckets.
Trigger events
Functions are invoked in response to events. Stacktape automatically creates the necessary integrations and permissions for your specified triggers. A single function can have multiple event integrations, and the payload it receives will vary based on the event source.
HTTP API event
Triggers the function when a request is made to a specified HTTP API Gateway.
resources:myHttpApi:type: http-api-gatewaymyLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: http-api-gatewayproperties:httpApiGatewayName: myHttpApipath: /hellomethod: GET
Cognito authorizer
Restricts access to users authenticated with a User Pool.
resources:myGateway:type: http-api-gatewaymyUserPool:type: user-auth-poolproperties:userVerificationType: email-codemyLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: src/my-lambda.tsevents:- type: http-api-gatewayproperties:httpApiGatewayName: myGatewaypath: /some-pathmethod: '*'authorizer:type: cognitoproperties:userPoolName: myUserPool
import { CognitoIdentityProvider } from '@aws-sdk/client-cognito-identity-provider';const cognito = new CognitoIdentityProvider({});const handler = async (event, context) => {const userData = await cognito.getUser({ AccessToken: event.headers.authorization });// do something with your user data};export default handler;
Lambda authorizer
Uses another Lambda function to authorize incoming requests.
Schedule event
Triggers the function on a fixed rate or cron schedule.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:# invoke function every two hours- type: scheduleproperties:scheduleRate: rate(2 hours)# invoke function at 10:00 UTC every day- type: scheduleproperties:scheduleRate: cron(0 10 * * ? *)
Event Bus event
Triggers the function when a matching event is received by an event bus.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: event-busproperties:useDefaultBus: trueeventPattern:source:- 'aws.autoscaling'region:- 'us-west-2'
resources:myEventBus:type: event-busmyLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: event-busproperties:eventBusName: myEventBuseventPattern:source:- 'mycustomsource'
Kafka Topic event
Triggers the function when messages are available in a Kafka topic.
resources:# is triggered when there are records in custom configured kafka topicmyConsumer:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: consumer.tsevents:- type: kafka-topicproperties:customKafkaConfiguration:bootstrapServers:- my-kafka-broker-1.my-domain.com:9092- my-kafka-broker-2.my-domain.com:9092topicName: myTopicauthentication:type: SASL_SCRAM_256_AUTHproperties:authenticationSecretArn: arn:aws:secretsmanager:eu-west-1:xxxxxxxxxxx:secret:mySecret
SNS event
Triggers the function when a message is published to an SNS topic.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: snsproperties:snsTopicName: mySnsTopicmySnsTopic:type: sns-topic
SQS event
Triggers the function when messages are available in an SQS queue.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: sqsproperties:sqsQueueName: mySqsQueuemySqsQueue:type: sqs-queue
Kinesis stream event
Triggers the function when records are available in a Kinesis Data Stream.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: 'path/to/my-lambda.ts'events:- type: kinesis-streamproperties:autoCreateConsumer: truemaxBatchWindowSeconds: 30batchSize: 200streamArn: $CfResourceParam('myKinesisStream', 'Arn')onFailure:arn: $CfResourceParam('myOnFailureSqsQueue', 'Arn')type: sqscloudformationResources:myKinesisStream:Type: AWS::Kinesis::StreamProperties:ShardCount: 1myOnFailureSqsQueue:Type: AWS::SQS::Queue
DynamoDB stream event
Triggers the function in response to item-level changes in a DynamoDB table.
resources:myDynamoDbTable:type: dynamo-db-tableproperties:primaryKey:partitionKey:name: idtype: stringstreamType: NEW_AND_OLD_IMAGESmyLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: dynamo-db-streamproperties:streamArn: $ResourceParam('myDynamoDbTable', 'streamArn')# OPTIONALbatchSize: 200
S3 event
Triggers the function in response to events in an S3 bucket.
resources:myBucket:type: bucketmyLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: s3properties:bucketArn: $ResourceParam('myBucket', 'arn')s3EventType: 's3:ObjectCreated:*'filterRule:prefix: order-suffix: .jpg
Cloudwatch Log event
Triggers the function when a log record is added to a CloudWatch log group.
resources:myLogProducingLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: lambdas/log-producer.tsmyLogConsumingLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: lambdas/log-consumer.tsevents:- type: cloudwatch-logproperties:logGroupArn: $ResourceParam('myLogProducingLambda', 'arn')
Alarm event
Triggers the function when a CloudWatch alarm enters the ALARM
state. You can reference alarms created in the Stacktape Console or directly in your configuration file.
resources:myDatabase:type: relational-databaseproperties:engine:type: aurora-mysql-serverlesscredentials:masterUserPassword: my-master-passwordalarms:# alarm fires when cpu utilization is higher than 80%- trigger:type: database-cpu-utilizationproperties:thresholdPercent: 80myFunction:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: 'lambdas/cleanup-function.js'events:- type: cloudwatch-alarmproperties:alarmName: myDatabase.alarms.0
resources:myDatabase:type: relational-databaseproperties:engine:type: aurora-mysql-serverlesscredentials:masterUserPassword: my-master-passwordmyFunction:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: 'lambdas/cleanup-function.js'events:- type: cloudwatch-alarmproperties:alarmName: myDatabase.alarms.CpuUtilization
Application Load Balancer event
Triggers the function when an Application Load Balancer receives a request matching specified rules.
resources:# load balancer which routes traffic to the functionmyLoadBalancer:type: application-load-balancermyLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsevents:- type: application-load-balancerproperties:# referencing load balancer defined aboveloadBalancerName: myLoadBalancerpriority: 1paths:- /invoke-my-lambda- /another-path
Sync vs. Async invocations
Functions can be invoked synchronously or asynchronously, depending on the trigger.
Synchronous invocation
The caller waits for the function to complete and returns its result. This is used by API Gateway, Application Load Balancer, and direct SDK calls.
Asynchronous invocation
The caller queues the function for execution and does not wait for the result. This is used by SNS, SQS, EventBridge, S3, and others. If an asynchronously invoked function fails, AWS Lambda will automatically retry it up to two times.
Lambda Destinations
For asynchronous invocations, you can configure destinations to handle the results. You can send the output of a function to another service (like SQS, SNS, or another Lambda) on success or failure.
resources:myEventBus:type: event-busmySuccessLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: lambdas/success-handler.tsmyLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsdestinations:# if function succeeds, invoke the mySuccessLambda with the result dataonSuccess: $ResourceParam('mySuccessLambda', 'arn')# if the function fails, send the result to "myEventBus"onFailure: $ResourceParam('myEventBus', 'arn')
Accessing other resources
By default, functions cannot access other AWS resources. You must grant permissions explicitly using IAM.
Using connectTo
The connectTo
property is a simplified way to grant access to other Stacktape-managed resources.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsenvironment:- name: MY_BUCKET_NAMEvalue: $ResourceParam('myBucket', 'name')connectTo:# access to the bucket- myBucket# access to AWS SES- aws:sesmyBucket:type: bucket
By referencing resources (or services) in connectTo
list, Stacktape automatically:
- configures correct compute resource's IAM role permissions if needed
- sets up correct security group rules to allow access if needed
- injects relevant environment variables containing information about resource you are connecting to into the compute resource's runtime
- names of environment variables use upper-snake-case and are in form
STP_[RESOURCE_NAME]_[VARIABLE_NAME]
, - examples:
STP_MY_DATABASE_CONNECTION_STRING
orSTP_MY_EVENT_BUS_ARN
, - list of injected variables for each resource type can be seen below.
- names of environment variables use upper-snake-case and are in form
Granted permissions and injected environment variables are different depending on resource type:
Bucket
- Permissions:
- list objects in a bucket
- create / get / delete / tag object in a bucket
- Injected env variables:
NAME
,ARN
DynamoDB table
- Permissions:
- get / put / update / delete item in a table
- scan / query a table
- describe table stream
- Injected env variables:
NAME
,ARN
,STREAM_ARN
MongoDB Atlas cluster
- Permissions:
- Allows connection to a cluster with
accessibilityMode
set toscoping-workloads-in-vpc
. To learn more about MongoDB Atlas clusters accessibility modes, refer to MongoDB Atlas cluster docs. - Creates access "user" associated with compute resource's role to allow for secure credential-less access to the the cluster
- Allows connection to a cluster with
- Injected env variables:
CONNECTION_STRING
Relational(SQL) database
- Permissions:
- Allows connection to a relational database with
accessibilityMode
set toscoping-workloads-in-vpc
. To learn more about relational database accessibility modes, refer to Relational databases docs.
- Allows connection to a relational database with
- Injected env variables:
CONNECTION_STRING
,JDBC_CONNECTION_STRING
,HOST
,PORT
(in case of aurora multi instance cluster additionally:READER_CONNECTION_STRING
,READER_JDBC_CONNECTION_STRING
,READER_HOST
)
Redis cluster
- Permissions:
- Allows connection to a redis cluster with
accessibilityMode
set toscoping-workloads-in-vpc
. To learn more about redis cluster accessibility modes, refer to Redis clusters docs.
- Allows connection to a redis cluster with
- Injected env variables:
HOST
,READER_HOST
,PORT
Event bus
- Permissions:
- publish events to the specified Event bus
- Injected env variables:
ARN
Function
- Permissions:
- invoke the specified function
- invoke the specified function via url (if lambda has URL enabled)
- Injected env variables:
ARN
Batch job
- Permissions:
- submit batch-job instance into batch-job queue
- list submitted job instances in a batch-job queue
- describe / terminate a batch-job instance
- list executions of state machine which executes the batch-job according to its strategy
- start / terminate execution of a state machine which executes the batch-job according to its strategy
- Injected env variables:
JOB_DEFINITION_ARN
,STATE_MACHINE_ARN
User auth pool
- Permissions:
- full control over the user pool (
cognito-idp:*
) - for more information about allowed methods refer to AWS docs
- full control over the user pool (
- Injected env variables:
ID
,CLIENT_ID
,ARN
SNS Topic
- Permissions:
- confirm/list subscriptions of the topic
- publish/subscribe to the topic
- unsubscribe from the topic
- Injected env variables:
ARN
,NAME
SQS Queue
- Permissions:
- send/receive/delete message
- change visibility of message
- purge queue
- Injected env variables:
ARN
,NAME
,URL
Upstash Kafka topic
- Injected env variables:
TOPIC_NAME
,TOPIC_ID
,USERNAME
,PASSWORD
,TCP_ENDPOINT
,REST_URL
Upstash Redis
- Injected env variables:
HOST
,PORT
,PASSWORD
,REST_TOKEN
,REST_URL
,REDIS_URL
Private service
- Injected env variables:
ADDRESS
aws:ses
(Macro)
- Permissions:
- gives full permissions to aws ses (
ses:*
). - for more information about allowed methods refer to AWS docs
- gives full permissions to aws ses (
Using iamRoleStatements
For fine-grained control, you can provide raw IAM role statements.
resources:myFunction:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsenvironment:- name: TOPIC_ARNvalue: $CfResourceParam('NotificationTopic', 'Arn')iamRoleStatements:- Resource:- $CfResourceParam('NotificationTopic', 'Arn')Effect: 'Allow'Action:- 'sns:Publish'cloudformationResources:NotificationTopic:Type: AWS::SNS::Topic
Deployment strategies
- Using
deployment
you can update the function in live environment in a safe way - by shifting the traffic to the new version gradually. - Gradual shift of traffic gives you opportunity to test/monitor the function during update and in a case of a problem swiftly rollback.
- Supports multiple strategies:
- Canary10Percent5Minutes - Shifts 10 percent of traffic in the first increment. The remaining 90 percent is deployed five minutes later.
- Canary10Percent10Minutes - Shifts 10 percent of traffic in the first increment. The remaining 90 percent is deployed 10 minutes later.
- Canary10Percent15Minutes - Shifts 10 percent of traffic in the first increment. The remaining 90 percent is deployed 15 minutes later.
- Canary10Percent30Minutes - Shifts 10 percent of traffic in the first increment. The remaining 90 percent is deployed 30 minutes later.
- Linear10PercentEvery1Minute - Shifts 10 percent of traffic every minute until all traffic is shifted.
- Linear10PercentEvery2Minutes - Shifts 10 percent of traffic every two minutes until all traffic is shifted.
- Linear10PercentEvery3Minutes - Shifts 10 percent of traffic every three minutes until all traffic is shifted.
- Linear10PercentEvery10Minutes - Shifts 10 percent of traffic every 10 minutes until all traffic is shifted.
- AllAtOnce - Shifts all traffic to the updated Lambda functions at once.
- You can validate/abort deployment(update) using lambda-function hooks.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsdeployment:strategy: Linear10PercentEvery1Minute
Hook functions
You can use hook functions to perform checks during deployment.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsdeployment:strategy: Linear10PercentEvery1MinutebeforeAllowTrafficFunction: validateDeploymentvalidateDeployment:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: validate.ts
import { CodeDeployClient, PutLifecycleEventHookExecutionStatusCommand } from '@aws-sdk/client-codedeploy';const client = new CodeDeployClient({});export default async (event) => {// read DeploymentId and LifecycleEventHookExecutionId from payloadconst { DeploymentId, LifecycleEventHookExecutionId } = event;// performing validations hereawait client.send(new PutLifecycleEventHookExecutionStatusCommand({deploymentId: DeploymentId,lifecycleEventHookExecutionId: LifecycleEventHookExecutionId,status: 'Succeeded' // status can be 'Succeeded' or 'Failed'}));};
Cold starts
A cold start is the latency experienced on the first invocation of a function after a period of inactivity. This happens because AWS needs to provision a new container to run your code. Subsequent invocations are much faster until the container is terminated due to inactivity.
The duration of a cold start depends on the runtime, the size of your function package, and the amount of code that runs outside your main handler.
Default VPC connection
Functions are not connected to a VPC by default. If your function needs to access resources inside a VPC (like a Relational Database), you must explicitly connect it.
Connecting a function to a VPC will cut off its access to the public internet. Restoring internet access requires a NAT Gateway, which can be complex and costly.
resources:myLambda:type: functionproperties:packaging:type: stacktape-lambda-buildpackproperties:entryfilePath: path/to/my-lambda.tsjoinDefaultVpc: true
Function connected to the default VPC.
Pricing
You are charged for:
- Total compute: A combination of memory allocated and execution time.
- Number of requests: A flat rate per million invocations.
AWS offers a generous free tier for Lambda. For details, see the AWS pricing page.
Referenceable parameters
The following parameters can be easily referenced using $ResourceParam directive directive.
To learn more about referencing parameters, refer to referencing parameters.
Arn of the function
- Usage:
$ResourceParam('<<resource-name>>', 'arn')
Arn of the log group aggregating logs from the function
- Usage:
$ResourceParam('<<resource-name>>', 'logGroupArn')