@odigos/aws-cdk 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +347 -12
- package/README.md +211 -11
- package/lib/agentcore-recipes.d.ts +84 -0
- package/lib/agentcore-recipes.js +243 -0
- package/lib/agentcore.d.ts +107 -0
- package/lib/agentcore.js +174 -0
- package/lib/fargate.js +1 -1
- package/lib/generated/agentcore.d.ts +26 -0
- package/lib/generated/agentcore.js +55 -0
- package/lib/generated/distributions.d.ts +1 -1
- package/lib/generated/distributions.js +2 -2
- package/lib/generated/fargate.d.ts +2 -2
- package/lib/generated/fargate.js +3 -3
- package/lib/generated/layers.d.ts +3 -3
- package/lib/generated/layers.js +292 -292
- package/lib/index.d.ts +3 -0
- package/lib/index.js +16 -2
- package/lib/instrumentation.js +2 -2
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +54 -0
- package/lib/types.js +59 -2
- package/package.json +1 -1
package/.jsii
CHANGED
|
@@ -3826,7 +3826,7 @@
|
|
|
3826
3826
|
},
|
|
3827
3827
|
"name": "@odigos/aws-cdk",
|
|
3828
3828
|
"readme": {
|
|
3829
|
-
"markdown": "# Odigos CDK constructs for AWS\n\nInstrument AWS Lambda functions and ECS Fargate services with OpenTelemetry, from your own CDK app.\n\n```bash\nnpm install @odigos/aws-cdk@0.0.19\n```\n\nThe npm package is published. The corrections in this checkout need a new package release before\ncustomers receive them through npm. To use this checkout locally, run `npm ci`, `npm run build`, and\n`npm run package` in `cdk/`, then install `dist/js/aws-cdk@0.0.0.jsii.tgz` in the consuming app.\n\nThe Python distribution is built by jsii but is not published on PyPI;\n`pip install odigos-aws-cdk` currently fails. Python examples below apply to a locally built wheel:\nrun `npm ci`, `npm run build`, then `npm run package` from `cdk/`, and install the wheel under `dist/python/`.\nFor customer installation until PyPI publishing is enabled, use the CloudFormation instructions instead.\n\n| | Lambda | ECS Fargate |\n|---|---|---|\n| Construct | `OdigosLambdaInstrumentation` | `OdigosFargateInstrumentation` |\n| Mechanism | a layer, plus an exec wrapper or loader variable | agents staged into a shared task volume by a run-to-completion container |\n| Languages | python, nodejs, java, ruby | java, python, nodejs, dotnet, php, ruby |\n| Where telemetry goes | a collector in the same Lambda sandbox, which forwards | your destination, from the application process |\n| Language detection | from the function's declared runtime | none — you state the language |\n\nLambda writes `odigos:iac=v1` and exact SDK/collector layer ARNs as function tags. Fargate writes an\n`ODIGOS_IAC` environment marker on each application container. Neither claims connector-managed ownership.\n\n# AWS Lambda\n\n```ts\nimport { OdigosLambdaInstrumentation } from '@odigos/aws-cdk';\n\nnew OdigosLambdaInstrumentation(this, 'Odigos', {\n destination: { endpoint: 'otlp.example.com:4317' },\n functions: [apiFn, workerFn],\n});\n```\n\n```python\nfrom odigos_aws_cdk import OdigosLambdaInstrumentation\n\nOdigosLambdaInstrumentation(self, \"Odigos\",\n destination={\"endpoint\": \"otlp.example.com:4317\"},\n functions=[api_fn, worker_fn],\n)\n```\n\nThat attaches the matching layer(s), sets `AWS_LAMBDA_EXEC_WRAPPER`, and writes the readable version-2\n`ODIGOS_LAMBDA_CONFIG` JSON. The layer launcher builds SDK settings and collector pipelines at startup;\ncustomer SDK environment variables remain saved unchanged in AWS. Public and in-account layers must be\nfrom `v0.0.19` or newer to read this configuration; a custom `layerVersion` must have the same bootstrap.\n\nApply instrumentation before creating published versions and aliases, then deploy the updated version and\npoint all traffic-serving aliases at it. Updating `$LATEST` alone does not instrument older versions.\n\n## How the telemetry actually leaves the function\n\nYour function's SDK **does not** export to your destination. It exports to an OpenTelemetry collector\nrunning inside the same Lambda sandbox, on localhost. The collector forwards to your destination *after*\nthe handler has already returned its response.\n\nThat indirection is the whole point. A slow or unreachable destination costs billed duration, not caller\nlatency — and the collector's `decouple` processor is what holds the sandbox open until the export queue\ndrains, so a low-traffic function does not lose its telemetry to the freeze.\n\nConsequently `OTEL_EXPORTER_OTLP_ENDPOINT` is deliberately never set. If you set it yourself you put the\nexport back on the invocation's critical path.\n\n## Endpoint grammar\n\n`endpoint` is OTLP/**gRPC** as bare `host:port` (conventionally 4317). `httpEndpoint` is OTLP/**HTTP** as a\nscheme-qualified URL (conventionally 4318). Exactly one. They select different collector exporters with\ndifferent endpoint grammars, so a scheme in `endpoint` — or its absence in `httpEndpoint` — throws at synth\nrather than producing a collector that starts and silently delivers nothing. A gRPC endpoint on port 4318\n(or an HTTP one on 4317) is the likeliest version of that mistake, and is reported as a synth warning.\n\n## Choosing a layer source\n\n```ts\nnew OdigosLambdaInstrumentation(this, 'Odigos', {\n destination: { endpoint: 'otlp.example.com:4317' },\n functions: [fn],\n layerSource: OdigosLayerSource.IN_ACCOUNT,\n});\n```\n\n| | `ODIGOS_PUBLIC` (default) | `IN_ACCOUNT` |\n|---|---|---|\n| What it synthesizes | a layer ARN | an `AWS::Serverless::Application` (nested stack) per language/arch |\n| Layer owner | the Odigos AWS account | **your** account, created by your stack |\n| Resolution | synth time, from a table baked into this package | deploy time, from the Serverless Application Repository |\n| Environment-agnostic stacks | not supported — needs a concrete region | works |\n| Deploy speed | unchanged | slower on first deploy |\n\nBoth install identical bytes. `IN_ACCOUNT` exists for organisations whose policy forbids attaching a\nLambda layer owned by another AWS account. It needs the deploying principal to be allowed\n`serverlessrepo:CreateCloudFormationTemplate` and `serverlessrepo:GetApplication`.\n\nIf you mirror the layer somewhere yourself, pass `layerVersion` and neither path is used.\n\n## Versioning\n\n**The package version is the artifact release version.** `@odigos/aws-cdk@0.0.19` resolves to layers built and\npublished by Odigos release `v0.0.19`, and pins the SAR application to semantic version `0.0.19` — which is\nimmutable, so it means the same bytes forever.\n\nNothing resolves at deploy time in the default path, so upgrading the layer is `npm update` and a\n`cdk diff` that shows the change. An instrumentation layer moving on its own, under a deployment that\nchanged nothing, is not a property you want.\n\n## Handler mode vs. web-server mode\n\n`OdigosInstrumentationMode.HANDLER` (the default) is for a normal Lambda handler. It sets\n`AWS_LAMBDA_EXEC_WRAPPER`.\n\n`OdigosInstrumentationMode.WEB_SERVER` is for a function running a web server behind the\n[AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter). The adapter owns the exec\nwrapper. This mode sets `AWS_LAMBDA_EXEC_WRAPPER=/opt/odigos-webserver`, records the previous wrapper in\n`ODIGOS_LAMBDA_CONFIG.webWrapper`, loads the agent through its language loader, then invokes the saved\nwrapper. Define the adapter's wrapper before applying instrumentation so it is preserved.\n\n```ts\nnew OdigosLambdaInstrumentation(this, 'Odigos', {\n destination: { endpoint: 'otlp.example.com:4317' },\n functions: [webFn],\n mode: OdigosInstrumentationMode.WEB_SERVER,\n // NODE_OPTIONS the function already needs — ours is appended, not substituted.\n existingLoaderValue: '--max-old-space-size=2048',\n});\n```\n\nThere is no auto-detection, deliberately. Detecting the adapter means inspecting the function's other\nlayers, which at synth time are frequently unresolved tokens; a detector that was right most of the time\nwould silently break the functions it got wrong. **Applying `HANDLER` to a web-adapter function\noverwrites the adapter's wrapper and the function stops serving.**\n\nThe launcher preserves and joins the function's existing loader value at startup. `existingLoaderValue`\nis an optional override: when supplied, CDK saves it unchanged as the customer's loader variable, and the\nlauncher adds instrumentation in its child process. Omit it to preserve the loader already in the function.\n\nRuby has no verified web-server loader and is rejected at synth in this mode.\n\n## Java handler interfaces\n\nThe Java layer ships four wrapper scripts, one per handler interface, and this is a correctness switch\nrather than a detail level:\n\n```ts\njavaHandlerDistro: OdigosJavaHandlerDistro.OTEL_STREAM_HANDLER\n```\n\n| Distro | For |\n|---|---|\n| `OTEL_HANDLER` | `RequestHandler` |\n| `OTEL_PROXY_HANDLER` | API Gateway proxy events (enriched) |\n| `OTEL_SQS_HANDLER` | SQS events (enriched) |\n| `OTEL_STREAM_HANDLER` | `RequestStreamHandler` |\n\nJava defaults to the full `java-lambda-otel-agent`, which supports handler and stream interfaces. The\nlegacy `javaHandlerDistro` option explicitly selects a lightweight wrapper. `OTEL_HANDLER` implements\n`RequestHandler`; use `OTEL_STREAM_HANDLER` for `RequestStreamHandler` when selecting a lightweight wrapper.\nPrefer the equivalent `distro` IDs below. Do not set both options.\n\n## Distributions and ADOT\n\nSet `distro` to the exact connector catalog ID. A fixed distro must match every function on that construct.\n\n| Language | Default | Alternatives |\n|---|---|---|\n| Java | `java-lambda-otel-agent` | `java-lambda-otel-wrapper`, `java-lambda-otel-proxy-wrapper`, `java-lambda-otel-sqs-wrapper`, `java-lambda-otel-stream-wrapper`, `java-lambda-adot`, `java-lambda-adot-application-signals` |\n| Node.js | `nodejs-lambda-otel` | `nodejs-lambda-adot`, `nodejs-lambda-adot-application-signals` |\n| Python | `python-lambda-otel` | `python-lambda-adot`, `python-lambda-adot-application-signals` |\n| Ruby | `ruby-lambda-otel` | none |\n\nADOT uses two architecture-matched layers: the language SDK and `adot-collector`. If mirroring the SDK\nwith `layerVersion`, also supply `collectorLayerVersion` or let `layerSource` resolve the collector.\nADOT supports Java 11/17/21, Node.js 18/20/22/24, and Python 3.10–3.13. ADOT and lightweight Java wrappers\ncannot use `WEB_SERVER` mode. Plain ADOT disables Application Signals. The Application Signals presets\nrequire traces **and** metrics, add `CloudWatchLambdaApplicationSignalsExecutionRolePolicy` to the Lambda\nrole, and require one-time CloudWatch Application Signals account/region setup. For an immutable imported\nrole, attach the policy separately. These presets also send enriched spans to Lambda's embedded AWS agent;\nNode.js/Python's AWS-derived service metrics do not become ordinary OTLP metrics at a custom destination.\n\n## Signals\n\n**Traces only, by default.** Metrics and logs are opt-in:\n\n```ts\ndestination: {\n endpoint: 'otlp.example.com:4317',\n metrics: true, // off unless you ask\n logs: true, // off unless you ask\n}\n```\n\nThey are opt-in because the cost of a signal the destination does not implement falls on the function:\nevery batch is refused and the in-Lambda collector retries it on an exponential backoff, inside billed\nduration. Traces are what nearly every destination accepts; the other two are a decision about your\ndestination, so they are made deliberately.\n\nA disabled signal gets no collector pipeline **and** the SDK is told not to produce it\n(`OTEL_METRICS_EXPORTER=none`) inside the launcher's child process. Enabled signals explicitly select\n`otlp` there. Both halves matter: a signal with no pipeline would otherwise be refused on every batch.\n\n`traces: false` with neither of the others on throws at synth — a collector with no pipeline fails to\nstart, which would leave the function instrumented and silent.\n\n**If Odigos also manages this function in manual mode, the signals have to match.** The connector renders\nthe collector configuration from the destination configured in Odigos and compares the whole string, so a\ntraces-only function judged against an all-three destination is reported as drifted on the\ncollector-export component. Enable the same set on both sides.\n\n## Instrumenting a whole stack\n\n```ts\nAspects.of(stack).add(new OdigosInstrumentationAspect(stack, {\n destination: { endpoint: 'otlp.example.com:4317' },\n}));\n```\n\n`skipUnsupportedRuntimes` defaults to `true` for the aspect: it visits every function in the scope,\nincluding ones whose runtime has no OpenTelemetry Lambda layer (`dotnet*`, `provided.*` for Go and custom\nruntimes). Each skip is a synth warning rather than a silent no-op. The construct defaults it to `false`,\nbecause explicitly asking to instrument a Go function is a mistake worth failing on.\n\n## Credentials in `headers`\n\n`destination.headers` is rendered into `ODIGOS_LAMBDA_CONFIG`, which is a plain Lambda\nenvironment variable — readable by anyone with `lambda:GetFunctionConfiguration` and visible in the\nconsole. For a long-lived credential, prefer a destination that authenticates by network position, or\nterminate at a collector you control.\n\n## How Odigos recognises the function\n\nLambda attribution uses `odigos:iac=v1`, `odigos:sdk-layer`, and (for ADOT) `odigos:collector-layer`\nfunction tags. The recorded ARNs identify the exact attached layer versions, including SAR output tokens.\nThere is no Lambda `ODIGOS_IAC` environment marker. Fargate uses its per-container environment marker.\n\nThe connector's `odigos:managed` Lambda tag and `ODIGOS_MANAGED` Fargate marker describe mutations and\nrollback snapshots owned by the connector. Do not add them to an IaC-managed workload.\n\n## Service names\n\nLeft unset, `OTEL_SERVICE_NAME` is the function's physical name when your stack names it explicitly, and\nthe construct id otherwise. The fallback exists because a name CloudFormation generates is a `Ref` to the\nfunction, and a function referencing itself in its own environment is a dependency cycle CloudFormation\nrejects at deploy time.\n\nThe connector compares `OTEL_SERVICE_NAME` against the workload's name in Odigos, which is the real AWS\nfunction name — so for a function whose name is generated, pass `serviceName` explicitly or it is reported\nas drifted. `serviceName` applies to **every** function a construct instruments, so use one construct per\nfunction when you want per-function names.\n\n## Do not also instrument these functions with the Odigos connector\n\nThe Odigos AWS connector instruments **live** functions by mutating them, and reconciles them back to its\nown desired state on every pass. A function instrumented here *and* enabled as an automatic-mode connector\nsource ends up owned by both: each `cdk deploy` reasserts the CDK's environment, each reconcile reasserts\nthe connector's, and every round trip publishes a new function version.\n\nPick one per function. Discovery-only (manual) mode is the combination that works: Odigos watches and\nreports, your stack owns the configuration. The IaC markers express that ownership.\n\n# ECS Fargate\n\n```ts\nimport { OdigosFargateInstrumentation, OdigosFargateLanguage } from '@odigos/aws-cdk';\n\nconst odigos = new OdigosFargateInstrumentation(this, 'Odigos', {\n destination: { httpEndpoint: 'https://otlp.example.com:4318' },\n});\n\nodigos.instrument({\n container: apiContainer, // the ecs.ContainerDefinition to instrument\n language: OdigosFargateLanguage.JAVA,\n service: apiService, // read OTEL_SERVICE_NAME off the ECS service\n});\n```\n\n```python\nfrom odigos_aws_cdk import OdigosFargateInstrumentation, OdigosFargateLanguage\n\nodigos = OdigosFargateInstrumentation(self, \"Odigos\",\n destination={\"http_endpoint\": \"https://otlp.example.com:4318\"},\n)\nodigos.instrument(\n container=api_container,\n language=OdigosFargateLanguage.JAVA,\n service=api_service,\n)\n```\n\n## What it does to the task definition\n\nFour moves, which are one mechanism and only work together:\n\n1. a bare-name task volume, `odigos-agent` — on Fargate an ephemeral-storage bind mount scoped to the task\n (there is no tmpfs);\n2. a **non-essential** `odigos-agent` container that copies the language agents out of the agents bundle\n into that volume and exits 0;\n3. the volume mounted read-only at `/var/odigos` in your container, which `DependsOn` the staging container\n with condition `SUCCESS` — legal only against a non-essential container, which is why (2) is\n non-essential;\n4. the language's activation environment, the OTLP export environment and the `ODIGOS_IAC` marker on your\n container.\n\nMarker presence alone is a false green here. A container can carry a complete, correct activation\nenvironment while the staging container is gone — the application then starts, finds nothing at\n`/var/odigos`, and exports nothing while reporting as instrumented. That is why all four are one construct.\n\n## Where the telemetry goes\n\nStraight to your destination, from inside the application process. **This is the substantive difference\nfrom Lambda**, where the SDK hands batches to a collector in the same sandbox and the export happens after\nthe response has already been returned. A Fargate task has no such collector, so a slow or unreachable\ndestination is felt by the application's own exporter.\n\n## Naming the service\n\n`OTEL_SERVICE_NAME` **must equal the workload's name in Odigos, which for a Fargate workload is the ECS\nservice name** — not the task definition family and not the container name. A different value is reported\nas instrumentation drift rather than treated as a naming preference, so there is no default: pass `service`\nto read the name off an `ecs.FargateService`, or `serviceName` when the service is defined elsewhere.\n\nThe service's physical name has to be one you set. A name CloudFormation generates is a `Ref` to the\nservice, and the task definition that service runs cannot reference it — CloudFormation rejects the cycle\nat deploy time — so a generated name throws at synth pointing you at `serviceName`.\n\n## Languages, and stating them\n\n| | Activated through | Needs `runtimeVersion` |\n|---|---|---|\n| `JAVA` | `JAVA_TOOL_OPTIONS` | no |\n| `PYTHON` | `PYTHONPATH` | no |\n| `NODEJS` | `NODE_OPTIONS` | no |\n| `DOTNET` | `CORECLR_*` / `DOTNET_*` (glibc only) | no |\n| `PHP` | `PHP_INI_SCAN_DIR` | **yes** — major.minor, e.g. `\"8.3\"` |\n| `RUBY` | `RUBYOPT` | **yes** — major.minor, e.g. `\"3.3\"` |\n\nThere is no aspect and no detection, and unlike Lambda that is not a matter of taste. A function declares\nits runtime; a container declares an image. A language guessed from an image would silently mis-instrument\nwhatever it got wrong — a Java agent staged into a Python container leaves it uninstrumented, and a\n`JAVA_TOOL_OPTIONS` on a JVM-less image is simply ignored, so nothing fails loudly enough to notice.\n\nphp and ruby need `runtimeVersion` because their agents are laid down per runtime version in the bundle,\nand the version selects the path their activation variable points at. It must be exactly `major.minor`;\nanything else names a directory that does not exist, and the container starts with no agent loaded.\n\n**Go cannot be instrumented on Fargate at all.** Its only zero-code instrumentation is eBPF, and Fargate\nforbids the privileged containers and host PID an eBPF agent needs. Use the OpenTelemetry Go SDK.\n\n## Loader variables your container already sets\n\nThe construct reads the value your container was created with and **appends** to it, joined by the\nseparator the language's own pattern specifies — a space for `JAVA_TOOL_OPTIONS` and `NODE_OPTIONS`, a\ncolon for `PYTHONPATH`:\n\n```ts\ntaskDefinition.addContainer('App', {\n image,\n environment: { JAVA_TOOL_OPTIONS: '-Xmx512m' },\n});\n// becomes: -Xmx512m -javaagent:/var/odigos/java/javaagent.jar\n```\n\nPass `existingLoaderValue` when the value is not visible at synth — set by an `environmentFiles` entry\nor baked into the image's own `ENV`. Do not supply a generated instrumentation variable through ECS\n`secrets`: it conflicts with the ordinary environment setting and is rejected. Move loader options into\nordinary application configuration before applying instrumentation.\n\n`PHP_INI_SCAN_DIR` and `RUBYOPT` are the exception: Odigos compares them **exactly**, so they are set\noutright and a value already there is reported as a synth warning rather than merged. Fold what your\napplication needs into the value Odigos sets.\n\n## Transport\n\nEach language's agent has a preferred transport, and giving the destination **both** endpoints lets each\none take it:\n\n```ts\ndestination: {\n endpoint: 'otlp.example.com:4317', // OTLP/gRPC, bare host:port\n httpEndpoint: 'https://otlp.example.com:4318', // OTLP/HTTP, scheme-qualified\n}\n```\n\nEvery agent in the bundle prefers `http/protobuf`. java, python, nodejs and dotnet honour\n`OTEL_EXPORTER_OTLP_PROTOCOL` and fall back to gRPC when that is all the destination offers; **php and\nruby cannot** — their community SDKs are `http/protobuf`-only, so instrumenting one against a gRPC-only\ndestination throws at synth rather than deploying a task that exports nothing.\n\nEndpoint and protocol are one decision, and are compared as one. Pairing an endpoint with the other\nprotocol fails at runtime as a connection reset that points nowhere near the cause, so an endpoint on the\nother protocol's standard port (4317 with `http/protobuf`, 4318 with `grpc`) is a synth warning.\n\nOn Fargate, `destination.headers` is rendered into `OTEL_EXPORTER_OTLP_HEADERS` as a sorted, URL-encoded\nheader list matching the connector. Pass raw header values, such as `Bearer token`, and let the construct\nencode them. The connector compares the transport, endpoint and headers against the selected destination.\n`ecs:DescribeTaskDefinition` and the console can read these values; task revisions can retain them.\n\n## Signals\n\nSame defaults as Lambda — traces on, metrics and logs opt-in — and the same requirement that they match\nwhat Odigos has configured for the destination. All three `OTEL_*_EXPORTER` variables are written\nexplicitly here. Lambda sets the same selectors inside the launcher rather than storing them in AWS.\nRuby Fargate supports traces only; Ruby Lambda also supports function stdout/stderr logs, but no metrics.\nUnsupported Ruby signals and profiles generate synth warnings; they do not activate missing exporters.\n\n## A task definition with more than one application\n\nSix applications in six languages in one task definition is a real shape. Call `instrument()` once per\ncontainer; there is **one** staging container for the whole task definition, and its command is built\nlazily from the union of every instrumented container's agents, in ascending directory order — which is\nexactly what the connector compares it against.\n\n```ts\nodigos.instrumentAll([\n { container: apiContainer, language: OdigosFargateLanguage.JAVA, service: svc },\n { container: workerContainer, language: OdigosFargateLanguage.PYTHON, service: svc },\n]);\n```\n\nAWS caps a task definition at 10 containers and the staging container needs one of them; a definition\nalready at the limit fails at synth rather than on `RegisterTaskDefinition`. Several constructs can share\nthe staging container only when they use the same agents image. Instrument each application container once.\nExisting manual `odigos-agent` containers/volumes and conflicting mounts are rejected; remove those manual\nresources before adopting the construct. Use Linux Fargate platform version `1.3.0` or newer (`LATEST` is\nrecommended) so the `SUCCESS` startup dependency is supported.\n\n## The agents image\n\nThe staging container pulls `registry.odigos.io/odigos-fargate-agents` at this package's release tag — a\nmulti-arch manifest list, so amd64 and Graviton tasks both get a matching image. **It is pulled by your\ntask's execution role at every task start**, so a task in a private subnet with no NAT and no registry\nendpoint cannot pull it. Mirror it into a registry your tasks can reach and pass `agentsImage`:\n\n```ts\nagentsImage: '111122223333.dkr.ecr.eu-west-1.amazonaws.com/odigos-fargate-agents:v0.0.19',\n```\n\nA mirror has to be the same bundle — the activation environment names exact paths inside it. The bundle is\nLinux-only and glibc-based: a Windows task definition throws at synth, and musl (Alpine) images have no\n.NET native profiler in it.\n\n**Whatever image you stage from is recorded in the marker**, as `image`, and Odigos holds the task\ndefinition to *that* rather than to the bundle the connector's own build pins. Two consequences worth\nknowing: a mirror is judged against itself instead of reading as drift, and upgrading this package ahead of\nthe connector is not drift either — the service stays conformant until you re-deploy, exactly as a Lambda\nfunction pinned to an older layer does. What *is* reported is two containers in one task definition\nrecording different images: there is one staging container and it cannot serve two bundles.\n\n## Do not also instrument these services with the connector\n\nSame rule as Lambda, with ECS's own cost. The connector instruments a live service by registering a new\ntask-definition revision and updating the service to it. A service instrumented here *and* enabled as an\nautomatic-mode source is owned by both: each `cdk deploy` reasserts your stack's definition, each\nreconcile reasserts the connector's, and every round trip registers a revision and rolls the service.\nDiscovery-only (manual) mode is the combination that works.\n\n# Bill of materials and removal\n\n| Flow | Resources and configuration left by deployment |\n|---|---|\n| Lambda public/custom layer | Layer reference(s), wrapper and compact config environment variables, IaC layer tags, new published versions/aliases if your app creates them |\n| Lambda `IN_ACCOUNT` | The above plus one SAR nested stack/layer per artifact family and architecture; ADOT adds the shared collector application |\n| Application Signals | The above plus a managed-policy attachment on the Lambda role; account-wide discovery is configured separately |\n| Fargate | A task-definition revision with one non-essential copier, one shared volume, mounts/dependencies, activation/export environment and per-container IaC marker; an ECS deployment when the service references that revision |\n\nThe constructs do not create a regional Collector, network routes, telemetry destination, or customer\ncredentials. Provision and remove those using their separate guides. Registry access and destination\nreachability are deployment prerequisites.\n\nTo uninstall instrumentation while keeping the application:\n\n1. Disable automatic connector ownership for the workload, then remove the instrumentation construct,\n `instrument()` calls or aspect from your app. Restore any explicit loader override you no longer want.\n2. Run `cdk diff`, review removal of the instrumentation resources/settings, then run `cdk deploy`.\n For Lambda, publish the uninstrumented version and move every serving alias to it. For Fargate,\n ensure the service references the new task revision and wait for the rollout to finish.\n3. Verify the application is healthy and sends no new Odigos telemetry. Old published Lambda versions\n and ECS revisions remain instrumented until retired; review all traffic and rollback references first.\n4. SAR layers use retention policies and can remain after stack removal. After no function or published\n version references one, remove that exact retained layer version with\n `aws lambda delete-layer-version --layer-name \"<LAYER_NAME>\" --version-number \"<LAYER_VERSION>\"`.\n Never delete a shared layer still in use. Retire unused task revisions through your existing ECS lifecycle.\n5. Remove dedicated, unused role policy attachments and telemetry credentials after confirming no other\n consumer needs them. Configurations retained in versions, task revisions and IaC history may still hold\n headers. Account-wide Application Signals discovery and its service-linked role are separate resources.\n\n`cdk destroy` removes the entire application stack and is only appropriate when retiring that application.\n\n# API\n\n| Export | |\n|---|---|\n| `OdigosLambdaInstrumentation` | the Lambda construct; `instrument(fn)`, `instrumentAll(fns)` |\n| `OdigosInstrumentationAspect` | applies it to every function in a scope |\n| `OdigosFargateInstrumentation` | the Fargate construct; `instrument(target)`, `instrumentAll(targets)` |\n| `OdigosFargateTarget` | one container to instrument: `container`, `language`, `service` / `serviceName`, `runtimeVersion`, `existingLoaderValue` |\n| `OdigosFargateLanguage` | `JAVA` \\| `PYTHON` \\| `NODEJS` \\| `DOTNET` \\| `PHP` \\| `RUBY` |\n| `OdigosDestination` | where telemetry goes; exactly one endpoint on Lambda, either or both on Fargate |\n| `OdigosLayerSource` | `ODIGOS_PUBLIC` \\| `IN_ACCOUNT` |\n| `OdigosInstrumentationMode` | `HANDLER` \\| `WEB_SERVER` |\n| `OdigosJavaHandlerDistro` | the four Java wrappers |\n| `renderCollectorConfig` | legacy inline collector config renderer for validation; the compact launcher generates the deployed config |\n| `sidecarCommand`, `evaluateAppendPattern` | the Fargate staging command and loader-value rendering |\n| `LAYER_ARNS`, `ODIGOS_VERSION` | the baked layer table and the release it came from |\n| `FARGATE_AGENTS_IMAGE`, `FARGATE_DISTROS_VERSION` | the agents image this build stages, and the distros release its recipes mirror |\n\n## License\n\nApache-2.0.\n"
|
|
3829
|
+
"markdown": "# Odigos CDK constructs for AWS\n\nInstrument AWS Lambda functions, ECS Fargate services and Amazon Bedrock AgentCore Runtimes with\nOpenTelemetry, from your own CDK app.\n\n```bash\nnpm install @odigos/aws-cdk@0.0.19\n```\n\nThe npm package is published. The corrections in this checkout need a new package release before\ncustomers receive them through npm. To use this checkout locally, run `npm ci`, `npm run build`, and\n`npm run package` in `cdk/`, then install `dist/js/aws-cdk@0.0.0.jsii.tgz` in the consuming app.\n\nThe Python distribution is built by jsii but is not published on PyPI;\n`pip install odigos-aws-cdk` currently fails. Python examples below apply to a locally built wheel:\nrun `npm ci`, `npm run build`, then `npm run package` from `cdk/`, and install the wheel under `dist/python/`.\nFor customer installation until PyPI publishing is enabled, use the CloudFormation instructions instead.\n\n| | Lambda | ECS Fargate | AgentCore Runtime |\n|---|---|---|---|\n| Construct | `OdigosLambdaInstrumentation` | `OdigosFargateInstrumentation` | `OdigosAgentCoreInstrumentation` |\n| Mechanism | a layer, plus an exec wrapper or loader variable | agents staged into a shared task volume by a run-to-completion container | runtime environment variables; the SDK bundle is prepared into your artifact separately |\n| Languages | python, nodejs, java, ruby | java, python, nodejs, dotnet, php, ruby | python (3.12), nodejs (22, CommonJS) |\n| Where telemetry goes | a collector in the same Lambda sandbox, which forwards | your destination, from the application process | your OTLP/HTTP destination, from the application process |\n| Language detection | from the function's declared runtime | none — you state the language | none — you state the language |\n\nLambda writes `odigos:iac=v1` and exact SDK/collector layer ARNs as function tags. Fargate writes an\n`ODIGOS_IAC` environment marker on each application container, and AgentCore one on each runtime. None of\nthem claims connector-managed ownership.\n\n# AWS Lambda\n\n```ts\nimport { OdigosLambdaInstrumentation } from '@odigos/aws-cdk';\n\nnew OdigosLambdaInstrumentation(this, 'Odigos', {\n destination: { endpoint: 'otlp.example.com:4317' },\n functions: [apiFn, workerFn],\n});\n```\n\n```python\nfrom odigos_aws_cdk import OdigosLambdaInstrumentation\n\nOdigosLambdaInstrumentation(self, \"Odigos\",\n destination={\"endpoint\": \"otlp.example.com:4317\"},\n functions=[api_fn, worker_fn],\n)\n```\n\nThat attaches the matching layer(s), sets `AWS_LAMBDA_EXEC_WRAPPER`, and writes the readable version-2\n`ODIGOS_LAMBDA_CONFIG` JSON. The layer launcher builds SDK settings and collector pipelines at startup;\ncustomer SDK environment variables remain saved unchanged in AWS. Public and in-account layers must be\nfrom `v0.0.19` or newer to read this configuration; a custom `layerVersion` must have the same bootstrap.\n\nApply instrumentation before creating published versions and aliases, then deploy the updated version and\npoint all traffic-serving aliases at it. Updating `$LATEST` alone does not instrument older versions.\n\n## How the telemetry actually leaves the function\n\nYour function's SDK **does not** export to your destination. It exports to an OpenTelemetry collector\nrunning inside the same Lambda sandbox, on localhost. The collector forwards to your destination *after*\nthe handler has already returned its response.\n\nThat indirection is the whole point. A slow or unreachable destination costs billed duration, not caller\nlatency — and the collector's `decouple` processor is what holds the sandbox open until the export queue\ndrains, so a low-traffic function does not lose its telemetry to the freeze.\n\nConsequently `OTEL_EXPORTER_OTLP_ENDPOINT` is deliberately never set. If you set it yourself you put the\nexport back on the invocation's critical path.\n\n## Endpoint grammar\n\n`endpoint` is OTLP/**gRPC** as bare `host:port` (conventionally 4317). `httpEndpoint` is OTLP/**HTTP** as a\nscheme-qualified URL (conventionally 4318). Exactly one. They select different collector exporters with\ndifferent endpoint grammars, so a scheme in `endpoint` — or its absence in `httpEndpoint` — throws at synth\nrather than producing a collector that starts and silently delivers nothing. A gRPC endpoint on port 4318\n(or an HTTP one on 4317) is the likeliest version of that mistake, and is reported as a synth warning.\n\n## Choosing a layer source\n\n```ts\nnew OdigosLambdaInstrumentation(this, 'Odigos', {\n destination: { endpoint: 'otlp.example.com:4317' },\n functions: [fn],\n layerSource: OdigosLayerSource.IN_ACCOUNT,\n});\n```\n\n| | `ODIGOS_PUBLIC` (default) | `IN_ACCOUNT` |\n|---|---|---|\n| What it synthesizes | a layer ARN | an `AWS::Serverless::Application` (nested stack) per language/arch |\n| Layer owner | the Odigos AWS account | **your** account, created by your stack |\n| Resolution | synth time, from a table baked into this package | deploy time, from the Serverless Application Repository |\n| Environment-agnostic stacks | not supported — needs a concrete region | works |\n| Deploy speed | unchanged | slower on first deploy |\n\nBoth install identical bytes. `IN_ACCOUNT` exists for organisations whose policy forbids attaching a\nLambda layer owned by another AWS account. It needs the deploying principal to be allowed\n`serverlessrepo:CreateCloudFormationTemplate` and `serverlessrepo:GetApplication`.\n\nIf you mirror the layer somewhere yourself, pass `layerVersion` and neither path is used.\n\n## Versioning\n\n**The package version is the artifact release version.** `@odigos/aws-cdk@0.0.19` resolves to layers built and\npublished by Odigos release `v0.0.19`, and pins the SAR application to semantic version `0.0.19` — which is\nimmutable, so it means the same bytes forever.\n\nNothing resolves at deploy time in the default path, so upgrading the layer is `npm update` and a\n`cdk diff` that shows the change. An instrumentation layer moving on its own, under a deployment that\nchanged nothing, is not a property you want.\n\n## Handler mode vs. web-server mode\n\n`OdigosInstrumentationMode.HANDLER` (the default) is for a normal Lambda handler. It sets\n`AWS_LAMBDA_EXEC_WRAPPER`.\n\n`OdigosInstrumentationMode.WEB_SERVER` is for a function running a web server behind the\n[AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter). The adapter owns the exec\nwrapper. This mode sets `AWS_LAMBDA_EXEC_WRAPPER=/opt/odigos-webserver`, records the previous wrapper in\n`ODIGOS_LAMBDA_CONFIG.webWrapper`, loads the agent through its language loader, then invokes the saved\nwrapper. Define the adapter's wrapper before applying instrumentation so it is preserved.\n\n```ts\nnew OdigosLambdaInstrumentation(this, 'Odigos', {\n destination: { endpoint: 'otlp.example.com:4317' },\n functions: [webFn],\n mode: OdigosInstrumentationMode.WEB_SERVER,\n // NODE_OPTIONS the function already needs — ours is appended, not substituted.\n existingLoaderValue: '--max-old-space-size=2048',\n});\n```\n\nThere is no auto-detection, deliberately. Detecting the adapter means inspecting the function's other\nlayers, which at synth time are frequently unresolved tokens; a detector that was right most of the time\nwould silently break the functions it got wrong. **Applying `HANDLER` to a web-adapter function\noverwrites the adapter's wrapper and the function stops serving.**\n\nThe launcher preserves and joins the function's existing loader value at startup. `existingLoaderValue`\nis an optional override: when supplied, CDK saves it unchanged as the customer's loader variable, and the\nlauncher adds instrumentation in its child process. Omit it to preserve the loader already in the function.\n\nRuby has no verified web-server loader and is rejected at synth in this mode.\n\n## Java handler interfaces\n\nThe Java layer ships four wrapper scripts, one per handler interface, and this is a correctness switch\nrather than a detail level:\n\n```ts\njavaHandlerDistro: OdigosJavaHandlerDistro.OTEL_STREAM_HANDLER\n```\n\n| Distro | For |\n|---|---|\n| `OTEL_HANDLER` | `RequestHandler` |\n| `OTEL_PROXY_HANDLER` | API Gateway proxy events (enriched) |\n| `OTEL_SQS_HANDLER` | SQS events (enriched) |\n| `OTEL_STREAM_HANDLER` | `RequestStreamHandler` |\n\nJava defaults to the full `java-lambda-otel-agent`, which supports handler and stream interfaces. The\nlegacy `javaHandlerDistro` option explicitly selects a lightweight wrapper. `OTEL_HANDLER` implements\n`RequestHandler`; use `OTEL_STREAM_HANDLER` for `RequestStreamHandler` when selecting a lightweight wrapper.\nPrefer the equivalent `distro` IDs below. Do not set both options.\n\n## Distributions and ADOT\n\nSet `distro` to the exact connector catalog ID. A fixed distro must match every function on that construct.\n\n| Language | Default | Alternatives |\n|---|---|---|\n| Java | `java-lambda-otel-agent` | `java-lambda-otel-wrapper`, `java-lambda-otel-proxy-wrapper`, `java-lambda-otel-sqs-wrapper`, `java-lambda-otel-stream-wrapper`, `java-lambda-adot`, `java-lambda-adot-application-signals` |\n| Node.js | `nodejs-lambda-otel` | `nodejs-lambda-adot`, `nodejs-lambda-adot-application-signals` |\n| Python | `python-lambda-otel` | `python-lambda-adot`, `python-lambda-adot-application-signals` |\n| Ruby | `ruby-lambda-otel` | none |\n\nADOT uses two architecture-matched layers: the language SDK and `adot-collector`. If mirroring the SDK\nwith `layerVersion`, also supply `collectorLayerVersion` or let `layerSource` resolve the collector.\nADOT supports Java 11/17/21, Node.js 18/20/22/24, and Python 3.10–3.13. ADOT and lightweight Java wrappers\ncannot use `WEB_SERVER` mode. Plain ADOT disables Application Signals. The Application Signals presets\nrequire traces **and** metrics, add `CloudWatchLambdaApplicationSignalsExecutionRolePolicy` to the Lambda\nrole, and require one-time CloudWatch Application Signals account/region setup. For an immutable imported\nrole, attach the policy separately. These presets also send enriched spans to Lambda's embedded AWS agent;\nNode.js/Python's AWS-derived service metrics do not become ordinary OTLP metrics at a custom destination.\n\n## Signals\n\n**Traces only, by default.** Metrics and logs are opt-in:\n\n```ts\ndestination: {\n endpoint: 'otlp.example.com:4317',\n metrics: true, // off unless you ask\n logs: true, // off unless you ask\n}\n```\n\nThey are opt-in because the cost of a signal the destination does not implement falls on the function:\nevery batch is refused and the in-Lambda collector retries it on an exponential backoff, inside billed\nduration. Traces are what nearly every destination accepts; the other two are a decision about your\ndestination, so they are made deliberately.\n\nA disabled signal gets no collector pipeline **and** the SDK is told not to produce it\n(`OTEL_METRICS_EXPORTER=none`) inside the launcher's child process. Enabled signals explicitly select\n`otlp` there. Both halves matter: a signal with no pipeline would otherwise be refused on every batch.\n\n`traces: false` with neither of the others on throws at synth — a collector with no pipeline fails to\nstart, which would leave the function instrumented and silent.\n\n**If Odigos also manages this function in manual mode, the signals have to match.** The connector renders\nthe collector configuration from the destination configured in Odigos and compares the whole string, so a\ntraces-only function judged against an all-three destination is reported as drifted on the\ncollector-export component. Enable the same set on both sides.\n\n## Instrumenting a whole stack\n\n```ts\nAspects.of(stack).add(new OdigosInstrumentationAspect(stack, {\n destination: { endpoint: 'otlp.example.com:4317' },\n}));\n```\n\n`skipUnsupportedRuntimes` defaults to `true` for the aspect: it visits every function in the scope,\nincluding ones whose runtime has no OpenTelemetry Lambda layer (`dotnet*`, `provided.*` for Go and custom\nruntimes). Each skip is a synth warning rather than a silent no-op. The construct defaults it to `false`,\nbecause explicitly asking to instrument a Go function is a mistake worth failing on.\n\n## Credentials in `headers`\n\n`destination.headers` is rendered into `ODIGOS_LAMBDA_CONFIG`, which is a plain Lambda\nenvironment variable — readable by anyone with `lambda:GetFunctionConfiguration` and visible in the\nconsole. For a long-lived credential, prefer a destination that authenticates by network position, or\nterminate at a collector you control.\n\n## How Odigos recognises the function\n\nLambda attribution uses `odigos:iac=v1`, `odigos:sdk-layer`, and (for ADOT) `odigos:collector-layer`\nfunction tags. The recorded ARNs identify the exact attached layer versions, including SAR output tokens.\nThere is no Lambda `ODIGOS_IAC` environment marker. Fargate uses its per-container environment marker.\n\nThe connector's `odigos:managed` Lambda tag and `ODIGOS_MANAGED` Fargate marker describe mutations and\nrollback snapshots owned by the connector. Do not add them to an IaC-managed workload.\n\n## Service names\n\nLeft unset, `OTEL_SERVICE_NAME` is the function's physical name when your stack names it explicitly, and\nthe construct id otherwise. The fallback exists because a name CloudFormation generates is a `Ref` to the\nfunction, and a function referencing itself in its own environment is a dependency cycle CloudFormation\nrejects at deploy time.\n\nThe connector compares `OTEL_SERVICE_NAME` against the workload's name in Odigos, which is the real AWS\nfunction name — so for a function whose name is generated, pass `serviceName` explicitly or it is reported\nas drifted. `serviceName` applies to **every** function a construct instruments, so use one construct per\nfunction when you want per-function names.\n\n## Do not also instrument these functions with the Odigos connector\n\nThe Odigos AWS connector instruments **live** functions by mutating them, and reconciles them back to its\nown desired state on every pass. A function instrumented here *and* enabled as an automatic-mode connector\nsource ends up owned by both: each `cdk deploy` reasserts the CDK's environment, each reconcile reasserts\nthe connector's, and every round trip publishes a new function version.\n\nPick one per function. Discovery-only (manual) mode is the combination that works: Odigos watches and\nreports, your stack owns the configuration. The IaC markers express that ownership.\n\n# ECS Fargate\n\n```ts\nimport { OdigosFargateInstrumentation, OdigosFargateLanguage } from '@odigos/aws-cdk';\n\nconst odigos = new OdigosFargateInstrumentation(this, 'Odigos', {\n destination: { httpEndpoint: 'https://otlp.example.com:4318' },\n});\n\nodigos.instrument({\n container: apiContainer, // the ecs.ContainerDefinition to instrument\n language: OdigosFargateLanguage.JAVA,\n service: apiService, // read OTEL_SERVICE_NAME off the ECS service\n});\n```\n\n```python\nfrom odigos_aws_cdk import OdigosFargateInstrumentation, OdigosFargateLanguage\n\nodigos = OdigosFargateInstrumentation(self, \"Odigos\",\n destination={\"http_endpoint\": \"https://otlp.example.com:4318\"},\n)\nodigos.instrument(\n container=api_container,\n language=OdigosFargateLanguage.JAVA,\n service=api_service,\n)\n```\n\n## What it does to the task definition\n\nFour moves, which are one mechanism and only work together:\n\n1. a bare-name task volume, `odigos-agent` — on Fargate an ephemeral-storage bind mount scoped to the task\n (there is no tmpfs);\n2. a **non-essential** `odigos-agent` container that copies the language agents out of the agents bundle\n into that volume and exits 0;\n3. the volume mounted read-only at `/var/odigos` in your container, which `DependsOn` the staging container\n with condition `SUCCESS` — legal only against a non-essential container, which is why (2) is\n non-essential;\n4. the language's activation environment, the OTLP export environment and the `ODIGOS_IAC` marker on your\n container.\n\nMarker presence alone is a false green here. A container can carry a complete, correct activation\nenvironment while the staging container is gone — the application then starts, finds nothing at\n`/var/odigos`, and exports nothing while reporting as instrumented. That is why all four are one construct.\n\n## Where the telemetry goes\n\nStraight to your destination, from inside the application process. **This is the substantive difference\nfrom Lambda**, where the SDK hands batches to a collector in the same sandbox and the export happens after\nthe response has already been returned. A Fargate task has no such collector, so a slow or unreachable\ndestination is felt by the application's own exporter.\n\n## Naming the service\n\n`OTEL_SERVICE_NAME` **must equal the workload's name in Odigos, which for a Fargate workload is the ECS\nservice name** — not the task definition family and not the container name. A different value is reported\nas instrumentation drift rather than treated as a naming preference, so there is no default: pass `service`\nto read the name off an `ecs.FargateService`, or `serviceName` when the service is defined elsewhere.\n\nThe service's physical name has to be one you set. A name CloudFormation generates is a `Ref` to the\nservice, and the task definition that service runs cannot reference it — CloudFormation rejects the cycle\nat deploy time — so a generated name throws at synth pointing you at `serviceName`.\n\n## Languages, and stating them\n\n| | Activated through | Needs `runtimeVersion` |\n|---|---|---|\n| `JAVA` | `JAVA_TOOL_OPTIONS` | no |\n| `PYTHON` | `PYTHONPATH` | no |\n| `NODEJS` | `NODE_OPTIONS` | no |\n| `DOTNET` | `CORECLR_*` / `DOTNET_*` (glibc only) | no |\n| `PHP` | `PHP_INI_SCAN_DIR` | **yes** — major.minor, e.g. `\"8.3\"` |\n| `RUBY` | `RUBYOPT` | **yes** — major.minor, e.g. `\"3.3\"` |\n\nThere is no aspect and no detection, and unlike Lambda that is not a matter of taste. A function declares\nits runtime; a container declares an image. A language guessed from an image would silently mis-instrument\nwhatever it got wrong — a Java agent staged into a Python container leaves it uninstrumented, and a\n`JAVA_TOOL_OPTIONS` on a JVM-less image is simply ignored, so nothing fails loudly enough to notice.\n\nphp and ruby need `runtimeVersion` because their agents are laid down per runtime version in the bundle,\nand the version selects the path their activation variable points at. It must be exactly `major.minor`;\nanything else names a directory that does not exist, and the container starts with no agent loaded.\n\n**Go cannot be instrumented on Fargate at all.** Its only zero-code instrumentation is eBPF, and Fargate\nforbids the privileged containers and host PID an eBPF agent needs. Use the OpenTelemetry Go SDK.\n\n## Loader variables your container already sets\n\nThe construct reads the value your container was created with and **appends** to it, joined by the\nseparator the language's own pattern specifies — a space for `JAVA_TOOL_OPTIONS` and `NODE_OPTIONS`, a\ncolon for `PYTHONPATH`:\n\n```ts\ntaskDefinition.addContainer('App', {\n image,\n environment: { JAVA_TOOL_OPTIONS: '-Xmx512m' },\n});\n// becomes: -Xmx512m -javaagent:/var/odigos/java/javaagent.jar\n```\n\nPass `existingLoaderValue` when the value is not visible at synth — set by an `environmentFiles` entry\nor baked into the image's own `ENV`. Do not supply a generated instrumentation variable through ECS\n`secrets`: it conflicts with the ordinary environment setting and is rejected. Move loader options into\nordinary application configuration before applying instrumentation.\n\n`PHP_INI_SCAN_DIR` and `RUBYOPT` are the exception: Odigos compares them **exactly**, so they are set\noutright and a value already there is reported as a synth warning rather than merged. Fold what your\napplication needs into the value Odigos sets.\n\n## Transport\n\nEach language's agent has a preferred transport, and giving the destination **both** endpoints lets each\none take it:\n\n```ts\ndestination: {\n endpoint: 'otlp.example.com:4317', // OTLP/gRPC, bare host:port\n httpEndpoint: 'https://otlp.example.com:4318', // OTLP/HTTP, scheme-qualified\n}\n```\n\nEvery agent in the bundle prefers `http/protobuf`. java, python, nodejs and dotnet honour\n`OTEL_EXPORTER_OTLP_PROTOCOL` and fall back to gRPC when that is all the destination offers; **php and\nruby cannot** — their community SDKs are `http/protobuf`-only, so instrumenting one against a gRPC-only\ndestination throws at synth rather than deploying a task that exports nothing.\n\nEndpoint and protocol are one decision, and are compared as one. Pairing an endpoint with the other\nprotocol fails at runtime as a connection reset that points nowhere near the cause, so an endpoint on the\nother protocol's standard port (4317 with `http/protobuf`, 4318 with `grpc`) is a synth warning.\n\nOn Fargate, `destination.headers` is rendered into `OTEL_EXPORTER_OTLP_HEADERS` as a sorted, URL-encoded\nheader list matching the connector. Pass raw header values, such as `Bearer token`, and let the construct\nencode them. The connector compares the transport, endpoint and headers against the selected destination.\n`ecs:DescribeTaskDefinition` and the console can read these values; task revisions can retain them.\n\n## Signals\n\nSame defaults as Lambda — traces on, metrics and logs opt-in — and the same requirement that they match\nwhat Odigos has configured for the destination. All three `OTEL_*_EXPORTER` variables are written\nexplicitly here. Lambda sets the same selectors inside the launcher rather than storing them in AWS.\nRuby Fargate supports traces only; Ruby Lambda also supports function stdout/stderr logs, but no metrics.\nUnsupported Ruby signals and profiles generate synth warnings; they do not activate missing exporters.\n\n## A task definition with more than one application\n\nSix applications in six languages in one task definition is a real shape. Call `instrument()` once per\ncontainer; there is **one** staging container for the whole task definition, and its command is built\nlazily from the union of every instrumented container's agents, in ascending directory order — which is\nexactly what the connector compares it against.\n\n```ts\nodigos.instrumentAll([\n { container: apiContainer, language: OdigosFargateLanguage.JAVA, service: svc },\n { container: workerContainer, language: OdigosFargateLanguage.PYTHON, service: svc },\n]);\n```\n\nAWS caps a task definition at 10 containers and the staging container needs one of them; a definition\nalready at the limit fails at synth rather than on `RegisterTaskDefinition`. Several constructs can share\nthe staging container only when they use the same agents image. Instrument each application container once.\nExisting manual `odigos-agent` containers/volumes and conflicting mounts are rejected; remove those manual\nresources before adopting the construct. Use Linux Fargate platform version `1.3.0` or newer (`LATEST` is\nrecommended) so the `SUCCESS` startup dependency is supported.\n\n## The agents image\n\nThe staging container pulls `registry.odigos.io/odigos-fargate-agents` at this package's release tag — a\nmulti-arch manifest list, so amd64 and Graviton tasks both get a matching image. **It is pulled by your\ntask's execution role at every task start**, so a task in a private subnet with no NAT and no registry\nendpoint cannot pull it. Mirror it into a registry your tasks can reach and pass `agentsImage`:\n\n```ts\nagentsImage: '111122223333.dkr.ecr.eu-west-1.amazonaws.com/odigos-fargate-agents:v0.0.19',\n```\n\nA mirror has to be the same bundle — the activation environment names exact paths inside it. The bundle is\nLinux-only and glibc-based: a Windows task definition throws at synth, and musl (Alpine) images have no\n.NET native profiler in it.\n\n**Whatever image you stage from is recorded in the marker**, as `image`, and Odigos holds the task\ndefinition to *that* rather than to the bundle the connector's own build pins. Two consequences worth\nknowing: a mirror is judged against itself instead of reading as drift, and upgrading this package ahead of\nthe connector is not drift either — the service stays conformant until you re-deploy, exactly as a Lambda\nfunction pinned to an older layer does. What *is* reported is two containers in one task definition\nrecording different images: there is one staging container and it cannot serve two bundles.\n\n## Do not also instrument these services with the connector\n\nSame rule as Lambda, with ECS's own cost. The connector instruments a live service by registering a new\ntask-definition revision and updating the service to it. A service instrumented here *and* enabled as an\nautomatic-mode source is owned by both: each `cdk deploy` reasserts your stack's definition, each\nreconcile reasserts the connector's, and every round trip registers a revision and rolls the service.\nDiscovery-only (manual) mode is the combination that works.\n\n# Amazon Bedrock AgentCore Runtime\n\n```ts\nimport {\n OdigosAgentCoreInstrumentation,\n OdigosAgentCoreLanguage,\n OdigosAgentCoreDistribution,\n OdigosAgentCoreDelivery, // only for ADOT-only artifacts, see below\n} from '@odigos/aws-cdk';\n\nconst odigos = new OdigosAgentCoreInstrumentation(this, 'Odigos', {\n destination: {\n httpEndpoint: 'https://otlp.example.com:4318',\n headers: { Authorization: 'Bearer <token>' },\n },\n});\n\nodigos.instrument({\n runtime: agentRuntime, // CfnRuntime, L2 Runtime, or CfnInclude resource\n language: OdigosAgentCoreLanguage.PYTHON,\n distribution: OdigosAgentCoreDistribution.ADOT, // the profile prepared into the artifact\n});\n```\n\n```python\nfrom odigos_aws_cdk import (\n OdigosAgentCoreInstrumentation,\n OdigosAgentCoreLanguage,\n OdigosAgentCoreDistribution,\n)\n\nodigos = OdigosAgentCoreInstrumentation(self, \"Odigos\",\n destination={\n \"http_endpoint\": \"https://otlp.example.com:4318\",\n \"headers\": {\"Authorization\": \"Bearer <token>\"},\n },\n)\nodigos.instrument(\n runtime=agent_runtime,\n language=OdigosAgentCoreLanguage.PYTHON,\n distribution=OdigosAgentCoreDistribution.ADOT,\n)\n```\n\n`runtime` is any `AWS::BedrockAgentCore::Runtime` resource: an L1 `CfnRuntime`, a raw `CfnResource`, a\nresource from `CfnInclude.getResource()`, or a construct whose `node.defaultChild` is one (the L2\n`Runtime` in newer `aws-cdk-lib` releases). The construct writes through property overrides on\n`EnvironmentVariables`, so it needs no particular `aws-cdk-lib` version. Anything else throws at synth.\n\n## Prepare the artifact first\n\n**This construct does not install anything.** The environment it writes switches on an Odigos SDK\nbootstrap that must already be inside the artifact the runtime deploys; without it the variables are\ninert, and Odigos reports the runtime as not conformant. Prepare the artifact in your build by adding the\nOdigos package to the application's dependencies: `pip install \"odigos-agentcore[adot]\"` (or\n`[openllmetry]`, matching `distribution`) or `npm install @odigos/agentcore`.\n\n- **Container artifact:** Python needs nothing further; the package loads its dormant bootstrap at interpreter\n start. For Node.js, append `--require <abs path>/node_modules/@odigos/agentcore/register.cjs` to\n `NODE_OPTIONS`, keeping the application's existing flags.\n- **Code (ZIP) artifact:** install the package into the directory you ZIP, and set the runtime's `EntryPoint`\n to the wrapper followed by your original entry point: `[\"odigos_agentcore_start.py\", \"app.py\"]` or\n `[\"node_modules/@odigos/agentcore/odigos_agentcore_start.js\", \"index.js\"]`. The wrapper starts the\n bootstrap and then your application.\n\nWithout registry access, copy the bundle from `registry.odigos.io/odigos-agentcore-agents:<version>` instead\n(`/var/odigos/agentcore/python/3.12` or `/var/odigos/agentcore/nodejs/22`, into the image at\n`/opt/odigos/agentcore` or into the ZIP as `odigos-agentcore/`), and load its bootstrap before application\nimports: append `/opt/odigos/agentcore/bootstrap/python` to `PYTHONPATH` or `--require\n/opt/odigos/agentcore/bootstrap/node/register.cjs` to `NODE_OPTIONS`; in a ZIP, use the wrapper inside the\nbundle, `odigos-agentcore/bootstrap/python/odigos_agentcore_start.py` or `.../node/odigos_agentcore_start.js`.\n\nThe full steps are at <https://docs.odigos.io/cloud-connectors/aws/workloads/agentcore/prepare>.\n`AGENTCORE_AGENTS_IMAGE` exports the bundle image this package release pairs with.\n\n### ADOT only: `delivery: ADOPT`\n\nAn artifact that carries AWS Distro for OpenTelemetry and no Odigos package can be instrumented too.\nSet `delivery: OdigosAgentCoreDelivery.ADOPT` (the default is `PACKAGE`), with the ADOT distribution:\n\n```ts\nodigos.instrument({\n runtime: agentRuntime,\n language: OdigosAgentCoreLanguage.PYTHON,\n delivery: OdigosAgentCoreDelivery.ADOPT, // the artifact carries ADOT only\n});\n```\n\nPrepare the artifact with ADOT and its own launcher:\n\n- **Python:** add `aws-opentelemetry-distro` to the dependencies and start through `opentelemetry-instrument`:\n a ZIP's `EntryPoint` becomes `[\"opentelemetry-instrument\", \"app.py\"]`, a container's `CMD` is prefixed with\n `opentelemetry-instrument`.\n- **Node.js (CommonJS):** add `@aws/aws-distro-opentelemetry-node-autoinstrumentation` and append\n `--require @aws/aws-distro-opentelemetry-node-autoinstrumentation/register` to `NODE_OPTIONS`, on the runtime\n or in the image, keeping existing flags. The construct does not write `NODE_OPTIONS`.\n\nThe construct then writes the connector's adopt recipe (`agentCoreAdoptEnv`): the table below without\n`ODIGOS_AGENTCORE_ENABLED` and `ODIGOS_AGENTCORE_DISTRO` (both removed), `OTEL_PROPAGATORS` set to\n`tracecontext,baggage`, and `ODIGOS_AGENTCORE_PACKAGE` declaring the mode, for example\n`{\"v\":1,\"language\":\"python\",\"distros\":[\"python-agentcore-adot\"],\"mode\":\"adopt\"}` (Node.js adds\n`\"moduleFormat\":\"commonjs\"` before `mode`). The connector reads that mode and checks the runtime against the\nadopt recipe. ADOT cannot root an invocation at the agent, so AgentCore's own service span stays missing from\nthe trace; the Odigos package adds it. Any distribution other than `ADOT` with `ADOPT` throws at synth.\n\n`language` and `distribution` must describe what you prepared. They are written into\n`ODIGOS_AGENTCORE_PACKAGE` and `ODIGOS_AGENTCORE_DISTRO`, which the connector checks against the\nprofile, and the bootstrap starts the profile the distro names. `distribution` defaults to `ADOT`.\n\n| | `ADOT` (default) | `OPENLLMETRY` |\n|---|---|---|\n| Distro written | `<language>-agentcore-adot` | `<language>-agentcore-openllmetry` |\n| SDK | AWS Distro for OpenTelemetry | OpenLLMetry Bedrock on the upstream SDK |\n\nOnly Python 3.12 and CommonJS Node.js 22 artifacts are qualified. Native ESM Node.js needs explicit SDK\ninitialization and is not covered by this recipe.\n\n## What it writes\n\nWith `delivery: PACKAGE` (the default; see above for `ADOPT`). Every key is compared exactly by the connector's observer, which rebuilds the same map from the\ndestination configured in Odigos:\n\n| Variable | Value |\n|---|---|\n| `ODIGOS_AGENTCORE_ENABLED` | `true` |\n| `ODIGOS_AGENTCORE_DISTRO` | `<language>-agentcore-<distribution>` |\n| `ODIGOS_AGENTCORE_PACKAGE` | `{\"v\":1,\"language\":\"<language>\",\"distros\":[\"<distro>\"]}`, plus `\"moduleFormat\":\"commonjs\"` for Node.js |\n| `ODIGOS_IAC` | `{\"distro\":\"<distro>\",\"recipe\":\"1\",\"v\":1}` |\n| `DISABLE_ADOT_OBSERVABILITY` | `true` |\n| `AGENT_OBSERVABILITY_ENABLED` | `false` |\n| `OTEL_SERVICE_NAME` | see below |\n| `OTEL_EXPORTER_OTLP_ENDPOINT` | `httpEndpoint` with trailing `/` removed |\n| `OTEL_EXPORTER_OTLP_PROTOCOL` | `http/protobuf` |\n| `OTEL_EXPORTER_OTLP_{TRACES,METRICS,LOGS}_ENDPOINT` | `<endpoint>/v1/traces`, `/v1/metrics`, `/v1/logs` |\n| `OTEL_EXPORTER_OTLP_{TRACES,METRICS,LOGS}_PROTOCOL` | `http/protobuf` |\n| `OTEL_{TRACES,METRICS,LOGS}_EXPORTER` | `otlp` when the signal is enabled, `none` otherwise |\n| `OTEL_EXPORTER_OTLP_HEADERS` | the destination headers, URL-encoded and sorted; removed when there are none |\n| `OTEL_SDK_DISABLED` | `false` |\n| `OTEL_PROPAGATORS` | `tracecontext,baggage,xray` |\n| `OTEL_TRACES_SAMPLER` | `parentbased_always_on` |\n| `OTEL_AWS_APPLICATION_SIGNALS_ENABLED` | `false` |\n| `OTEL_AWS_DYNAMIC_INSTRUMENTATION_ENABLED` | `false` |\n| `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` | `false` |\n| `TRACELOOP_TRACE_CONTENT` | `false` |\n| `OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED` | `true` (also on Node.js, where it is inert) |\n| `OTEL_PYTHON_DISTRO` (Python) | `aws_distro` (ADOT) or `distro` (OpenLLMetry) |\n| `OTEL_PYTHON_CONFIGURATOR` (Python) | `aws_configurator` (ADOT) or `configurator` (OpenLLMetry) |\n| `OTEL_PYTHON_DISABLED_INSTRUMENTATIONS` (Python) | `boto3` (ADOT) or `botocore,aws_langchain,aws_openai_agents,aws_llama-index,aws_crewai,aws_mcp` (OpenLLMetry) |\n\nIt also **removes** `OTEL_EXPORTER_OTLP_{TRACES,METRICS,LOGS}_HEADERS`, because a signal-specific header\noverrides the shared credential, and `ODIGOS_MANAGED`, which is the connector's own ownership marker.\nOther variables the runtime sets are kept. Replacing one the runtime already sets to a different value is\na synth warning. AgentCore allows at most 50 variables; the recipe uses 27–30 of them. Synth warns when\nthe known total would exceed 50, or when its size exceeds the platform byte limit (1536 bytes for V2 code\nartifacts, 2560 for V2 containers).\n\nPrompt, response and tool content capture stays off. The Python bootstrap also strips GenAI content\nattributes that some instrumentations record regardless of that setting.\n\n## Destination\n\nAgentCore exports **directly** to a global OTLP/HTTP destination. `httpEndpoint` is required and\n`endpoint` (gRPC) is rejected. The URL must be an `http` or `https` base URL without credentials, query or\nfragment, and without a per-signal `/v1/traces`, `/v1/metrics` or `/v1/logs` path: the recipe adds those\npaths itself. `destination.headers` is written into `OTEL_EXPORTER_OTLP_HEADERS` as plain runtime\nconfiguration, readable by anyone with `bedrock-agentcore:GetAgentRuntime`. Pass raw header values and\nlet the construct encode them.\n\n## Service names\n\n`OTEL_SERVICE_NAME` defaults to the runtime's `AgentRuntimeName` when the template gives it as a literal\nstring. That is also the workload name Odigos uses, unless a service name override is configured there.\nWhen the name is a token, such as a `Fn::Join` with the stack name, pass `serviceName`; synth throws\notherwise.\n\n## Signals\n\nSame defaults as Lambda and Fargate: traces on, metrics and logs opt-in. They must match the signals the\ndestination has in Odigos. All three exporter selectors are written explicitly, and at least one signal\nmust be enabled.\n\n## Do not also enable automatic mode for these runtimes\n\nThe connector refuses to install or manage a runtime that carries `ODIGOS_IAC`, and reports it as an\nerror. Leave AgentCore sources in discovery-only (manual) mode in Odigos: Odigos observes and reports, and\nyour stack owns the configuration. To hand a runtime to automatic mode, remove this construct and deploy\nfirst.\n\n# Bill of materials and removal\n\n| Flow | Resources and configuration left by deployment |\n|---|---|\n| Lambda public/custom layer | Layer reference(s), wrapper and compact config environment variables, IaC layer tags, new published versions/aliases if your app creates them |\n| Lambda `IN_ACCOUNT` | The above plus one SAR nested stack/layer per artifact family and architecture; ADOT adds the shared collector application |\n| Application Signals | The above plus a managed-policy attachment on the Lambda role; account-wide discovery is configured separately |\n| Fargate | A task-definition revision with one non-essential copier, one shared volume, mounts/dependencies, activation/export environment and per-container IaC marker; an ECS deployment when the service references that revision |\n| AgentCore Runtime | Environment variables on the runtime (export settings, profile selection, `ODIGOS_AGENTCORE_PACKAGE`, `ODIGOS_IAC`) and a new runtime version when it deploys. The prepared SDK bundle in your artifact comes from your own build, not this construct |\n\nThe constructs do not create a regional Collector, network routes, telemetry destination, or customer\ncredentials. Provision and remove those using their separate guides. Registry access and destination\nreachability are deployment prerequisites.\n\nTo uninstall instrumentation while keeping the application:\n\n1. Disable automatic connector ownership for the workload, then remove the instrumentation construct,\n `instrument()` calls or aspect from your app. Restore any explicit loader override you no longer want.\n2. Run `cdk diff`, review removal of the instrumentation resources/settings, then run `cdk deploy`.\n For Lambda, publish the uninstrumented version and move every serving alias to it. For Fargate,\n ensure the service references the new task revision and wait for the rollout to finish. For\n AgentCore, wait for the `DEFAULT` endpoint to serve the new version, update custom endpoints, and\n remove the SDK bundle from your artifact build if you no longer want it.\n3. Verify the application is healthy and sends no new Odigos telemetry. Old published Lambda versions\n and ECS revisions remain instrumented until retired; review all traffic and rollback references first.\n4. SAR layers use retention policies and can remain after stack removal. After no function or published\n version references one, remove that exact retained layer version with\n `aws lambda delete-layer-version --layer-name \"<LAYER_NAME>\" --version-number \"<LAYER_VERSION>\"`.\n Never delete a shared layer still in use. Retire unused task revisions through your existing ECS lifecycle.\n5. Remove dedicated, unused role policy attachments and telemetry credentials after confirming no other\n consumer needs them. Configurations retained in versions, task revisions and IaC history may still hold\n headers. Account-wide Application Signals discovery and its service-linked role are separate resources.\n\n`cdk destroy` removes the entire application stack and is only appropriate when retiring that application.\n\n# API\n\n| Export | |\n|---|---|\n| `OdigosLambdaInstrumentation` | the Lambda construct; `instrument(fn)`, `instrumentAll(fns)` |\n| `OdigosInstrumentationAspect` | applies it to every function in a scope |\n| `OdigosFargateInstrumentation` | the Fargate construct; `instrument(target)`, `instrumentAll(targets)` |\n| `OdigosFargateTarget` | one container to instrument: `container`, `language`, `service` / `serviceName`, `runtimeVersion`, `existingLoaderValue` |\n| `OdigosFargateLanguage` | `JAVA` \\| `PYTHON` \\| `NODEJS` \\| `DOTNET` \\| `PHP` \\| `RUBY` |\n| `OdigosAgentCoreInstrumentation` | the AgentCore construct; `instrument(target)` |\n| `OdigosAgentCoreTarget` | one runtime to instrument: `runtime`, `language`, `distribution`, `delivery`, `serviceName` |\n| `OdigosAgentCoreLanguage` | `PYTHON` \\| `NODEJS` |\n| `OdigosAgentCoreDistribution` | `ADOT` \\| `OPENLLMETRY` |\n| `OdigosAgentCoreDelivery` | `PACKAGE` (Odigos package or carrier bundle) \\| `ADOPT` (ADOT only) |\n| `OdigosDestination` | where telemetry goes; exactly one endpoint on Lambda, either or both on Fargate, `httpEndpoint` only on AgentCore |\n| `OdigosLayerSource` | `ODIGOS_PUBLIC` \\| `IN_ACCOUNT` |\n| `OdigosInstrumentationMode` | `HANDLER` \\| `WEB_SERVER` |\n| `OdigosJavaHandlerDistro` | the four Java wrappers |\n| `renderCollectorConfig` | legacy inline collector config renderer for validation; the compact launcher generates the deployed config |\n| `sidecarCommand`, `evaluateAppendPattern` | the Fargate staging command and loader-value rendering |\n| `LAYER_ARNS`, `ODIGOS_VERSION` | the baked layer table and the release it came from |\n| `FARGATE_AGENTS_IMAGE`, `FARGATE_DISTROS_VERSION` | the agents image this build stages, and the distros release its recipes mirror |\n| `AGENTCORE_AGENTS_IMAGE`, `AGENTCORE_RECIPE_VERSION`, `AGENTCORE_DISTRIBUTIONS` | the AgentCore SDK bundle image for this release, the connector recipe version, and the profile catalog |\n| `agentCoreEnvironment`, `renderAgentCoreHeaders` | the AgentCore environment recipe and header encoding (TypeScript only) |\n\n## License\n\nApache-2.0.\n"
|
|
3830
3830
|
},
|
|
3831
3831
|
"repository": {
|
|
3832
3832
|
"directory": "cdk",
|
|
@@ -3848,6 +3848,341 @@
|
|
|
3848
3848
|
}
|
|
3849
3849
|
},
|
|
3850
3850
|
"types": {
|
|
3851
|
+
"@odigos/aws-cdk.OdigosAgentCoreDelivery": {
|
|
3852
|
+
"assembly": "@odigos/aws-cdk",
|
|
3853
|
+
"docs": {
|
|
3854
|
+
"remarks": "Mirrors the connector's delivery modes for a manually instrumented runtime. The construct cannot see the\nartifact, so this must say how it was actually prepared: the connector reads the mode back from\n`ODIGOS_AGENTCORE_PACKAGE` and compares the runtime against that recipe.",
|
|
3855
|
+
"stability": "stable",
|
|
3856
|
+
"summary": "How the AgentCore artifact carries its OpenTelemetry SDK, which decides the environment recipe."
|
|
3857
|
+
},
|
|
3858
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreDelivery",
|
|
3859
|
+
"kind": "enum",
|
|
3860
|
+
"locationInModule": {
|
|
3861
|
+
"filename": "src/types.ts",
|
|
3862
|
+
"line": 169
|
|
3863
|
+
},
|
|
3864
|
+
"members": [
|
|
3865
|
+
{
|
|
3866
|
+
"docs": {
|
|
3867
|
+
"remarks": "The bootstrap roots each invocation at\nthe agent and links AgentCore's own service span.",
|
|
3868
|
+
"stability": "stable",
|
|
3869
|
+
"summary": "The artifact carries the Odigos package (`odigos-agentcore` / `@odigos/agentcore`) or the carrier bundle, whose dormant bootstrap this environment switches on."
|
|
3870
|
+
},
|
|
3871
|
+
"name": "PACKAGE"
|
|
3872
|
+
},
|
|
3873
|
+
{
|
|
3874
|
+
"docs": {
|
|
3875
|
+
"custom": {
|
|
3876
|
+
"aws": "/aws-distro-opentelemetry-node-autoinstrumentation/register`\nin `NODE_OPTIONS` for Node.js). No Odigos code runs: the bootstrap switches are removed and the X-Ray\npropagator is dropped. ADOT cannot root an invocation at the agent, so AgentCore's service span stays\nmissing from the trace. Only `OdigosAgentCoreDistribution.ADOT` can be adopted."
|
|
3877
|
+
},
|
|
3878
|
+
"stability": "stable",
|
|
3879
|
+
"summary": "The artifact carries AWS Distro for OpenTelemetry only, started through its own launcher (`opentelemetry-instrument` for Python, `--require."
|
|
3880
|
+
},
|
|
3881
|
+
"name": "ADOPT"
|
|
3882
|
+
}
|
|
3883
|
+
],
|
|
3884
|
+
"name": "OdigosAgentCoreDelivery",
|
|
3885
|
+
"symbolId": "src/types:OdigosAgentCoreDelivery"
|
|
3886
|
+
},
|
|
3887
|
+
"@odigos/aws-cdk.OdigosAgentCoreDistribution": {
|
|
3888
|
+
"assembly": "@odigos/aws-cdk",
|
|
3889
|
+
"docs": {
|
|
3890
|
+
"remarks": "It must be the profile actually bundled into the artifact. The construct cannot see the artifact, so a\nmismatch is not caught at synth: the connector reports the runtime as non-conformant, and the runtime\nstarts the bootstrap for a profile that is not on disk.",
|
|
3891
|
+
"stability": "stable",
|
|
3892
|
+
"summary": "The OpenTelemetry SDK profile the AgentCore artifact was prepared with."
|
|
3893
|
+
},
|
|
3894
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreDistribution",
|
|
3895
|
+
"kind": "enum",
|
|
3896
|
+
"locationInModule": {
|
|
3897
|
+
"filename": "src/types.ts",
|
|
3898
|
+
"line": 155
|
|
3899
|
+
},
|
|
3900
|
+
"members": [
|
|
3901
|
+
{
|
|
3902
|
+
"docs": {
|
|
3903
|
+
"stability": "stable",
|
|
3904
|
+
"summary": "AWS Distro for OpenTelemetry — the connector's default profile for both languages."
|
|
3905
|
+
},
|
|
3906
|
+
"name": "ADOT"
|
|
3907
|
+
},
|
|
3908
|
+
{
|
|
3909
|
+
"docs": {
|
|
3910
|
+
"stability": "stable",
|
|
3911
|
+
"summary": "OpenLLMetry Bedrock instrumentation on the upstream OpenTelemetry SDK."
|
|
3912
|
+
},
|
|
3913
|
+
"name": "OPENLLMETRY"
|
|
3914
|
+
}
|
|
3915
|
+
],
|
|
3916
|
+
"name": "OdigosAgentCoreDistribution",
|
|
3917
|
+
"symbolId": "src/types:OdigosAgentCoreDistribution"
|
|
3918
|
+
},
|
|
3919
|
+
"@odigos/aws-cdk.OdigosAgentCoreInstrumentation": {
|
|
3920
|
+
"assembly": "@odigos/aws-cdk",
|
|
3921
|
+
"base": "constructs.Construct",
|
|
3922
|
+
"docs": {
|
|
3923
|
+
"remarks": "```ts\nnew OdigosAgentCoreInstrumentation(this, 'Odigos', {\n destination: { httpEndpoint: 'https://otlp.example.com:4318' },\n targets: [{ runtime, language: OdigosAgentCoreLanguage.PYTHON }],\n});\n```\n\n## What it does\n\nSets, through property overrides on the runtime's `EnvironmentVariables`, the exact environment the\nOdigos AWS connector expects for a manually instrumented runtime — the export settings, the SDK\nprofile selection, the `ODIGOS_AGENTCORE_PACKAGE` preparation contract and the `ODIGOS_IAC` marker —\nand removes the per-signal header variables, `ODIGOS_MANAGED`, and (when the destination has no\nheaders) `OTEL_EXPORTER_OTLP_HEADERS`. Variables the runtime already sets are kept.\n\n## What it does NOT do\n\nIt does not prepare the artifact. The Odigos SDK bundle and its bootstrap (`delivery: PACKAGE`), or ADOT\nand its launcher (`delivery: ADOPT`), must already be in the image or ZIP the runtime deploys; the\nenvironment alone installs nothing, and the construct does not write `NODE_OPTIONS`. See\nhttps://docs.odigos.io/cloud-connectors/aws/workloads/agentcore/prepare.\n\n## Do not also enable connector automatic mode for these runtimes\n\nThe connector refuses to manage a runtime carrying `ODIGOS_IAC`, and an IaC-owned runtime that the\nconnector also tries to own is reported as an error instead of being instrumented twice.",
|
|
3924
|
+
"stability": "stable",
|
|
3925
|
+
"summary": "Writes the Odigos environment recipe onto Amazon Bedrock AgentCore Runtimes."
|
|
3926
|
+
},
|
|
3927
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreInstrumentation",
|
|
3928
|
+
"initializer": {
|
|
3929
|
+
"docs": {
|
|
3930
|
+
"stability": "stable"
|
|
3931
|
+
},
|
|
3932
|
+
"locationInModule": {
|
|
3933
|
+
"filename": "src/agentcore.ts",
|
|
3934
|
+
"line": 121
|
|
3935
|
+
},
|
|
3936
|
+
"parameters": [
|
|
3937
|
+
{
|
|
3938
|
+
"name": "scope",
|
|
3939
|
+
"type": {
|
|
3940
|
+
"fqn": "constructs.Construct"
|
|
3941
|
+
}
|
|
3942
|
+
},
|
|
3943
|
+
{
|
|
3944
|
+
"name": "id",
|
|
3945
|
+
"type": {
|
|
3946
|
+
"primitive": "string"
|
|
3947
|
+
}
|
|
3948
|
+
},
|
|
3949
|
+
{
|
|
3950
|
+
"name": "props",
|
|
3951
|
+
"type": {
|
|
3952
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreInstrumentationProps"
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
]
|
|
3956
|
+
},
|
|
3957
|
+
"kind": "class",
|
|
3958
|
+
"locationInModule": {
|
|
3959
|
+
"filename": "src/agentcore.ts",
|
|
3960
|
+
"line": 115
|
|
3961
|
+
},
|
|
3962
|
+
"methods": [
|
|
3963
|
+
{
|
|
3964
|
+
"docs": {
|
|
3965
|
+
"remarks": "Idempotent — instrumenting the same runtime again is a no-op.",
|
|
3966
|
+
"stability": "stable",
|
|
3967
|
+
"summary": "Instruments one runtime."
|
|
3968
|
+
},
|
|
3969
|
+
"locationInModule": {
|
|
3970
|
+
"filename": "src/agentcore.ts",
|
|
3971
|
+
"line": 143
|
|
3972
|
+
},
|
|
3973
|
+
"name": "instrument",
|
|
3974
|
+
"parameters": [
|
|
3975
|
+
{
|
|
3976
|
+
"name": "target",
|
|
3977
|
+
"type": {
|
|
3978
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreTarget"
|
|
3979
|
+
}
|
|
3980
|
+
}
|
|
3981
|
+
]
|
|
3982
|
+
}
|
|
3983
|
+
],
|
|
3984
|
+
"name": "OdigosAgentCoreInstrumentation",
|
|
3985
|
+
"symbolId": "src/agentcore:OdigosAgentCoreInstrumentation"
|
|
3986
|
+
},
|
|
3987
|
+
"@odigos/aws-cdk.OdigosAgentCoreInstrumentationProps": {
|
|
3988
|
+
"assembly": "@odigos/aws-cdk",
|
|
3989
|
+
"datatype": true,
|
|
3990
|
+
"docs": {
|
|
3991
|
+
"stability": "stable",
|
|
3992
|
+
"summary": "Props for {@link OdigosAgentCoreInstrumentation}."
|
|
3993
|
+
},
|
|
3994
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreInstrumentationProps",
|
|
3995
|
+
"kind": "interface",
|
|
3996
|
+
"locationInModule": {
|
|
3997
|
+
"filename": "src/agentcore.ts",
|
|
3998
|
+
"line": 68
|
|
3999
|
+
},
|
|
4000
|
+
"name": "OdigosAgentCoreInstrumentationProps",
|
|
4001
|
+
"properties": [
|
|
4002
|
+
{
|
|
4003
|
+
"abstract": true,
|
|
4004
|
+
"docs": {
|
|
4005
|
+
"remarks": "AgentCore exports straight to a global OTLP/HTTP destination: `httpEndpoint` must be set, as a base\nURL with no per-signal `/v1/...` path, and `endpoint` (gRPC) must not be.",
|
|
4006
|
+
"stability": "stable",
|
|
4007
|
+
"summary": "Where the runtimes export telemetry to."
|
|
4008
|
+
},
|
|
4009
|
+
"immutable": true,
|
|
4010
|
+
"locationInModule": {
|
|
4011
|
+
"filename": "src/agentcore.ts",
|
|
4012
|
+
"line": 75
|
|
4013
|
+
},
|
|
4014
|
+
"name": "destination",
|
|
4015
|
+
"type": {
|
|
4016
|
+
"fqn": "@odigos/aws-cdk.OdigosDestination"
|
|
4017
|
+
}
|
|
4018
|
+
},
|
|
4019
|
+
{
|
|
4020
|
+
"abstract": true,
|
|
4021
|
+
"docs": {
|
|
4022
|
+
"default": "- none",
|
|
4023
|
+
"remarks": "More can be added with `instrument()`.",
|
|
4024
|
+
"stability": "stable",
|
|
4025
|
+
"summary": "Runtimes to instrument on construction."
|
|
4026
|
+
},
|
|
4027
|
+
"immutable": true,
|
|
4028
|
+
"locationInModule": {
|
|
4029
|
+
"filename": "src/agentcore.ts",
|
|
4030
|
+
"line": 82
|
|
4031
|
+
},
|
|
4032
|
+
"name": "targets",
|
|
4033
|
+
"optional": true,
|
|
4034
|
+
"type": {
|
|
4035
|
+
"collection": {
|
|
4036
|
+
"elementtype": {
|
|
4037
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreTarget"
|
|
4038
|
+
},
|
|
4039
|
+
"kind": "array"
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
],
|
|
4044
|
+
"symbolId": "src/agentcore:OdigosAgentCoreInstrumentationProps"
|
|
4045
|
+
},
|
|
4046
|
+
"@odigos/aws-cdk.OdigosAgentCoreLanguage": {
|
|
4047
|
+
"assembly": "@odigos/aws-cdk",
|
|
4048
|
+
"docs": {
|
|
4049
|
+
"remarks": "Stated rather than detected. A container artifact declares an image, and even a code artifact's runtime\nsays nothing about how the artifact was PREPARED — which is what this selects: the Odigos SDK profile\nbundled into the artifact. The values are the connector's canonical language keys, because they are\nwritten verbatim into `ODIGOS_AGENTCORE_PACKAGE` and the distro name the connector checks the runtime\nagainst.\n\nOnly Python 3.12 and CommonJS Node.js 22 artifacts are qualified. Native ESM Node.js applications need\nexplicit SDK initialization and are not covered by this recipe.",
|
|
4050
|
+
"stability": "stable",
|
|
4051
|
+
"summary": "The language of an Amazon Bedrock AgentCore Runtime's application."
|
|
4052
|
+
},
|
|
4053
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreLanguage",
|
|
4054
|
+
"kind": "enum",
|
|
4055
|
+
"locationInModule": {
|
|
4056
|
+
"filename": "src/types.ts",
|
|
4057
|
+
"line": 141
|
|
4058
|
+
},
|
|
4059
|
+
"members": [
|
|
4060
|
+
{
|
|
4061
|
+
"docs": {
|
|
4062
|
+
"stability": "stable",
|
|
4063
|
+
"summary": "Python (3.12)."
|
|
4064
|
+
},
|
|
4065
|
+
"name": "PYTHON"
|
|
4066
|
+
},
|
|
4067
|
+
{
|
|
4068
|
+
"docs": {
|
|
4069
|
+
"stability": "stable",
|
|
4070
|
+
"summary": "Node.js (22, CommonJS)."
|
|
4071
|
+
},
|
|
4072
|
+
"name": "NODEJS"
|
|
4073
|
+
}
|
|
4074
|
+
],
|
|
4075
|
+
"name": "OdigosAgentCoreLanguage",
|
|
4076
|
+
"symbolId": "src/types:OdigosAgentCoreLanguage"
|
|
4077
|
+
},
|
|
4078
|
+
"@odigos/aws-cdk.OdigosAgentCoreTarget": {
|
|
4079
|
+
"assembly": "@odigos/aws-cdk",
|
|
4080
|
+
"datatype": true,
|
|
4081
|
+
"docs": {
|
|
4082
|
+
"stability": "stable",
|
|
4083
|
+
"summary": "One AgentCore Runtime to instrument."
|
|
4084
|
+
},
|
|
4085
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreTarget",
|
|
4086
|
+
"kind": "interface",
|
|
4087
|
+
"locationInModule": {
|
|
4088
|
+
"filename": "src/agentcore.ts",
|
|
4089
|
+
"line": 22
|
|
4090
|
+
},
|
|
4091
|
+
"name": "OdigosAgentCoreTarget",
|
|
4092
|
+
"properties": [
|
|
4093
|
+
{
|
|
4094
|
+
"abstract": true,
|
|
4095
|
+
"docs": {
|
|
4096
|
+
"remarks": "Stated rather than detected: what matters is how the artifact was prepared, which the template does\nnot say.",
|
|
4097
|
+
"stability": "stable",
|
|
4098
|
+
"summary": "The language of the application, and of the Odigos SDK profile prepared into its artifact."
|
|
4099
|
+
},
|
|
4100
|
+
"immutable": true,
|
|
4101
|
+
"locationInModule": {
|
|
4102
|
+
"filename": "src/agentcore.ts",
|
|
4103
|
+
"line": 36
|
|
4104
|
+
},
|
|
4105
|
+
"name": "language",
|
|
4106
|
+
"type": {
|
|
4107
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreLanguage"
|
|
4108
|
+
}
|
|
4109
|
+
},
|
|
4110
|
+
{
|
|
4111
|
+
"abstract": true,
|
|
4112
|
+
"docs": {
|
|
4113
|
+
"stability": "stable",
|
|
4114
|
+
"summary": "The runtime: an `AWS::BedrockAgentCore::Runtime` `CfnResource` (an L1 `CfnRuntime`, a raw `CfnResource`, or a resource from `CfnInclude.getResource()`), or any construct whose `node.defaultChild` is one — such as the L2 `Runtime` in newer `aws-cdk-lib` releases."
|
|
4115
|
+
},
|
|
4116
|
+
"immutable": true,
|
|
4117
|
+
"locationInModule": {
|
|
4118
|
+
"filename": "src/agentcore.ts",
|
|
4119
|
+
"line": 28
|
|
4120
|
+
},
|
|
4121
|
+
"name": "runtime",
|
|
4122
|
+
"type": {
|
|
4123
|
+
"fqn": "constructs.IConstruct"
|
|
4124
|
+
}
|
|
4125
|
+
},
|
|
4126
|
+
{
|
|
4127
|
+
"abstract": true,
|
|
4128
|
+
"docs": {
|
|
4129
|
+
"default": "OdigosAgentCoreDelivery.PACKAGE",
|
|
4130
|
+
"remarks": "Must match how the artifact was prepared; `ADOPT` requires the ADOT\ndistribution and leaves AgentCore's own service span missing from the trace.",
|
|
4131
|
+
"stability": "stable",
|
|
4132
|
+
"summary": "How the artifact carries the SDK: the Odigos package or carrier bundle (`PACKAGE`), or AWS Distro for OpenTelemetry only (`ADOPT`)."
|
|
4133
|
+
},
|
|
4134
|
+
"immutable": true,
|
|
4135
|
+
"locationInModule": {
|
|
4136
|
+
"filename": "src/agentcore.ts",
|
|
4137
|
+
"line": 52
|
|
4138
|
+
},
|
|
4139
|
+
"name": "delivery",
|
|
4140
|
+
"optional": true,
|
|
4141
|
+
"type": {
|
|
4142
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreDelivery"
|
|
4143
|
+
}
|
|
4144
|
+
},
|
|
4145
|
+
{
|
|
4146
|
+
"abstract": true,
|
|
4147
|
+
"docs": {
|
|
4148
|
+
"default": "OdigosAgentCoreDistribution.ADOT",
|
|
4149
|
+
"remarks": "Must be the one actually bundled.",
|
|
4150
|
+
"stability": "stable",
|
|
4151
|
+
"summary": "The SDK profile prepared into the artifact."
|
|
4152
|
+
},
|
|
4153
|
+
"immutable": true,
|
|
4154
|
+
"locationInModule": {
|
|
4155
|
+
"filename": "src/agentcore.ts",
|
|
4156
|
+
"line": 43
|
|
4157
|
+
},
|
|
4158
|
+
"name": "distribution",
|
|
4159
|
+
"optional": true,
|
|
4160
|
+
"type": {
|
|
4161
|
+
"fqn": "@odigos/aws-cdk.OdigosAgentCoreDistribution"
|
|
4162
|
+
}
|
|
4163
|
+
},
|
|
4164
|
+
{
|
|
4165
|
+
"abstract": true,
|
|
4166
|
+
"docs": {
|
|
4167
|
+
"default": "- the runtime's `AgentRuntimeName`; required when that is not a literal string",
|
|
4168
|
+
"remarks": "THIS MUST MATCH THE WORKLOAD'S NAME IN ODIGOS, which for an AgentCore runtime is the runtime name\nunless a service name override is configured in Odigos. A different value is reported as drift.",
|
|
4169
|
+
"stability": "stable",
|
|
4170
|
+
"summary": "`OTEL_SERVICE_NAME` for this runtime."
|
|
4171
|
+
},
|
|
4172
|
+
"immutable": true,
|
|
4173
|
+
"locationInModule": {
|
|
4174
|
+
"filename": "src/agentcore.ts",
|
|
4175
|
+
"line": 62
|
|
4176
|
+
},
|
|
4177
|
+
"name": "serviceName",
|
|
4178
|
+
"optional": true,
|
|
4179
|
+
"type": {
|
|
4180
|
+
"primitive": "string"
|
|
4181
|
+
}
|
|
4182
|
+
}
|
|
4183
|
+
],
|
|
4184
|
+
"symbolId": "src/agentcore:OdigosAgentCoreTarget"
|
|
4185
|
+
},
|
|
3851
4186
|
"@odigos/aws-cdk.OdigosDestination": {
|
|
3852
4187
|
"assembly": "@odigos/aws-cdk",
|
|
3853
4188
|
"datatype": true,
|
|
@@ -3860,7 +4195,7 @@
|
|
|
3860
4195
|
"kind": "interface",
|
|
3861
4196
|
"locationInModule": {
|
|
3862
4197
|
"filename": "src/types.ts",
|
|
3863
|
-
"line":
|
|
4198
|
+
"line": 214
|
|
3864
4199
|
},
|
|
3865
4200
|
"name": "OdigosDestination",
|
|
3866
4201
|
"properties": [
|
|
@@ -3875,7 +4210,7 @@
|
|
|
3875
4210
|
"immutable": true,
|
|
3876
4211
|
"locationInModule": {
|
|
3877
4212
|
"filename": "src/types.ts",
|
|
3878
|
-
"line":
|
|
4213
|
+
"line": 223
|
|
3879
4214
|
},
|
|
3880
4215
|
"name": "endpoint",
|
|
3881
4216
|
"optional": true,
|
|
@@ -3894,7 +4229,7 @@
|
|
|
3894
4229
|
"immutable": true,
|
|
3895
4230
|
"locationInModule": {
|
|
3896
4231
|
"filename": "src/types.ts",
|
|
3897
|
-
"line":
|
|
4232
|
+
"line": 255
|
|
3898
4233
|
},
|
|
3899
4234
|
"name": "headers",
|
|
3900
4235
|
"optional": true,
|
|
@@ -3917,7 +4252,7 @@
|
|
|
3917
4252
|
"immutable": true,
|
|
3918
4253
|
"locationInModule": {
|
|
3919
4254
|
"filename": "src/types.ts",
|
|
3920
|
-
"line":
|
|
4255
|
+
"line": 230
|
|
3921
4256
|
},
|
|
3922
4257
|
"name": "httpEndpoint",
|
|
3923
4258
|
"optional": true,
|
|
@@ -3936,7 +4271,7 @@
|
|
|
3936
4271
|
"immutable": true,
|
|
3937
4272
|
"locationInModule": {
|
|
3938
4273
|
"filename": "src/types.ts",
|
|
3939
|
-
"line":
|
|
4274
|
+
"line": 239
|
|
3940
4275
|
},
|
|
3941
4276
|
"name": "insecure",
|
|
3942
4277
|
"optional": true,
|
|
@@ -3955,7 +4290,7 @@
|
|
|
3955
4290
|
"immutable": true,
|
|
3956
4291
|
"locationInModule": {
|
|
3957
4292
|
"filename": "src/types.ts",
|
|
3958
|
-
"line":
|
|
4293
|
+
"line": 292
|
|
3959
4294
|
},
|
|
3960
4295
|
"name": "logs",
|
|
3961
4296
|
"optional": true,
|
|
@@ -3974,7 +4309,7 @@
|
|
|
3974
4309
|
"immutable": true,
|
|
3975
4310
|
"locationInModule": {
|
|
3976
4311
|
"filename": "src/types.ts",
|
|
3977
|
-
"line":
|
|
4312
|
+
"line": 281
|
|
3978
4313
|
},
|
|
3979
4314
|
"name": "metrics",
|
|
3980
4315
|
"optional": true,
|
|
@@ -3993,7 +4328,7 @@
|
|
|
3993
4328
|
"immutable": true,
|
|
3994
4329
|
"locationInModule": {
|
|
3995
4330
|
"filename": "src/types.ts",
|
|
3996
|
-
"line":
|
|
4331
|
+
"line": 299
|
|
3997
4332
|
},
|
|
3998
4333
|
"name": "profiles",
|
|
3999
4334
|
"optional": true,
|
|
@@ -4012,7 +4347,7 @@
|
|
|
4012
4347
|
"immutable": true,
|
|
4013
4348
|
"locationInModule": {
|
|
4014
4349
|
"filename": "src/types.ts",
|
|
4015
|
-
"line":
|
|
4350
|
+
"line": 269
|
|
4016
4351
|
},
|
|
4017
4352
|
"name": "traces",
|
|
4018
4353
|
"optional": true,
|
|
@@ -4984,6 +5319,6 @@
|
|
|
4984
5319
|
"symbolId": "src/types:OdigosLayerSource"
|
|
4985
5320
|
}
|
|
4986
5321
|
},
|
|
4987
|
-
"version": "0.0.
|
|
4988
|
-
"fingerprint": "
|
|
5322
|
+
"version": "0.0.22",
|
|
5323
|
+
"fingerprint": "ZigYwf16i5IKqTc0NYkE2hhn7uppDLFGvTaVaCHlfjQ="
|
|
4989
5324
|
}
|