Self-hosted setup for Serverless Workers
Temporal Cloud handles Serverless Worker infrastructure automatically. Self-hosted Temporal Service operators must enable the feature and configure the server to invoke compute providers.
This page covers the prerequisites for running Serverless Workers on a self-hosted Temporal Service with AWS Lambda. Once setup is complete, follow the AWS Lambda deployment guide to deploy your Worker.
Enable the Worker Controller
The Worker Controller is the server component that monitors Task Queues and invokes compute providers. It is disabled by default and must be enabled through dynamic configuration.
Add the following keys to your dynamic config file:
workercontroller.enabled:
- value: true
workercontroller.compute_providers.enabled:
- value:
- aws-lambda
workercontroller.scaling_algorithms.enabled:
- value:
- no-sync
To enable the Worker Controller for specific Namespaces instead of globally:
workercontroller.enabled:
- value: true
constraints:
namespace: "your-namespace"
The Temporal Service watches the dynamic config file for changes and applies updates without a restart.
Worker Controller dynamic config reference
| Key | Scope | Default | Description |
|---|---|---|---|
workercontroller.enabled | Namespace | false | Enables the Worker Controller for a Namespace. |
workercontroller.compute_providers.enabled | Global | none | List of enabled compute providers (e.g., ["aws-lambda"]). |
workercontroller.scaling_algorithms.enabled | Global | none | List of enabled scaling algorithms (e.g., ["no-sync"]). |
workercontroller.maxInstances | Namespace | 100 | Maximum number of Worker Controller instances per Namespace. |
workercontroller.compute_providers.aws.require_role_and_external_id | Global | true | Whether AWS Lambda compute providers require a role ARN and external ID. |
Configure AWS credentials
The Temporal Service needs AWS credentials to assume an IAM role that invokes Lambda functions. How you provide credentials depends on where the Temporal Service runs.
On AWS infrastructure (EC2, ECS, EKS): The server uses the attached instance role, task role, or pod role automatically. No additional credential configuration is needed. The attached role must have sts:AssumeRole permission for the Lambda invocation role created in the next step.
Outside AWS: Configure AWS credentials in the server's environment:
AWS_ACCESS_KEY_ID=<access-key>
AWS_SECRET_ACCESS_KEY=<secret-key>
AWS_REGION=<region>
These credentials must belong to an IAM user or role that has sts:AssumeRole permission for the Lambda invocation role.
Create the Lambda invocation role
Temporal invokes Lambda functions by assuming an IAM role in your AWS account.
This role needs lambda:InvokeFunction permission on your Worker Lambda functions, and a trust policy that allows the Temporal server's identity to assume it.
Deploy the following CloudFormation template to create the role. Download the template.
| Parameter | Description |
|---|---|
TemporalIamRoleArn | The ARN of the IAM role or user that the Temporal Service runs as. This is the identity the server uses to call sts:AssumeRole. To find the ARN, run aws sts get-caller-identity in the server's environment. |
AssumeRoleExternalId | A unique string to prevent confused deputy attacks. Choose any value and pass the same value when creating the Worker Deployment Version. |
LambdaFunctionARNs | Comma-separated list of Lambda function ARNs that Temporal may invoke. |
RoleName | Base name for the created IAM role. Defaults to Temporal-Serverless-Worker. |
CloudFormation template
AWSTemplateFormatVersion: '2010-09-09'
Description: Creates an IAM role that a self-hosted Temporal Service can assume to invoke Lambda functions for Serverless Workers.
Parameters:
TemporalIamRoleArn:
Type: String
Description: The ARN of the IAM role or user that the Temporal Service runs as.
AssumeRoleExternalId:
Type: String
Description: A unique identifier to prevent confused deputy attacks.
AllowedPattern: '[a-zA-Z0-9_+=,.@-]*'
MinLength: 5
MaxLength: 45
LambdaFunctionARNs:
Type: CommaDelimitedList
Description: >-
Comma-separated list of Lambda function ARNs to invoke
(e.g., arn:aws:lambda:us-west-2:123456789012:function:worker-1,arn:aws:lambda:us-west-2:123456789012:function:worker-2)
RoleName:
Type: String
Default: 'Temporal-Serverless-Worker'
Resources:
TemporalServerlessWorker:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${RoleName}-${AWS::StackName}'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS:
[!Ref TemporalIamRoleArn]
Action: sts:AssumeRole
Condition:
StringEquals:
'sts:ExternalId': [!Ref AssumeRoleExternalId]
Description: "The role the Temporal Service uses to invoke Lambda functions for Serverless Workers"
MaxSessionDuration: 3600
TemporalLambdaInvokePermissions:
Type: AWS::IAM::Policy
DependsOn: TemporalServerlessWorker
Properties:
PolicyName: 'Temporal-Lambda-Invoke-Permissions'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- lambda:InvokeFunction
- lambda:GetFunction
Resource: !Ref LambdaFunctionARNs
Roles:
- !Sub '${RoleName}-${AWS::StackName}'
Outputs:
RoleARN:
Description: The ARN of the IAM role created for the Temporal Service
Value: !GetAtt TemporalServerlessWorker.Arn
Export:
Name: !Sub "${AWS::StackName}-RoleARN"
RoleName:
Description: The name of the IAM role
Value: !Ref RoleName
LambdaFunctionARNs:
Description: The Lambda function ARNs that can be invoked
Value: !Join [", ", !Ref LambdaFunctionARNs]
Deploy the template:
aws cloudformation create-stack --stack-name temporal-serverless-worker --template-body file://temporal-self-hosted-serverless-worker-role.yaml --parameters ParameterKey=TemporalIamRoleArn,ParameterValue=<TEMPORAL_SERVER_ROLE_ARN> ParameterKey=AssumeRoleExternalId,ParameterValue=<EXTERNAL_ID> ParameterKey=LambdaFunctionARNs,ParameterValue='"<LAMBDA_FUNCTION_ARN>"' --capabilities CAPABILITY_NAMED_IAM --region <AWS_REGION>
After the stack finishes creating, retrieve the IAM role ARN from the stack outputs:
aws cloudformation describe-stacks --stack-name temporal-serverless-worker --query 'Stacks[0].Outputs[?OutputKey==`RoleARN`].OutputValue' --output text --region <AWS_REGION>
Use this role ARN when creating the Worker Deployment Version.
Verify the Worker Controller
After you complete the AWS Lambda deployment guide and create a Worker Deployment Version with a compute provider, the Temporal Service starts a Worker Controller Instance (WCI) workflow to manage scaling for that version.
To confirm the WCI is running, list workflows with the TemporalNamespaceDivision search attribute filter:
temporal workflow list --query 'TemporalNamespaceDivision = "TemporalWorkerControllerInstance"'
The WCI workflow is hidden from the default workflow list. In the Temporal UI, add the same filter in the Workflows tab to view it.
To verify end-to-end, start a Workflow on the Task Queue configured for the deployment. The WCI should detect the task, invoke the Lambda function, and the Workflow should complete.