-
Notifications
You must be signed in to change notification settings - Fork 306
docs: self-hosted setup for serverless workers #4476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/serverless-worker-prerelease
Are you sure you want to change the base?
Changes from all commits
a094a82
6935886
349520e
6d7db59
6ac6aa3
11fff48
3b68f71
6575365
c70e028
4db0b5a
a04352b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,199 @@ | ||||||
| --- | ||||||
| id: self-hosted-setup | ||||||
| title: Self-hosted setup for Serverless Workers | ||||||
| sidebar_label: Self-hosted setup | ||||||
| description: Configure a self-hosted Temporal Service to use Serverless Workers with AWS Lambda. | ||||||
| slug: /production-deployment/worker-deployments/serverless-workers/self-hosted-setup | ||||||
| toc_max_heading_level: 4 | ||||||
| keywords: | ||||||
| - serverless | ||||||
| - self-hosted | ||||||
| - lambda | ||||||
| - aws | ||||||
| - worker | ||||||
| - deployment | ||||||
| tags: | ||||||
| - Workers | ||||||
| - Deploy | ||||||
| - Serverless | ||||||
| - Self-hosted | ||||||
| --- | ||||||
|
|
||||||
| This page covers the prerequisites for running [Serverless Workers](/serverless-workers) on a self-hosted Temporal | ||||||
| Service with AWS Lambda: | ||||||
|
|
||||||
| 1. Enable the Worker Controller Instance (WCI) on the server through dynamic configuration. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| 2. Provide the server with AWS credentials to assume IAM roles. | ||||||
| 3. Create an IAM role in your AWS account that grants Temporal permission to invoke Lambda functions. | ||||||
|
|
||||||
| Once setup is complete, follow the | ||||||
| [AWS Lambda deployment guide](/production-deployment/worker-deployments/serverless-workers/aws-lambda) to deploy your | ||||||
| Worker. | ||||||
|
|
||||||
| ## Enable the Worker Controller {#enable-worker-controller} | ||||||
|
|
||||||
| The Worker Controller Instance (WCI) is the server component that monitors Task Queues and invokes compute providers. It | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My concern with this is that users will confuse this with https://github.com/temporalio/temporal-worker-controller These are not the same thing right😅? At least per my understanding these are very different things. But we've already named the Kubernetes thing Worker Controller. Even though this is an internal component, it's a nice one to explain to users so they can understand how it works. It would be great if we can avoid a complete name collision There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, our naming in this department has been sub-optimal. Let's leave it as WCI - but make sure that it is always WCI and never worker controller?! |
||||||
| is disabled by default and must be enabled through [dynamic configuration](/references/dynamic-configuration). | ||||||
|
|
||||||
| Add the following keys to your dynamic config file: | ||||||
|
|
||||||
| ```yaml | ||||||
| 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: | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| ```yaml | ||||||
| workercontroller.enabled: | ||||||
| - value: true | ||||||
| constraints: | ||||||
| namespace: 'your-namespace' | ||||||
| ``` | ||||||
|
|
||||||
| The Temporal Service watches the dynamic config file for changes and applies updates without a restart. | ||||||
|
|
||||||
| ## Configure AWS credentials {#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:** Use [IAM Roles Anywhere](https://aws.amazon.com/iam/roles-anywhere/), or configure static AWS credentials in the server's environment (not recommended): | ||||||
|
|
||||||
| ``` | ||||||
| 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 {#create-invocation-role} | ||||||
|
|
||||||
| Temporal invokes Lambda functions by assuming an IAM role in your AWS account. This role needs `lambda:GetFunction` and `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](/files/temporal-self-hosted-serverless-worker-role.yaml). | ||||||
|
|
||||||
| | 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](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html) 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`. | | ||||||
|
|
||||||
| <details> | ||||||
| <summary>CloudFormation template</summary> | ||||||
|
|
||||||
| ```yaml | ||||||
| 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] | ||||||
| ``` | ||||||
|
|
||||||
| </details> | ||||||
|
|
||||||
| Deploy the template: | ||||||
|
|
||||||
| ```bash | ||||||
| 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: | ||||||
|
|
||||||
| ```bash | ||||||
| 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. | ||||||
|
|
||||||
| ## Next steps {#next-steps} | ||||||
|
|
||||||
| Follow the [AWS Lambda deployment guide](/production-deployment/worker-deployments/serverless-workers/aws-lambda) to | ||||||
| write your Worker code, deploy it to Lambda, and create a Worker Deployment Version with the IAM role from the previous | ||||||
| step. | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| 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] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.