@odigos/aws-cdk 0.0.13 → 0.0.14
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 +415 -13
- package/README.md +206 -6
- package/lib/fargate-recipes.d.ts +108 -0
- package/lib/fargate-recipes.js +231 -0
- package/lib/fargate.d.ts +218 -0
- package/lib/fargate.js +400 -0
- package/lib/generated/fargate.d.ts +44 -0
- package/lib/generated/fargate.js +125 -0
- package/lib/generated/layers.d.ts +4 -4
- package/lib/generated/layers.js +149 -149
- 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 +51 -0
- package/lib/types.js +41 -2
- package/package.json +2 -2
package/lib/fargate.d.ts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { OdigosDestination, OdigosFargateLanguage } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Options shared by every container this construct instruments.
|
|
6
|
+
*/
|
|
7
|
+
export interface OdigosFargateInstrumentationOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Where the instrumented containers export telemetry to.
|
|
10
|
+
*
|
|
11
|
+
* Unlike Lambda, BOTH transports may be set and often should be: a Fargate task has no collector of its
|
|
12
|
+
* own, so each language's agent exports to this destination itself and takes the transport it prefers.
|
|
13
|
+
* php and ruby can only speak OTLP/HTTP at all.
|
|
14
|
+
*/
|
|
15
|
+
readonly destination: OdigosDestination;
|
|
16
|
+
/**
|
|
17
|
+
* The agents bundle the staging container copies the language agents out of.
|
|
18
|
+
*
|
|
19
|
+
* Defaults to the multi-arch image this package's release published, at that release's immutable tag.
|
|
20
|
+
* Override it to mirror the image into a registry your tasks can reach — the image is pulled by YOUR
|
|
21
|
+
* task's execution role at every task start, so a task in a private subnet with no NAT and no
|
|
22
|
+
* interface endpoint cannot pull the default.
|
|
23
|
+
*
|
|
24
|
+
* A mirror must be the same bundle: the activation environment set below names exact paths inside it.
|
|
25
|
+
*
|
|
26
|
+
* @default - the released `registry.odigos.io/odigos-fargate-agents` image for this package version
|
|
27
|
+
*/
|
|
28
|
+
readonly agentsImage?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Raise agent verbosity (`OTEL_LOG_LEVEL=debug`) on every instrumented container.
|
|
31
|
+
*
|
|
32
|
+
* Useful while wiring up a destination, expensive to leave on — and it is compared: the connector
|
|
33
|
+
* expects the variable ABSENT unless debug telemetry is enabled for the connector too, so leaving this
|
|
34
|
+
* on can itself be reported as drift.
|
|
35
|
+
*
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
readonly debug?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* One container to instrument.
|
|
42
|
+
*/
|
|
43
|
+
export interface OdigosFargateTarget {
|
|
44
|
+
/**
|
|
45
|
+
* The application container. Its task definition is taken from it, so the staging container, the shared
|
|
46
|
+
* volume and the startup dependency are added to the right one automatically.
|
|
47
|
+
*/
|
|
48
|
+
readonly container: ecs.ContainerDefinition;
|
|
49
|
+
/**
|
|
50
|
+
* The language whose agent to stage and activate.
|
|
51
|
+
*
|
|
52
|
+
* Stated rather than detected — a container declares an image, not a runtime, and resolving a language
|
|
53
|
+
* from an image means pulling it.
|
|
54
|
+
*/
|
|
55
|
+
readonly language: OdigosFargateLanguage;
|
|
56
|
+
/**
|
|
57
|
+
* `OTEL_SERVICE_NAME` for this container.
|
|
58
|
+
*
|
|
59
|
+
* THIS MUST MATCH THE WORKLOAD'S NAME IN ODIGOS, which for a Fargate workload is the ECS SERVICE name —
|
|
60
|
+
* not the task definition family and not the container name. A different value is reported as
|
|
61
|
+
* instrumentation drift rather than treated as a naming preference.
|
|
62
|
+
*
|
|
63
|
+
* Pass `service` instead to read it off the service, or set this when the service is defined elsewhere
|
|
64
|
+
* (a different stack, Terraform, the console). One of the two is required.
|
|
65
|
+
*
|
|
66
|
+
* @default - taken from `service`
|
|
67
|
+
*/
|
|
68
|
+
readonly serviceName?: string;
|
|
69
|
+
/**
|
|
70
|
+
* The ECS service that runs this task definition, used only to read its name.
|
|
71
|
+
*
|
|
72
|
+
* Its physical name has to be one your stack SET, not one CloudFormation generates: a generated name is
|
|
73
|
+
* a `Ref` to the service, and a service's own task definition referencing it is a dependency cycle
|
|
74
|
+
* CloudFormation rejects at deploy time. A generated name throws at synth pointing at `serviceName`.
|
|
75
|
+
*
|
|
76
|
+
* @default - `serviceName` must be given instead
|
|
77
|
+
*/
|
|
78
|
+
readonly service?: ecs.BaseService;
|
|
79
|
+
/**
|
|
80
|
+
* The application's runtime version as `major.minor` — for example `"8.3"`.
|
|
81
|
+
*
|
|
82
|
+
* Required for php and ruby, whose agents are laid down per runtime version in the bundle, and the
|
|
83
|
+
* version selects the path their activation variables point at. Ignored by every other language.
|
|
84
|
+
*
|
|
85
|
+
* @default - none; required for php and ruby
|
|
86
|
+
*/
|
|
87
|
+
readonly runtimeVersion?: string;
|
|
88
|
+
/**
|
|
89
|
+
* The value this container already needs in its loader variable (`JAVA_TOOL_OPTIONS`, `NODE_OPTIONS` or
|
|
90
|
+
* `PYTHONPATH`), which the Odigos fragment is joined to rather than replacing.
|
|
91
|
+
*
|
|
92
|
+
* Only needed as an OVERRIDE. The construct reads the value the container was created with and appends
|
|
93
|
+
* to it, so a container that sets its own `JAVA_TOOL_OPTIONS` in `addContainer` keeps it. Pass this when
|
|
94
|
+
* the value is not visible at synth — set by an `environmentFiles` entry, injected by the image's own
|
|
95
|
+
* `ENV`, or supplied through `secrets`.
|
|
96
|
+
*
|
|
97
|
+
* @default - read from the container's own environment
|
|
98
|
+
*/
|
|
99
|
+
readonly existingLoaderValue?: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Props for {@link OdigosFargateInstrumentation}.
|
|
103
|
+
*/
|
|
104
|
+
export interface OdigosFargateInstrumentationProps extends OdigosFargateInstrumentationOptions {
|
|
105
|
+
/**
|
|
106
|
+
* Containers to instrument on construction. More can be added with `instrument()`.
|
|
107
|
+
*
|
|
108
|
+
* @default - none
|
|
109
|
+
*/
|
|
110
|
+
readonly targets?: OdigosFargateTarget[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Instruments ECS Fargate containers with the Odigos OpenTelemetry agents.
|
|
114
|
+
*
|
|
115
|
+
* ```ts
|
|
116
|
+
* const odigos = new OdigosFargateInstrumentation(this, 'Odigos', {
|
|
117
|
+
* destination: { httpEndpoint: 'https://otlp.example.com:4318' },
|
|
118
|
+
* });
|
|
119
|
+
* odigos.instrument({
|
|
120
|
+
* container: apiContainer,
|
|
121
|
+
* language: OdigosFargateLanguage.JAVA,
|
|
122
|
+
* service: apiService,
|
|
123
|
+
* });
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* ## What it does to the task definition
|
|
127
|
+
*
|
|
128
|
+
* Four moves, which are one mechanism and only work together — the ECS adaptation of the Odikos
|
|
129
|
+
* init-container mount method:
|
|
130
|
+
*
|
|
131
|
+
* 1. a bare-name task volume (`odigos-agent`), which on Fargate is an ephemeral-storage bind mount
|
|
132
|
+
* scoped to the task;
|
|
133
|
+
* 2. a NON-ESSENTIAL `odigos-agent` container that copies the language agents out of the agents bundle
|
|
134
|
+
* into that volume and exits 0;
|
|
135
|
+
* 3. the volume mounted read-only at `/var/odigos` in each instrumented container, which depends on the
|
|
136
|
+
* staging container with condition `SUCCESS` — only valid against a non-essential container, which is
|
|
137
|
+
* why (2) is non-essential;
|
|
138
|
+
* 4. the language's activation environment, the OTLP export environment, and the `ODIGOS_IAC` marker on
|
|
139
|
+
* each instrumented container.
|
|
140
|
+
*
|
|
141
|
+
* There is ONE staging container per task definition however many languages the task holds; its command
|
|
142
|
+
* is the union of every instrumented container's agent directories, and it is built lazily so containers
|
|
143
|
+
* instrumented later are included.
|
|
144
|
+
*
|
|
145
|
+
* ## Where the telemetry goes
|
|
146
|
+
*
|
|
147
|
+
* Straight to your destination, from inside the application process. This is the substantive difference
|
|
148
|
+
* from Lambda: there is no collector in the task to hand a batch to, so a slow or unreachable destination
|
|
149
|
+
* is felt by the application's own exporter rather than absorbed after a response has been returned.
|
|
150
|
+
*
|
|
151
|
+
* ## What it deliberately does NOT do
|
|
152
|
+
*
|
|
153
|
+
* There is no aspect that sweeps a scope, as there is for Lambda. An aspect there works because a
|
|
154
|
+
* function DECLARES its runtime; a container declares an image, and a language guessed from an image name
|
|
155
|
+
* would silently mis-instrument the ones it got wrong — staging a Java agent into a Python container
|
|
156
|
+
* leaves it uninstrumented, and a `JAVA_TOOL_OPTIONS` on a JVM-less image is simply ignored, so nothing
|
|
157
|
+
* fails loudly enough to notice.
|
|
158
|
+
*
|
|
159
|
+
* ## Do not also instrument these services with the connector
|
|
160
|
+
*
|
|
161
|
+
* The connector instruments live services by registering a new task-definition revision and updating the
|
|
162
|
+
* service to it, reconciling to its own desired state on every pass. A service instrumented here and also
|
|
163
|
+
* enabled as a connector source ends up owned by both: each `cdk deploy` reasserts the stack's
|
|
164
|
+
* definition, each reconcile reasserts the connector's, and every round trip registers a revision and
|
|
165
|
+
* rolls the service. Choose one per service.
|
|
166
|
+
*/
|
|
167
|
+
export declare class OdigosFargateInstrumentation extends Construct {
|
|
168
|
+
private readonly options;
|
|
169
|
+
private readonly agentsImage;
|
|
170
|
+
private readonly taskDefinitions;
|
|
171
|
+
private readonly instrumented;
|
|
172
|
+
constructor(scope: Construct, id: string, props: OdigosFargateInstrumentationProps);
|
|
173
|
+
/**
|
|
174
|
+
* Instruments one container. Idempotent — instrumenting the same container twice is a no-op rather than
|
|
175
|
+
* a doubled loader value.
|
|
176
|
+
*/
|
|
177
|
+
instrument(target: OdigosFargateTarget): void;
|
|
178
|
+
/** Instruments every target in the list. */
|
|
179
|
+
instrumentAll(targets: OdigosFargateTarget[]): void;
|
|
180
|
+
/**
|
|
181
|
+
* The task definition's staging container and volume, created once and shared by every container in it.
|
|
182
|
+
*
|
|
183
|
+
* The command is a lazy list rather than a literal because the union it renders is not known until
|
|
184
|
+
* synthesis: a task definition holding a Java and a Python application is instrumented by two
|
|
185
|
+
* `instrument()` calls, and the single staging container has to stage both. The connector compares this
|
|
186
|
+
* command against exactly that union, so a stale one is reported as drift on the whole task definition
|
|
187
|
+
* and leaves one of the containers with no agent on disk.
|
|
188
|
+
*/
|
|
189
|
+
private taskDefinitionState;
|
|
190
|
+
/**
|
|
191
|
+
* `OTEL_SERVICE_NAME` for a target, and the one value a caller cannot be allowed to leave to a default.
|
|
192
|
+
*
|
|
193
|
+
* The connector compares it against the workload's name in Odigos, which is the ECS SERVICE name, so
|
|
194
|
+
* guessing — the task definition family, the container name, the construct id — would produce a stack
|
|
195
|
+
* that deploys cleanly and then reports as drifted on a component nothing in the stack makes visible.
|
|
196
|
+
*
|
|
197
|
+
* Read from the L1, not from `service.serviceName`: the L2 property is a token that resolves to a `Ref`
|
|
198
|
+
* to the service even when the stack set the name explicitly, and a `Ref` here is worse than useless —
|
|
199
|
+
* the task definition would reference the service that references it, which CloudFormation rejects as a
|
|
200
|
+
* dependency cycle at deploy time.
|
|
201
|
+
*/
|
|
202
|
+
private resolveServiceName;
|
|
203
|
+
/**
|
|
204
|
+
* Checks the task definition can carry the staged-agent method at all, and warns about the things that
|
|
205
|
+
* are legal but almost certainly a mistake.
|
|
206
|
+
*/
|
|
207
|
+
private checkTaskDefinition;
|
|
208
|
+
/**
|
|
209
|
+
* The environment applied to one instrumented container.
|
|
210
|
+
*
|
|
211
|
+
* Mirrors `instrumentContainer` in the connector, including the ORDER of decisions: the agent's own
|
|
212
|
+
* activation variables first, then identity, then export, then the marker. Every variable here has a
|
|
213
|
+
* counterpart in the connector's `containerDiff`, which is what a customer's conformance report is
|
|
214
|
+
* built from — so one that is absent, or spelled differently, is reported as a named broken component
|
|
215
|
+
* rather than passing quietly.
|
|
216
|
+
*/
|
|
217
|
+
private environmentFor;
|
|
218
|
+
}
|