diff --git a/README.md b/README.md index 161302d..2567adb 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Deploy and operate [Temporal](https://temporal.io/) Workers on serverless comput ## What the skill can do -- Build Serverless Workers with the Go, Python, TypeScript, or Java SDK. +- Build Serverless Workers with the Go, Python, TypeScript, Java, or .NET SDK. - Package and deploy Workers to AWS Lambda with the correct architecture, timeout, and shutdown settings. - Configure the separate AWS roles used by the Lambda function and by Temporal. - Register a Worker Deployment Version, validate its Task Queue binding, and set it current. @@ -26,7 +26,7 @@ Deploy and operate [Temporal](https://temporal.io/) Workers on serverless comput |---|---| | Compute | AWS Lambda — Public Preview | | Temporal | Temporal Cloud and self-hosted Temporal Service | -| SDKs | Go, Python, TypeScript, Java | +| SDKs | Go, Python, TypeScript, Java, .NET | | Other compute providers | Not currently supported | For Temporal Cloud, the Namespace must be hosted on AWS. The Namespace and Lambda function may be in different AWS regions. @@ -94,6 +94,10 @@ Add OpenTelemetry tracing to my Go Serverless Worker on Lambda. Package this Java Worker as a shaded jar and deploy it to Lambda. ``` +```text +Deploy this .NET Worker to Lambda with a runtime-specific publish. +``` + For a new deployment, the skill follows five stages: 1. **Scope** — confirm the SDK, compute provider, Namespace, region, and resource-naming prefix. @@ -124,6 +128,7 @@ Nothing is created before you approve the resource list. Troubleshooting and ins | [`references/aws-lambda/sdk-python.md`](references/aws-lambda/sdk-python.md) | Python package, API, handler, build, packaging, Lambda deployment values, tuned defaults, connection configuration, OpenTelemetry integration, and diagnostics | | [`references/aws-lambda/sdk-typescript.md`](references/aws-lambda/sdk-typescript.md) | TypeScript package, API, handler, Workflow pre-bundling, build, packaging, Lambda deployment values, tuned defaults, connection configuration, and OpenTelemetry integration | | [`references/aws-lambda/sdk-java.md`](references/aws-lambda/sdk-java.md) | Java artifact, API, handler, callbacks, build, packaging, Lambda deployment values, tuned defaults, connection configuration, OpenTelemetry integration, logging, and diagnostics | +| [`references/aws-lambda/sdk-dotnet.md`](references/aws-lambda/sdk-dotnet.md) | .NET package, API, handler, build, RID-specific publish, Lambda deployment values, tuned defaults, connection configuration, OpenTelemetry integration, logging, and diagnostics | | [`references/aws-lambda/setup.md`](references/aws-lambda/setup.md) | Shared AWS and Temporal deployment lifecycle, verification, and teardown workflow | | [`references/aws-lambda/iam.md`](references/aws-lambda/iam.md) | Operator permissions, Lambda execution role, and Temporal invocation role | | [`references/aws-lambda/diagnostics.md`](references/aws-lambda/diagnostics.md) | Diagnostic decision tree and WCI inspection | diff --git a/SKILL.md b/SKILL.md index 3a1462d..9c825a5 100644 --- a/SKILL.md +++ b/SKILL.md @@ -27,6 +27,7 @@ Every supported provider's directory carries the same shared layout — `setup.m | Python | `references/aws-lambda/sdk-python.md` | | TypeScript | `references/aws-lambda/sdk-typescript.md` | | Java | `references/aws-lambda/sdk-java.md` | +| .NET | `references/aws-lambda/sdk-dotnet.md` | **Public Preview is not GA.** The APIs are still evolving and may change: pin SDK and CLI versions for anything long-lived, and read the installed package's actual API surface rather than writing from memory. @@ -90,7 +91,7 @@ Where the harness has a todo list, use it *in addition to* the printed checklist **A step is complete when its verification passed — not when its command exited zero.** Several commands in this workflow exit clean having done nothing: the traffic-shifting and key-revocation commands no-op when their confirmation prompt goes unanswered, and providers return from create and update calls while the resource is still settling. Check an item off against state you read back, not against an exit code. When a step's verification fails, say which step you are on and what it is blocked on rather than moving down the list. -1. **Scope the task.** Identify the SDK language (Go, Python, TypeScript, or Java), the deployment target (Temporal Cloud or self-hosted — self-hosted has its own server prerequisites), the compute provider, and whether this is a new setup, a configuration change, or troubleshooting. Confirm the deployment target is compatible with the chosen provider — see "A Namespace on the target cloud provider is required" under Provider-neutral principles. Ensure a Temporal client/CLI is available and authenticated to the target. Each changes the specifics. → `references/concepts.md` for what the user is building; `references//setup.md` for the compatibility and client-setup details. +1. **Scope the task.** Identify the SDK language (Go, Python, TypeScript, Java, or .NET), the deployment target (Temporal Cloud or self-hosted — self-hosted has its own server prerequisites), the compute provider, and whether this is a new setup, a configuration change, or troubleshooting. Confirm the deployment target is compatible with the chosen provider — see "A Namespace on the target cloud provider is required" under Provider-neutral principles. Ensure a Temporal client/CLI is available and authenticated to the target. Each changes the specifics. → `references/concepts.md` for what the user is building; `references//setup.md` for the compatibility and client-setup details. **Put the compute provider in that batch of questions as a confirmable default, not a free choice.** Pre-select the supported provider from the table above and carry its support status in the option's description. The user confirms rather than chooses, so it costs no extra turn, but the provider is never something they were assumed into. Skip the question only when the request already names a provider. Do not restate any of this in a paragraph before the questions; the option description is where it belongs. @@ -229,6 +230,7 @@ Most questions need 2–3 reference files. | Python SDK-specific options and tuned defaults, package and import, API inspection, handler, build and packaging, runtime and deployment values, versioning-behavior configuration, connection config, OpenTelemetry integration, diagnostic signatures. | `references//sdk-python.md` | | TypeScript SDK-specific options and tuned defaults, package and import, API inspection, handler, build and packaging, runtime and deployment values, versioning-behavior configuration, connection config, pre-bundled Workflow code, OpenTelemetry integration. | `references//sdk-typescript.md` | | Java SDK-specific options and tuned defaults, artifact and imports, API inspection, handler, build and packaging, runtime and deployment values, versioning-behavior configuration, connection config, OpenTelemetry integration, logging and diagnostic signatures. | `references//sdk-java.md` | +| .NET SDK-specific options and tuned defaults, package and imports, API inspection, handler, RID-specific publish and packaging, runtime and deployment values, versioning-behavior configuration, connection config and `SSL_CERT_FILE`, OpenTelemetry integration, logging and diagnostic signatures. | `references//sdk-dotnet.md` | | Add OpenTelemetry observability, Collector config, X-Ray, and IAM. | `references//observability.md` + the selected `references//sdk-.md` | | Worker not invoked, Workflows not progressing, inspect the WCI. | `references//diagnostics.md` + the selected `references//sdk-.md` (+ `references/concepts.md`) | | Long-running Activities and timeout relationships. Isolate Activities from resource exhaustion. | `references/concepts.md` (+ the selected `references//sdk-.md`) | diff --git a/references/aws-lambda/diagnostics.md b/references/aws-lambda/diagnostics.md index b1d2750..2d4ac73 100644 --- a/references/aws-lambda/diagnostics.md +++ b/references/aws-lambda/diagnostics.md @@ -125,9 +125,9 @@ Common errors include: ### Language-specific signatures -**No application logs at all, but the Worker clearly ran.** Two different SDKs produce this same misleading silence by unrelated mechanisms, and in both cases the Worker is healthy — only the logging is broken. Diagnose invocation health from Lambda's own runtime markers (`INIT_START`/`START`/`END`/`REPORT`) and CloudWatch metrics instead, then fix the binding. +**No application logs at all, but the Worker clearly ran.** SDK-specific logging configuration can suppress application logs even when the Worker is healthy. Diagnose invocation health from Lambda's runtime markers (`INIT_START`/`START`/`END`/`REPORT`) and CloudWatch metrics. -For SDK-specific diagnostics, see the selected SDK reference. +For the exact logging cause and fix, see the selected SDK reference. ### Check for Lambda timeout diff --git a/references/aws-lambda/observability.md b/references/aws-lambda/observability.md index 6d8537f..0492608 100644 --- a/references/aws-lambda/observability.md +++ b/references/aws-lambda/observability.md @@ -12,6 +12,7 @@ Load the selected SDK reference's **Observability** section: | Python | `sdk-python.md` → Observability | | TypeScript | `sdk-typescript.md` → Observability | | Java | `sdk-java.md` → Observability | +| .NET | `sdk-dotnet.md` → Observability | The remaining steps in this file are shared across SDKs. diff --git a/references/aws-lambda/sdk-dotnet.md b/references/aws-lambda/sdk-dotnet.md new file mode 100644 index 0000000..4e385dc --- /dev/null +++ b/references/aws-lambda/sdk-dotnet.md @@ -0,0 +1,267 @@ +# .NET SDK on AWS Lambda + +Sources: [`Temporalio.Extensions.Aws.Lambda` 1.18.0](https://www.nuget.org/packages/Temporalio.Extensions.Aws.Lambda/1.18.0), [Lambda extension source](https://github.com/temporalio/sdk-dotnet/tree/90c4ef35e260ed5bf553de7ef458053da28e3912/src/Temporalio.Extensions.Aws.Lambda), [OpenTelemetry extension source](https://github.com/temporalio/sdk-dotnet/tree/90c4ef35e260ed5bf553de7ef458053da28e3912/src/Temporalio.Extensions.Aws.Lambda.OpenTelemetry), and the [maintained Lambda Worker sample](https://github.com/temporalio/samples-dotnet/tree/6aba4fb9ea08177e303352ec9a4c61e303cefb0e/src/LambdaWorker). + +Use this reference for .NET SDK-specific package, entry-point, Worker configuration, tuned defaults, observability, and diagnostic details. For shared AWS Lambda deployment, observability infrastructure, and diagnostic flow, see `setup.md`, `observability.md`, and `diagnostics.md`. + +## Package + +Import: `using Temporalio.Extensions.Aws.Lambda;` plus `Temporalio.Common` (for `WorkerDeploymentVersion`) and `Amazon.Lambda.Core` (for `ILambdaContext`). + +Install: `dotnet add package Temporalio.Extensions.Aws.Lambda` — a **separate NuGet package** from `Temporalio`, published in **lockstep** with it (both 1.18.0). Published versions: 1.17.0 and 1.18.0. The package targets `netstandard2.0` and declares `Temporalio` 1.18.0 and `Amazon.Lambda.Core` 3.1.0. + +OpenTelemetry lives in a **second package**, `Temporalio.Extensions.Aws.Lambda.OpenTelemetry` (also 1.18.0). → Observability below. + +- .NET: [.NET Lambda Worker sample](https://github.com/temporalio/samples-dotnet/tree/6aba4fb9ea08177e303352ec9a4c61e303cefb0e/src/LambdaWorker) — `Worker/`, `Starter/`, and `Deploy/` (deploy, IAM-role, execution-role, and telemetry scripts plus a CloudFormation template), with a test project under `tests/LambdaWorker`. + +List the real public API of the resolved package before generating code — the `.nupkg` is a zip and ships full XML documentation: + +```bash +curl -sO https://api.nuget.org/v3-flatcontainer/temporalio.extensions.aws.lambda//temporalio.extensions.aws.lambda..nupkg +unzip -p temporalio.extensions.aws.lambda..nupkg \ + lib/netstandard2.0/Temporalio.Extensions.Aws.Lambda.xml +# the .nuspec lists the exact dependency versions: +unzip -p ...nupkg Temporalio.Extensions.Aws.Lambda.nuspec | grep dependency +``` + +If sources disagree, use the installed artifact's public API, followed by the maintained sample and the prose documentation. + +## Entry point + +**`TemporalLambdaWorker.CreateHandler(version, configure)`** — returns a `Func` that your handler method delegates to. Overloads take either a synchronous `Action` or an asynchronous `Func` for setup that must await. A further overload taking `TemporalLambdaWorkerHandlerOptions` is an internal test seam and is not for production use. + +## Configure callback + +Receives a `TemporalLambdaWorkerOptions` with public `ClientOptions`, `WorkerOptions`, `ShutdownDeadlineBuffer`, and `AddShutdownHook(Func)` members. The Task Queue and registrations go through `WorkerOptions` — an ordinary `TemporalWorkerOptions`, so `TaskQueue`, `AddWorkflow()` and `AddActivity(...)` behave exactly as they do for a long-lived Worker. The callback runs **per invocation**. + +## Versioning behavior + +Per-Workflow via the `[Workflow]` attribute: + +```csharp +[Workflow(VersioningBehavior = VersioningBehavior.Pinned)] +public class MyWorkflow +{ + [WorkflowRun] + public async Task RunAsync(string name) => /* ... */; +} +``` + +Or a Worker-level default through `DefaultVersioningBehavior` in `DeploymentOptions`. + +**The .NET Worker-level default is `AutoUpgrade`.** Prefer setting the behavior explicitly per Workflow. + +## Handler example + +A plain class exposes an async method that delegates to the handler returned by `TemporalLambdaWorker.CreateHandler`. + +```csharp +namespace MyCompany.Temporal.Worker; + +using Amazon.Lambda.Core; +using Temporalio.Common; +using Temporalio.Extensions.Aws.Lambda; + +public class LambdaFunction +{ + private static readonly Func WorkerHandler = + TemporalLambdaWorker.CreateHandler( + new WorkerDeploymentVersion("my-app", "build-1"), + config => + { + config.WorkerOptions.TaskQueue = "my-task-queue"; + config.WorkerOptions + .AddWorkflow() + .AddActivity(MyActivities.MyActivity); + }); + + public Task HandlerAsync(Stream input, ILambdaContext context) => + WorkerHandler(input, context); +} +``` + +Registrations go through `config.WorkerOptions`, an ordinary `TemporalWorkerOptions` — the same API a long-lived Worker uses. Use the `Func` overload when setup must await. + +## Lambda-tuned defaults + + + +| Setting | Lambda default | +|---|---| +| `MaxConcurrentActivities` | 2 | +| `MaxConcurrentWorkflowTasks` | 10 | +| `MaxConcurrentLocalActivities` | 2 | +| `MaxConcurrentNexusTasks` | 5 | +| `MaxConcurrentWorkflowTaskPolls` | 2 | +| `MaxConcurrentActivityTaskPolls` | 1 | +| `MaxConcurrentNexusTaskPolls` | 1 | +| `MaxCachedWorkflows` | 30 | +| `GracefulShutdownTimeout` | 5 seconds | +| `ShutdownDeadlineBuffer` | 7 seconds | +| `DisableEagerActivityExecution` | Always `true`, cannot be overridden | + +## Logging — set a LoggerFactory or Workflow logs vanish + +`TemporalWorkerOptions.LoggerFactory` is unset by default and "defaults to the client logger factory", which is also unset — so `Workflow.Logger` output is discarded. Activity `Console.WriteLine` still reaches CloudWatch, which makes the gap look selective rather than total. + +Install the console logging provider: + +```bash +dotnet add package Microsoft.Extensions.Logging.Console +``` + +```csharp +using Microsoft.Extensions.Logging; + +config.WorkerOptions.LoggerFactory = + LoggerFactory.Create(b => b.AddSimpleConsole().SetMinimumLevel(LogLevel.Information)); +``` + +## Connection configuration + +Loaded automatically from environment variables and an optional TOML config file, in this resolution order: + +1. `TEMPORAL_CONFIG_FILE` environment variable, if set. +2. `temporal.toml` in the Lambda task root (typically `/var/task`). +3. `temporal.toml` in the current working directory. + +When using `temporal.toml`, copy it into the publish directory before zipping so it lands in the task root. Keep the API key in `TEMPORAL_API_KEY` rather than in the file; supplying an API key enables TLS automatically. + +**TLS caveat specific to .NET — set `SSL_CERT_FILE` or the first invocation fails.** AWS's .NET 8 Lambda images force-override `SSL_CERT_FILE`, which prevents the SDK's Rust core from loading system root CAs. Set it explicitly on the function: + +``` +SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt # or /etc/ssl/certs/ca-certificates.crt +``` + +**This is server-certificate verification, not client credentials.** The API key is unaffected and is not the problem — an API key auto-enables TLS, and TLS requires verifying Temporal Cloud's certificate chain against root CAs. The connection fails before authentication is ever attempted. See `diagnostics.md` for the corresponding failure signature and recovery steps. + +## Build and package + +### Native dependency — publish must be RID-specific + +The .NET SDK wraps a **native Rust core** (`libtemporalio_sdk_core_c_bridge.so`). For Lambda, publish for an explicit runtime identifier matching the function's architecture and confirm the native library is present before creating the zip: + +| `--runtime` | `--architectures` | +|---|---| +| `linux-x64` | `x86_64` | +| `linux-arm64` | `arm64` | + +Publish for an explicit Linux runtime identifier, then zip the publish output. + +```bash +dotnet publish path/to/Worker.csproj \ + --configuration Release \ + --runtime linux-x64 \ + --self-contained false \ + --output ./publish + +# Guard: the SDK's native Rust bridge must be in the output, or the function +# fails at FIRST INVOCATION, not at build time. +[[ -f ./publish/libtemporalio_sdk_core_c_bridge.so ]] || { + echo "Publish output is missing the linux-x64 Temporal native bridge." >&2; exit 1; } + +# Copy each optional configuration file that this deployment uses so it lands +# in the Lambda task root: +if [[ -f temporal.toml ]]; then + cp temporal.toml ./publish/ +fi +if [[ -f otel-collector-config.yaml ]]; then + cp otel-collector-config.yaml ./publish/ +fi + +cd ./publish && zip -r ../function.zip . && cd .. +``` + +Keep the native-library check before zipping. `--self-contained false` is correct because the `dotnet8` managed runtime supplies the framework. + +## Deploy the Lambda function + +```bash +aws lambda create-function \ + --function-name my-temporal-worker \ + --runtime dotnet8 \ + --architectures x86_64 \ + --handler 'MyAssembly::MyCompany.Temporal.Worker.LambdaFunction::HandlerAsync' \ + --role \ + --zip-file fileb://function.zip \ + --timeout 600 \ + --memory-size 256 \ + --environment file:///tmp/lambda-env.json +``` + +**The environment block for .NET must include `SSL_CERT_FILE`**, in addition to the usual `TEMPORAL_*` variables: + +```json +{"Variables":{ + "TEMPORAL_ADDRESS":"...", "TEMPORAL_NAMESPACE":"...", "TEMPORAL_API_KEY":"...", + "SSL_CERT_FILE":"/etc/pki/tls/certs/ca-bundle.crt"}} +``` + +Without it the **first invocation fails**, the Task Queue is never bound, and the Worker is never invoked again. AWS's .NET 8 Lambda images force-override `SSL_CERT_FILE`, which stops the SDK's Rust core from loading system root CAs. `/etc/ssl/certs/ca-certificates.crt` also works; try the other if one fails. This is server-certificate verification, unrelated to your API key. → `diagnostics.md`. + +- `--runtime`: `dotnet8` for a `net8.0` build. +- `--handler`: **`ASSEMBLY::NAMESPACE.TYPE::METHOD` — three colon-separated parts.** Getting this wrong presents as a handler-not-found error at first invocation. +- `--timeout 600` / `--memory-size 256` are example values. The timeout must accommodate Worker startup and registration, Task and Activity processing, and graceful shutdown. Memory contributes directly to Lambda cost. → `setup.md` for how to choose both values. +- `--architectures` must match the publish RID (`linux-x64` → `x86_64`, `linux-arm64` → `arm64`). + +## Observability + +### OTel package + +A **second NuGet package**, separate from the Lambda extension itself: + +```bash +dotnet add package Temporalio.Extensions.Aws.Lambda.OpenTelemetry +``` + +Published in lockstep with `Temporalio` and `Temporalio.Extensions.Aws.Lambda` (all 1.18.0). + +### OTel functions + +The package contributes an extension method on the options object, applied inside the configure callback: + +```csharp +using Temporalio.Extensions.Aws.Lambda.OpenTelemetry; + +TemporalLambdaWorker.CreateHandler( + new WorkerDeploymentVersion("my-app", "build-1"), + config => + { + config.ApplyOpenTelemetryDefaults(); + config.WorkerOptions.TaskQueue = "my-task-queue"; + config.WorkerOptions.AddWorkflow().AddActivity(MyActivities.MyActivity); + }); +``` + +`ApplyOpenTelemetryDefaults()` configures metrics and tracing against the ADOT layer's collector. Telemetry must be exported before the invocation ends — keep any metrics export interval shorter than the Lambda timeout. + +### ADOT layer setup + +Attach an **ADOT Collector layer** for the target region and architecture. No language-specific auto-instrumentation layer is needed because the OpenTelemetry SDK arrives as an ordinary package dependency. Supply the collector layer ARN for the target region. + +Set `OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/otel-collector-config.yaml` and copy `otel-collector-config.yaml` into the publish directory before zipping so it lands in the task root. + +For the shared Collector configuration, X-Ray enablement, and execution-role permissions, see `observability.md`. + +## Diagnostic signatures + +| SDK | Cause | Fix | +|---|---|---| +| .NET | `TemporalWorkerOptions.LoggerFactory` is unset and "defaults to the client logger factory", which is also unset — so `Workflow.Logger` output is discarded. Activity `Console.WriteLine` still reaches CloudWatch, which makes the gap look selective rather than total | set `config.WorkerOptions.LoggerFactory` (e.g. `LoggerFactory.Create(b => b.AddSimpleConsole().SetMinimumLevel(LogLevel.Information))`) | + +**.NET — `DllNotFoundException` / missing `libtemporalio_sdk_core_c_bridge.so` at first invocation.** Republish with an explicit runtime identifier matching the function's architecture (`--runtime linux-x64` for `x86_64`, `linux-arm64` for `arm64`) and check the native library is in the publish output before zipping. → Build and package above. + +**.NET — `NativeCertsNotFound` at first invocation, despite a correct address, Namespace, and API key.** + +``` +System.InvalidOperationException: Connection failed: Server connection error: + tonic::transport::Error(Transport, NativeCertsNotFound) + at Temporalio.Bridge.Client.ConnectAsync(...) + at Temporalio.Client.TemporalConnection.ConnectAsync(...) +``` + +*Cause:* AWS's .NET 8 Lambda images force-override `SSL_CERT_FILE`, so the SDK's Rust core cannot load system root CAs. *Fix:* set `SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt` (or `/etc/ssl/certs/ca-certificates.crt`) on the function, then recover the binding as described under "Failed first invocation" in `diagnostics.md` — the failed validation invocation means no Task Queue was bound and Temporal will not retry on its own. + +"Certs" here means the operating system's root CA store, not client credentials. An API key auto-enables TLS, and TLS requires verifying the server's certificate chain. The connection fails before authentication is attempted, so changing the API key, Namespace, invocation role, or External ID will not fix this error. + +**.NET — handler not found at first invocation.** The handler string has **three** colon-separated parts, `ASSEMBLY::NAMESPACE.TYPE::METHOD`. Compare against the assembly name (not the project name, if they differ) and the fully-qualified type. diff --git a/references/aws-lambda/sdk-go.md b/references/aws-lambda/sdk-go.md index 8a2216e..0b57603 100644 --- a/references/aws-lambda/sdk-go.md +++ b/references/aws-lambda/sdk-go.md @@ -19,7 +19,7 @@ go doc go.temporal.io/sdk/contrib/aws/lambdaworker go doc go.temporal.io/sdk/contrib/aws/lambdaworker.Options ``` -**A useful ordering when sources disagree:** the installed artifact first, the SDK's maintained samples second (they are built in CI, so they cannot reference a method that does not exist), the prose docs last. Entry-point names are not consistent across SDKs — Java's is `define`, not "run"-shaped like the others — so check rather than pattern-match from another language. +**Ordering when sources disagree:** the installed artifact first, the SDK's maintained samples second (they are built in CI, so they cannot reference a method that does not exist), the prose docs last. Entry-point names are not consistent across SDKs, so check rather than pattern-match from another language. ## Entry point diff --git a/references/aws-lambda/sdk-python.md b/references/aws-lambda/sdk-python.md index 583b1d2..5d46172 100644 --- a/references/aws-lambda/sdk-python.md +++ b/references/aws-lambda/sdk-python.md @@ -18,7 +18,7 @@ Read the installed API before generating code: python -c "import temporalio.contrib.aws.lambda_worker as m; help(m.LambdaWorkerConfig)" ``` -**A useful ordering when sources disagree:** the installed artifact first, the SDK's maintained samples second (they are built in CI, so they cannot reference a method that does not exist), the prose docs last. Entry-point names are not consistent across SDKs — Java's is `define`, not "run"-shaped like the others — so check rather than pattern-match from another language. +**Ordering when sources disagree:** the installed artifact first, the SDK's maintained samples second (they are built in CI, so they cannot reference a method that does not exist), the prose docs last. Entry-point names are not consistent across SDKs, so check rather than pattern-match from another language. **Fastest path:** start from the language sample linked above — it has a working Worker, Workflow, and Activity already wired together. The handler example below imports the Workflow and Activity from separate modules (`my_workflows`, `my_activities`). When writing from scratch, create those modules with at least one registered Workflow (declaring a versioning behavior) and one Activity, and name the entry-point file to match the `--handler` you deploy (for example, `lambda_function.py` → `--handler lambda_function.lambda_handler`). diff --git a/references/aws-lambda/sdk-typescript.md b/references/aws-lambda/sdk-typescript.md index 603b1bb..a89a51e 100644 --- a/references/aws-lambda/sdk-typescript.md +++ b/references/aws-lambda/sdk-typescript.md @@ -18,7 +18,7 @@ Check the installed version, then read its type declarations: npm ls @temporalio/lambda-worker ``` -**A useful ordering when sources disagree:** the installed artifact first, the SDK's maintained samples second (they are built in CI, so they cannot reference a method that does not exist), the prose docs last. Entry-point names are not consistent across SDKs — Java's is `define`, not "run"-shaped like the others — so check rather than pattern-match from another language. +**Ordering when sources disagree:** the installed artifact first, the SDK's maintained samples second (they are built in CI, so they cannot reference a method that does not exist), the prose docs last. Entry-point names are not consistent across SDKs, so check rather than pattern-match from another language. ## Entry point diff --git a/references/aws-lambda/setup.md b/references/aws-lambda/setup.md index 34db17d..30083bd 100644 --- a/references/aws-lambda/setup.md +++ b/references/aws-lambda/setup.md @@ -16,7 +16,7 @@ This is the end-to-end golden path: connect, write the Worker, package and deplo - Every Workflow must declare a versioning behavior, or the Worker must set a default versioning behavior. - An AWS account with permissions to create and invoke Lambda functions and create IAM roles. For the exact operator actions and a preflight check, see `iam.md`. - The AWS-specific steps require the `aws` CLI installed and configured with your AWS credentials. You may also use the AWS Console or the AWS SDKs. -- The Go SDK, Python SDK, TypeScript SDK, or Java SDK, depending on your language. +- The Go SDK, Python SDK, TypeScript SDK, Java SDK, or .NET SDK, depending on your language. - The `temporal` CLI, authenticated to the target Temporal Service — Steps 4–6 and the CLI troubleshooting paths use it. See "Temporal CLI and Cloud connection" below. The selected SDK reference links its maintained sample project. @@ -123,6 +123,7 @@ Load the reference for the selected SDK alongside this shared deployment guide: | Python | `sdk-python.md` | | TypeScript | `sdk-typescript.md` | | Java | `sdk-java.md` | +| .NET | `sdk-dotnet.md` | Complete the selected SDK reference before continuing.