Skip to content

Commit c8f9b46

Browse files
committed
Update for released TS
1 parent 1e76089 commit c8f9b46

12 files changed

Lines changed: 555 additions & 518 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,4 @@ package-lock.json
114114

115115
**/client.key
116116
**/client.pem
117+
worker-versioning/.claude/settings.local.json

.scripts/list-of-samples.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
"hello-world-mtls",
2626
"interceptors-opentelemetry",
2727
"lambda-worker",
28-
"message-passing",
2928
"monorepo-folders",
3029
"mutex",
3130
"nestjs-exchange-rates",
@@ -56,4 +55,4 @@
5655
"message-passing/safe-message-handlers",
5756
"polling/infrequent"
5857
]
59-
}
58+
}

lambda-worker/README.md

Lines changed: 45 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ which `@temporalio/lambda-worker` automatically detects and uses to produce stru
1313
logs that CloudWatch Logs can parse natively. If you don't need structured logging, you can
1414
remove the dependency and the SDK will fall back to its default human-readable logger.
1515

16-
> **Note:** `@temporalio/lambda-worker` is not yet published. The `package.json` currently
17-
> references it via a local `file:` path to `../../sdk-node/packages/lambda-worker`.
18-
> TODO: Replace with a versioned dependency (e.g. `^1.15.0`) once the package is published.
19-
2016
## Prerequisites
2117

2218
- A [Temporal Cloud](https://temporal.io/cloud) namespace (or a self-hosted Temporal
@@ -29,29 +25,46 @@ remove the dependency and the SDK will fall back to its default human-readable l
2925

3026
## Files
3127

32-
| File | Description |
33-
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
28+
| File | Description |
29+
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
3430
| `src/index.ts` | Lambda entry point — configures the worker, registers Workflows/Activities, enables OTel, and exports the handler |
35-
| `src/workflows.ts` | Sample Workflow that executes a greeting Activity |
36-
| `src/activities.ts` | Sample Activity that returns a greeting string |
37-
| `src/client.ts` | Helper program to start a Workflow execution from a local machine |
38-
| `src/scripts/build-workflow-bundle.ts` | Pre-bundles Workflow code with OTel interceptor modules for Lambda cold start performance |
39-
| `temporal.toml` | Temporal client connection configuration (update with your namespace) |
40-
| `otel-collector-config.yaml` | OpenTelemetry Collector configuration for ADOT (routes metrics to CloudWatch, traces to X-Ray) |
41-
| `deploy-lambda.sh` | Packages and deploys the Lambda function |
42-
| `mk-iam-role.sh` | Creates the IAM role that allows Temporal Cloud to invoke the Lambda |
43-
| `iam-role-for-temporal-lambda-invoke-test.yaml` | CloudFormation template for the IAM role |
44-
| `extra-setup-steps` | Additional IAM and Lambda configuration for OpenTelemetry support |
31+
| `src/workflows.ts` | Sample Workflow that executes a greeting Activity |
32+
| `src/activities.ts` | Sample Activity that returns a greeting string |
33+
| `src/client.ts` | Helper program to start a Workflow execution from a local machine |
34+
| `src/scripts/build-workflow-bundle.ts` | Pre-bundles Workflow code with OTel interceptor modules for Lambda cold start performance |
35+
| `temporal.toml` | Temporal client connection configuration (update with your namespace) |
36+
| `otel-collector-config.yaml` | OpenTelemetry Collector configuration for ADOT (routes metrics to CloudWatch, traces to X-Ray) |
37+
| `deploy-lambda.sh` | Packages and deploys the Lambda function |
38+
| `mk-iam-role.sh` | Creates the IAM role that allows Temporal Cloud to invoke the Lambda |
39+
| `iam-role-for-temporal-lambda-invoke-test.yaml` | CloudFormation template for the IAM role |
40+
| `extra-setup-steps` | Additional IAM and Lambda configuration for OpenTelemetry support |
4541

4642
## Setup
4743

48-
### 1. Configure Temporal connection
44+
The instructions here are a slimmed down version of the more complete getting started guide which
45+
you can find [here](https://docs.temporal.io/production-deployment/worker-deployments/serverless-workers/aws-lambda).
46+
47+
### 1. Create a lambda function for your TypeScript worker
48+
49+
Use either the AWS web UI or CLI to create a Node.js runtime Lambda function. Ex:
50+
51+
```bash
52+
aws lambda create-function \
53+
--function-name my-temporal-worker \
54+
--runtime nodejs22.x \
55+
--handler lib/index.handler \
56+
--role arn:aws:iam::<YOUR_ACCOUNT_ID>:role/my-temporal-worker-execution \
57+
--timeout 600 \
58+
--memory-size 256
59+
```
60+
61+
### 2. Configure Temporal connection
4962

5063
Edit `temporal.toml` with your Temporal Cloud namespace address and credentials. In production,
5164
we'd recommend reading your credentials from a secret store, but to keep this example simple
5265
the toml file defaults to reading them from keys bundled along with the Lambda code.
5366

54-
### 2. Create the IAM role
67+
### 3. Create the IAM role
5568

5669
This creates the IAM role that Temporal Cloud assumes to invoke your Lambda function:
5770

@@ -62,57 +75,24 @@ This creates the IAM role that Temporal Cloud assumes to invoke your Lambda func
6275
The External ID is provided by Temporal Cloud in your namespace's serverless worker
6376
configuration.
6477

65-
### 3. (Optional) Enable OpenTelemetry
66-
67-
The sample calls `applyDefaults(config)` in the handler, which registers Temporal SDK
68-
interceptors for tracing Workflow, Activity, and Nexus calls, and configures the Core SDK
69-
to export metrics via OTLP. To complete the setup, attach two ADOT Lambda layers:
70-
71-
1. **ADOT JavaScript layer** — auto-instruments the handler and exports Node.js-side
72-
traces to X-Ray. See [this page](https://aws-otel.github.io/docs/getting-started/lambda/lambda-js)
73-
for the layer ARN for your region.
74-
2. **ADOT Collector layer** (`aws-otel-collector-amd64`) — runs the OTel Collector as a
75-
Lambda extension, receiving Temporal Core SDK metrics via OTLP and forwarding them to
76-
CloudWatch/X-Ray. See [this page](https://aws-otel.github.io/docs/getting-started/lambda)
77-
for the layer ARN.
78-
79-
Update `otel-collector-config.yaml` with your function name and region, then set the
80-
following environment variables on your Lambda:
81-
82-
```
83-
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument
84-
OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/otel-collector-config.yaml
85-
```
86-
87-
`AWS_LAMBDA_EXEC_WRAPPER` enables the JS layer's auto-instrumentation.
88-
`OPENTELEMETRY_COLLECTOR_CONFIG_URI` points the collector at the custom config that
89-
routes metrics to CloudWatch EMF and traces to X-Ray.
78+
### 4. (Optional) Enable OpenTelemetry
9079

91-
Enable X-Ray active tracing on the Lambda function (required for traces to appear):
92-
93-
```bash
94-
aws lambda update-function-configuration --function-name <function-name> \
95-
--tracing-config Mode=Active
96-
```
80+
If you want traces, metrics, and logs, you'll have to attach the ADOT layer to your Lambda function.
81+
You will need to add the appropriate layer for your runtime and region. See [this page
82+
](https://aws-otel.github.io/docs/getting-started/lambda#getting-started-with-aws-lambda-layers)
83+
for more info. See also the [Temporal docs on adding observability
84+
](https://docs.temporal.io/develop/typescript/workers/serverless-workers/aws-lambda#add-observability)
85+
for additional TypeScript-specific configuration.
9786

9887
Then run the extra setup to grant the Lambda role the necessary permissions:
9988

10089
```bash
10190
./extra-setup-steps <role-name> <function-name> <region> <account-id>
10291
```
10392

104-
### 4. Deploy the Lambda function
93+
Update `otel-collector-config.yaml` with your function name and region as needed.
10594

106-
Create a Lambda function in AWS with:
107-
108-
- **Runtime**: Node.js >=20
109-
- **Handler**: `index.handler` (the default)
110-
- **Architecture**: x86_64
111-
112-
It's likely you will need to increase the default memory limit in AWS for your lambda. A minimum of
113-
256MB is recommended.
114-
115-
Then deploy:
95+
### 5. Deploy the Lambda function
11696

11797
```bash
11898
./deploy-lambda.sh <function-name>
@@ -121,7 +101,11 @@ Then deploy:
121101
This compiles TypeScript, pre-bundles Workflow code, packages everything with dependencies,
122102
and uploads to AWS Lambda.
123103

124-
### 5. Start a Workflow
104+
### 6. Configure Temporal to be able to invoke your lambda function
105+
106+
Refer to the docs [here](https://docs.temporal.io/production-deployment/worker-deployments/serverless-workers/aws-lambda#create-worker-deployment-version).
107+
108+
### 7. Start a Workflow
125109

126110
Use the starter program to execute a Workflow on the Lambda worker, using
127111
the same config file the Lambda uses for connecting to the server:

lambda-worker/deploy-lambda.sh

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ set -euo pipefail
33

44
FUNCTION_NAME="${1:?Usage: deploy-lambda.sh <function-name>}"
55
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6-
SDK_DIR="$SCRIPT_DIR/../../sdk-node"
76

87
# Build TypeScript
98
cd "$SCRIPT_DIR"
@@ -22,22 +21,15 @@ cp "$SCRIPT_DIR/lib/"*.js "$SCRIPT_DIR/package/"
2221
# Copy workflow bundle alongside the handler
2322
cp "$SCRIPT_DIR/workflow-bundle.js" "$SCRIPT_DIR/package/"
2423

25-
# Install production dependencies.
26-
# TODO: Once @temporalio/lambda-worker is published, remove the sed and the
27-
# manual copy below — npm install will handle everything.
24+
# Install production dependencies
2825
cd "$SCRIPT_DIR/package"
29-
sed '/@temporalio\/lambda-worker/d' "$SCRIPT_DIR/package.json" > package.json
26+
cp "$SCRIPT_DIR/package.json" package.json
3027
npm install --omit=dev --ignore-scripts
3128

3229
# Strip native binaries for platforms other than Lambda's (linux x86_64)
3330
find node_modules/@temporalio/core-bridge/releases -mindepth 1 -maxdepth 1 \
3431
! -name 'x86_64-unknown-linux-gnu' -exec rm -rf {} +
3532

36-
# Manually place the local lambda-worker package (not yet published)
37-
mkdir -p node_modules/@temporalio/lambda-worker
38-
cp "$SDK_DIR/packages/lambda-worker/package.json" node_modules/@temporalio/lambda-worker/
39-
cp -r "$SDK_DIR/packages/lambda-worker/lib" node_modules/@temporalio/lambda-worker/
40-
4133
# Copy config files and certs
4234
cp "$SCRIPT_DIR/temporal.toml" "$SCRIPT_DIR/otel-collector-config.yaml" \
4335
"$SCRIPT_DIR/client.pem" "$SCRIPT_DIR/client.key" "$SCRIPT_DIR/package/"

lambda-worker/iam-role-for-temporal-lambda-invoke-test.yaml

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CloudFormation template for creating an IAM role that Temporal Cloud can assume to invoke Lambda functions.
22
AWSTemplateFormatVersion: '2010-09-09'
3-
Description: Creates an IAM role that Temporal Cloud can assume to invoke Lambda functions for Serverless Workers.
3+
Description: Creates an IAM role that Temporal Cloud can assume to invoke multiple Lambda functions for Serverless Workers.
44

55
Parameters:
66
AssumeRoleExternalId:
@@ -10,11 +10,15 @@ Parameters:
1010
MinLength: 5
1111
MaxLength: 45
1212

13-
LambdaFunctionARN:
14-
Type: String
13+
LambdaFunctionARNs:
14+
Type: CommaDelimitedList
1515
Description: >-
16-
The ARN of the Lambda function to invoke
17-
(e.g., arn:aws:lambda:us-west-2:123456789012:function:worker-1)
16+
Comma-separated list of Lambda function ARNs to invoke (e.g.,
17+
arn:aws:lambda:us-west-2:123456789012:function:worker-1,arn:aws:lambda:us-west-2:123456789012:function:worker-2)
18+
19+
RoleName:
20+
Type: String
21+
Default: 'Temporal-Cloud-Serverless-Worker'
1822

1923
Metadata:
2024
AWS::CloudFormation::Interface:
@@ -26,26 +30,34 @@ Metadata:
2630
- Label:
2731
default: 'Lambda Configuration'
2832
Parameters:
29-
- LambdaFunctionARN
33+
- LambdaFunctionARNs
34+
- RoleName
3035
ParameterLabels:
3136
AssumeRoleExternalId:
3237
default: 'External ID (provided by Temporal Cloud)'
33-
LambdaFunctionARN:
34-
default: 'Lambda Function ARN'
38+
LambdaFunctionARNs:
39+
default: 'Lambda Function ARNs (comma-separated list)'
40+
RoleName:
41+
default: 'IAM Role Name'
3542

3643
Resources:
3744
TemporalCloudServerlessWorker:
3845
Type: AWS::IAM::Role
3946
Properties:
40-
RoleName: !Sub
41-
- 'Temporal-Cloud-Serverless-Worker-${LambdaName}'
42-
- LambdaName: !Select [6, !Split [':', !Ref LambdaFunctionARN]]
47+
RoleName: !Sub '${RoleName}-${AWS::StackName}'
4348
AssumeRolePolicyDocument:
4449
Version: '2012-10-17'
4550
Statement:
4651
- Effect: Allow
4752
Principal:
48-
AWS: [arn:aws:iam::031568301006:role/wci-lambda-invoke]
53+
AWS:
54+
[
55+
arn:aws:iam::902542641901:role/wci-lambda-invoke,
56+
arn:aws:iam::160190466495:role/wci-lambda-invoke,
57+
arn:aws:iam::819232936619:role/wci-lambda-invoke,
58+
arn:aws:iam::829909441867:role/wci-lambda-invoke,
59+
arn:aws:iam::354116250941:role/wci-lambda-invoke,
60+
]
4961
Action: sts:AssumeRole
5062
Condition:
5163
StringEquals:
@@ -65,9 +77,9 @@ Resources:
6577
Action:
6678
- lambda:InvokeFunction
6779
- lambda:GetFunction
68-
Resource: [!Ref LambdaFunctionARN]
80+
Resource: !Ref LambdaFunctionARNs
6981
Roles:
70-
- !Ref TemporalCloudServerlessWorker
82+
- !Sub '${RoleName}-${AWS::StackName}'
7183

7284
Outputs:
7385
RoleARN:
@@ -78,8 +90,8 @@ Outputs:
7890

7991
RoleName:
8092
Description: The name of the IAM role
81-
Value: !Ref TemporalCloudServerlessWorker
93+
Value: !Ref RoleName
8294

83-
LambdaFunctionARN:
84-
Description: The Lambda function ARN that can be invoked
85-
Value: !Ref LambdaFunctionARN
95+
LambdaFunctionARNs:
96+
Description: The Lambda function ARNs that can be invoked
97+
Value: !Join [', ', !Ref LambdaFunctionARNs]

lambda-worker/mk-iam-role.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ aws cloudformation create-stack \
1313
--template-body file://iam-role-for-temporal-lambda-invoke-test.yaml \
1414
--parameters \
1515
ParameterKey=AssumeRoleExternalId,ParameterValue="$EXTERNAL_ID" \
16-
ParameterKey=LambdaFunctionARN,ParameterValue="$LAMBDA_ARN" \
16+
ParameterKey=LambdaFunctionARNs,ParameterValue="$LAMBDA_ARN" \
1717
--capabilities CAPABILITY_NAMED_IAM

lambda-worker/otel-collector-config.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ exporters:
1515
# AWS EMF exporter for metrics
1616
# These are example configurations
1717
namespace: TemporalWorkerMetrics
18-
# log_group_name: /aws/lambda/<your-function-name>
19-
log_group_name: /aws/lambda/sdk-worker-typescript
18+
log_group_name: /aws/lambda/<your-function-name>
2019
region: us-west-2
2120
dimension_rollup_option: NoDimensionRollup
2221
resource_to_telemetry_conversion:
@@ -32,7 +31,7 @@ service:
3231
exporters: [awsemf]
3332
telemetry:
3433
logs:
35-
level: debug
34+
level: info
3635
metrics:
3736
address: localhost:8888
3837
# @@@SNIPEND

lambda-worker/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
"workflow": "ts-node src/client.ts"
1313
},
1414
"dependencies": {
15-
"@temporalio/activity": "^1.15.0",
16-
"@temporalio/client": "^1.15.0",
17-
"@temporalio/envconfig": "^1.15.0",
18-
"@temporalio/lambda-worker": "file:../../sdk-node/packages/lambda-worker",
19-
"@temporalio/worker": "^1.15.0",
20-
"@temporalio/workflow": "^1.15.0",
15+
"@temporalio/activity": "^1.17.0",
16+
"@temporalio/client": "^1.17.0",
17+
"@temporalio/envconfig": "^1.17.0",
18+
"@temporalio/lambda-worker": "^1.17.0",
19+
"@temporalio/worker": "^1.17.0",
20+
"@temporalio/workflow": "^1.17.0",
2121
"@aws-lambda-powertools/logger": "^2.0.0",
22-
"@temporalio/interceptors-opentelemetry": "^1.15.0",
22+
"@temporalio/interceptors-opentelemetry": "^1.17.0",
2323
"@opentelemetry/exporter-trace-otlp-grpc": "^0.52.0",
2424
"@opentelemetry/resources": "^1.25.1",
2525
"@opentelemetry/sdk-trace-base": "^1.25.1",

lambda-worker/sample.temporal.toml

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)