@composurecdk/lambda 0.10.0 → 0.10.1
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/README.md +175 -0
- package/dist/commonjs/function-builder.d.ts +76 -5
- package/dist/commonjs/function-builder.d.ts.map +1 -1
- package/dist/commonjs/function-builder.js +56 -2
- package/dist/commonjs/function-builder.js.map +1 -1
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +4 -1
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/invoke-on-deploy.d.ts +83 -0
- package/dist/commonjs/invoke-on-deploy.d.ts.map +1 -0
- package/dist/commonjs/invoke-on-deploy.js +155 -0
- package/dist/commonjs/invoke-on-deploy.js.map +1 -0
- package/dist/esm/function-builder.d.ts +76 -5
- package/dist/esm/function-builder.d.ts.map +1 -1
- package/dist/esm/function-builder.js +57 -3
- package/dist/esm/function-builder.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/invoke-on-deploy.d.ts +83 -0
- package/dist/esm/invoke-on-deploy.d.ts.map +1 -0
- package/dist/esm/invoke-on-deploy.js +151 -0
- package/dist/esm/invoke-on-deploy.js.map +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -49,6 +49,32 @@ const handler = createFunctionBuilder()
|
|
|
49
49
|
.build(stack, "MyFunction");
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
## Environment variables
|
|
53
|
+
|
|
54
|
+
Each **value** in `.environment(...)` is independently `Resolvable`, so a variable can carry a sibling's output while the rest stay literal:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { compose, ref } from "@composurecdk/core";
|
|
58
|
+
import { createRestApiBuilder, type RestApiBuilderResult } from "@composurecdk/apigateway";
|
|
59
|
+
|
|
60
|
+
compose(
|
|
61
|
+
{
|
|
62
|
+
api: createRestApiBuilder().restApiName("Orders"),
|
|
63
|
+
worker: createFunctionBuilder()
|
|
64
|
+
.runtime(Runtime.NODEJS_22_X)
|
|
65
|
+
.handler("index.handler")
|
|
66
|
+
.code(Code.fromAsset("lambda"))
|
|
67
|
+
.environment({
|
|
68
|
+
API_URL: ref("api", (r: RestApiBuilderResult) => r.api.url),
|
|
69
|
+
LOG_LEVEL: "info",
|
|
70
|
+
}),
|
|
71
|
+
},
|
|
72
|
+
{ api: [], worker: ["api"] },
|
|
73
|
+
);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Per value rather than over the whole record, because mixing the two is the common case: wrapping the record would push every literal through the same `ref`, and through [`combine`](../core/README.md) as soon as two siblings are involved.
|
|
77
|
+
|
|
52
78
|
## Environment variable encryption
|
|
53
79
|
|
|
54
80
|
Lambda encrypts environment variables at rest with an AWS-managed key. `.environmentEncryption(...)` opts into a customer-managed one, and accepts a concrete key or a `Resolvable`, so a key built by [`@composurecdk/kms`](../kms/README.md) can be a component of the same system rather than a construct created before `compose`:
|
|
@@ -402,6 +428,155 @@ today (the queue often arrives as an unresolved `ref()`); they are tracked in
|
|
|
402
428
|
`kinesisEventSource` is still deferred — see
|
|
403
429
|
[#120](https://github.com/laazyj/composureCDK/issues/120).
|
|
404
430
|
|
|
431
|
+
## Deploy-time invocation: `.invokeOnDeploy()`
|
|
432
|
+
|
|
433
|
+
Some work has to happen _as part of shipping the stack_, and its outcome has to
|
|
434
|
+
gate the deployment: registering the release with an external service, calling
|
|
435
|
+
the system you just deployed to prove it answers, seeding reference data through
|
|
436
|
+
a service API. `.invokeOnDeploy()` invokes the function once during deployment
|
|
437
|
+
and **fails the deployment if the function fails** — the stack rolls back and
|
|
438
|
+
the handler's error message lands in the CloudFormation events.
|
|
439
|
+
|
|
440
|
+
```ts
|
|
441
|
+
import { compose, ref } from "@composurecdk/core";
|
|
442
|
+
import { createFunctionBuilder } from "@composurecdk/lambda";
|
|
443
|
+
|
|
444
|
+
compose(
|
|
445
|
+
{
|
|
446
|
+
register: createFunctionBuilder()
|
|
447
|
+
.runtime(Runtime.NODEJS_22_X)
|
|
448
|
+
.handler("index.handler")
|
|
449
|
+
.code(Code.fromAsset("register"))
|
|
450
|
+
.timeout(Duration.seconds(30))
|
|
451
|
+
.environment({ API_URL: "https://releases.example.com/v1/register" })
|
|
452
|
+
.invokeOnDeploy({ after: [ref("api", (r: RestApiBuilderResult) => r.api)] }),
|
|
453
|
+
|
|
454
|
+
api: createRestApiBuilder().restApiName("Orders"),
|
|
455
|
+
},
|
|
456
|
+
{ api: [], register: ["api"] },
|
|
457
|
+
).build(stack, "Release");
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### What it is
|
|
461
|
+
|
|
462
|
+
If you already write CDK custom resources, the whole mental model is one
|
|
463
|
+
sentence: **it is CDK's
|
|
464
|
+
[`triggers.Trigger`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.triggers-readme.html),
|
|
465
|
+
with the synchronous invocation fixed and the wait and ordering derived from the
|
|
466
|
+
function.** Everything below is detail on those defaults.
|
|
467
|
+
|
|
468
|
+
Worth stating plainly, because the other two tools look right and are not.
|
|
469
|
+
`custom_resources.Provider` wants a handler of yours that speaks the
|
|
470
|
+
CloudFormation custom-resource protocol. `AwsCustomResource` runs one fixed SDK
|
|
471
|
+
call with no handler of yours — and reaching for `Lambda.invoke` there
|
|
472
|
+
[reports success when your handler fails](../custom-resources/README.md).
|
|
473
|
+
`Trigger` is the one that invokes a plain handler and fails the stack on an
|
|
474
|
+
error, and it is the least known of the three.
|
|
475
|
+
|
|
476
|
+
It is a domain action on the function builder
|
|
477
|
+
([ADR-0016](../../docs/adr/0016-domain-action-custom-resource.md)): you declare
|
|
478
|
+
the intent, the builder owns the invocation semantics, the wait derivation, the
|
|
479
|
+
execution-role ordering and the IAM. The custom resource is exposed on the build
|
|
480
|
+
result as `deploymentTrigger`, so a sibling can be ordered against the call
|
|
481
|
+
itself (`deploymentTrigger.executeBefore(...)`).
|
|
482
|
+
|
|
483
|
+
Three things reach the template:
|
|
484
|
+
|
|
485
|
+
- **A `Custom::Trigger`**, carrying the handler ARN, the invocation type, the
|
|
486
|
+
wait, and `ExecuteOnHandlerChange`.
|
|
487
|
+
- **A trigger provider Lambda and its role** — one per stack, shared by every
|
|
488
|
+
`Trigger` in it, created by CDK rather than by this builder.
|
|
489
|
+
- **An `AWS::Lambda::Version` of your function.** `Trigger` addresses the handler
|
|
490
|
+
by its `currentVersion`, so calling `.invokeOnDeploy()` publishes a version —
|
|
491
|
+
unconditionally, including under `executeOnHandlerChange: false`. That is the
|
|
492
|
+
re-invocation mechanism rather than an accident: the version ARN changes when
|
|
493
|
+
the function's code or configuration does, and that property change is what
|
|
494
|
+
CloudFormation acts on.
|
|
495
|
+
|
|
496
|
+
### The handler must throw
|
|
497
|
+
|
|
498
|
+
**A handler that returns an error rather than throwing does not fail the
|
|
499
|
+
deployment.** Lambda considers an invocation that returns successful no matter
|
|
500
|
+
what the payload says, so an HTTP-shaped `{ statusCode: 500 }` — or a caught
|
|
501
|
+
error folded into the response — deploys green:
|
|
502
|
+
|
|
503
|
+
```ts
|
|
504
|
+
export const handler = async () => {
|
|
505
|
+
const response = await fetch(process.env.API_URL, { method: "POST" });
|
|
506
|
+
if (!response.ok) {
|
|
507
|
+
// Throw. Returning `{ statusCode: response.status }` here would deploy green.
|
|
508
|
+
throw new Error(`Registration failed: ${response.status} ${await response.text()}`);
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Ordering
|
|
514
|
+
|
|
515
|
+
The function's own execution role is always waited for, so the policies attached
|
|
516
|
+
_to it_ by `.grant()` and `.configureRole()` exist before the handler runs —
|
|
517
|
+
CloudFormation does not otherwise sequence those ahead of a custom resource, and
|
|
518
|
+
the handler would race them.
|
|
519
|
+
|
|
520
|
+
That covers the **identity** half of a grant, which is not always the whole
|
|
521
|
+
grant. `grantDecrypt` on a KMS key, or a cross-account bucket grant, also writes
|
|
522
|
+
a **resource** policy, and that half lives in the granting resource's own tree
|
|
523
|
+
where this ordering does not reach. If the handler needs it at deploy time, name
|
|
524
|
+
that resource in `after`.
|
|
525
|
+
|
|
526
|
+
Everything else the call depends on goes in `after` as well. It takes any
|
|
527
|
+
[`DependencySource`](../core/README.md#ordering-adddependencies) — the same
|
|
528
|
+
shapes as `dependsOn` in
|
|
529
|
+
[`@composurecdk/custom-resources`](../custom-resources/README.md).
|
|
530
|
+
|
|
531
|
+
One caveat on "always": a role supplied with `.role(Role.fromRoleArn(...))`
|
|
532
|
+
contributes no resources to the template, so there is nothing to sequence and
|
|
533
|
+
the wait is a no-op. Nothing is lost — an imported role's policies were never
|
|
534
|
+
this stack's to create — but do not read it as a guarantee that they are in
|
|
535
|
+
place.
|
|
536
|
+
|
|
537
|
+
### Defaults
|
|
538
|
+
|
|
539
|
+
| Option | Default | Rationale |
|
|
540
|
+
| ------------------------ | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
541
|
+
| invocation type | `RequestResponse` (not settable) | The deployment waits for the result. An asynchronous invocation returns before the work happens, reporting success whatever the handler did — the opposite of the point. |
|
|
542
|
+
| `timeout` | function `timeout` + 30s | The deployment outlives the handler, so a handler that runs to its limit reports _its_ error ("Task timed out after …") instead of the deployment abandoning the call. Capped at 14m30s. |
|
|
543
|
+
| `executeOnHandlerChange` | `true` | Re-invokes when the handler's code or configuration changes; a no-op on unrelated stack updates. |
|
|
544
|
+
|
|
545
|
+
The derivation values are exported as `INVOKE_ON_DEPLOY_DEFAULTS`. With no
|
|
546
|
+
function `timeout` set (or a token one), the wait falls back to 2 minutes,
|
|
547
|
+
matching CDK's own `Trigger` default.
|
|
548
|
+
|
|
549
|
+
Whenever the wait ends up at or below the function's own timeout, a suppressible
|
|
550
|
+
warning fires under `INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID` — the deployment would
|
|
551
|
+
stop waiting while the handler is still running, so a slow call fails the stack
|
|
552
|
+
as an abandoned invocation rather than reporting the handler's error. That
|
|
553
|
+
covers an explicit `timeout` set too low, and also a function timeout at or
|
|
554
|
+
above the 14m30s cap, where the cap leaves no margin to add.
|
|
555
|
+
|
|
556
|
+
The cap is not Lambda's 15-minute ceiling but CDK's trigger provider: that
|
|
557
|
+
provider runs with a 15-minute Lambda timeout of its own and `Trigger` sets no
|
|
558
|
+
`ServiceTimeout` on the custom resource, so a provider that dies mid-wait posts
|
|
559
|
+
nothing back and CloudFormation is never told. The result is a **hung**
|
|
560
|
+
deployment, not a failed one. `.invokeOnDeploy()` therefore **throws** on an
|
|
561
|
+
explicit `timeout` above the cap rather than clamping it, and keeps 30s in hand
|
|
562
|
+
on the derived path so the provider outlives the call it is waiting on.
|
|
563
|
+
|
|
564
|
+
### What it does not do
|
|
565
|
+
|
|
566
|
+
- **It does not invoke on every deployment.** With `executeOnHandlerChange: true`
|
|
567
|
+
the invocation re-runs when the handler changes; with `false` it runs only on
|
|
568
|
+
the stack's first deployment. CDK's `Trigger` offers no "always" mode.
|
|
569
|
+
- **It does not invoke on stack deletion.** For teardown-time work, use
|
|
570
|
+
[`@composurecdk/custom-resources`](../custom-resources/README.md), which has
|
|
571
|
+
create/update/**delete** semantics.
|
|
572
|
+
- **It creates no alarms.** The custom resource runs once per deployment, not
|
|
573
|
+
continuously; there is no steady-state signal to alarm on. Failures surface as
|
|
574
|
+
a failed deployment.
|
|
575
|
+
- **It is not a general SDK-call escape hatch.** A call that has no
|
|
576
|
+
CloudFormation resource but needs no handler of yours belongs in
|
|
577
|
+
`createAwsCustomResourceBuilder()` — that builder invokes an AWS API directly,
|
|
578
|
+
no Lambda of yours involved.
|
|
579
|
+
|
|
405
580
|
## Examples
|
|
406
581
|
|
|
407
582
|
- [DualFunctionStack](../examples/src/dual-function-app.ts) — Two Lambda functions with recommended alarms, custom alarms, and SNS alarm actions
|
|
@@ -2,6 +2,7 @@ import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
|
2
2
|
import { type IGrantable, type IRole } from "aws-cdk-lib/aws-iam";
|
|
3
3
|
import { Function as LambdaFunction, type FunctionProps, type IEventSource } from "aws-cdk-lib/aws-lambda";
|
|
4
4
|
import type { LogGroup } from "aws-cdk-lib/aws-logs";
|
|
5
|
+
import type { Trigger } from "aws-cdk-lib/triggers";
|
|
5
6
|
import { type IConstruct } from "constructs";
|
|
6
7
|
import { COPY_STATE, type Grant, type Lifecycle, type Resolvable } from "@composurecdk/core";
|
|
7
8
|
import { type ITaggedBuilder } from "@composurecdk/cloudformation";
|
|
@@ -9,16 +10,18 @@ import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
|
9
10
|
import { type IRoleBuilder } from "@composurecdk/iam";
|
|
10
11
|
import type { FunctionAlarmConfig } from "./alarm-config.js";
|
|
11
12
|
import { type ComposureEventSource } from "./event-sources/composure-event-source.js";
|
|
13
|
+
import { type InvokeOnDeployOptions } from "./invoke-on-deploy.js";
|
|
12
14
|
/**
|
|
13
15
|
* Configuration properties for the Lambda function builder.
|
|
14
16
|
*
|
|
15
17
|
* Extends the CDK {@link FunctionProps} with builder-specific options. The
|
|
16
|
-
* `role` and `environmentEncryption`
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* `role` and `environmentEncryption` are widened to {@link Resolvable}, and
|
|
19
|
+
* `environment` to a record of `Resolvable` values, so a role, key or value
|
|
20
|
+
* built by a sibling component can be referenced via `ref(...)` at
|
|
21
|
+
* configuration time. Each reads its inner type from CDK's own prop so they
|
|
22
|
+
* keep tracking it (ADR-0018).
|
|
20
23
|
*/
|
|
21
|
-
export interface FunctionBuilderProps extends Omit<FunctionProps, "role" | "environmentEncryption"> {
|
|
24
|
+
export interface FunctionBuilderProps extends Omit<FunctionProps, "role" | "environmentEncryption" | "environment"> {
|
|
22
25
|
/**
|
|
23
26
|
* The IAM execution role to attach to the function. When set, the builder
|
|
24
27
|
* skips creating its own role and the auto-created `LogsWriter` inline
|
|
@@ -52,6 +55,20 @@ export interface FunctionBuilderProps extends Omit<FunctionProps, "role" | "envi
|
|
|
52
55
|
* @see https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-encryption
|
|
53
56
|
*/
|
|
54
57
|
environmentEncryption?: Resolvable<NonNullable<FunctionProps["environmentEncryption"]>>;
|
|
58
|
+
/**
|
|
59
|
+
* Key-value pairs the function can read from `process.env` (e.g.
|
|
60
|
+
* `.environment({ API_URL: ref("api", (r) => r.api.url), LOG_LEVEL: "info" })`).
|
|
61
|
+
*
|
|
62
|
+
* Each **value** is independently {@link Resolvable}, rather than the record
|
|
63
|
+
* as a whole, because mixing a reference with literals is the common case:
|
|
64
|
+
* wrapping the record would push every literal through the same `ref`, and
|
|
65
|
+
* through {@link combine} as soon as two siblings are involved. Matches
|
|
66
|
+
* `validationZones` in `@composurecdk/acm`.
|
|
67
|
+
*
|
|
68
|
+
* The value type is read from CDK's own prop rather than written as `string`,
|
|
69
|
+
* so it tracks `aws-cdk-lib` (ADR-0018).
|
|
70
|
+
*/
|
|
71
|
+
environment?: Record<string, Resolvable<NonNullable<FunctionProps["environment"]>[string]>>;
|
|
55
72
|
/**
|
|
56
73
|
* Configuration for AWS-recommended CloudWatch alarms.
|
|
57
74
|
*
|
|
@@ -131,6 +148,18 @@ export interface FunctionBuilderResult {
|
|
|
131
148
|
* Always present — `{}` when no event sources were added.
|
|
132
149
|
*/
|
|
133
150
|
eventSources: Record<string, IEventSource>;
|
|
151
|
+
/**
|
|
152
|
+
* The custom resource that invokes the function during deployment, or
|
|
153
|
+
* `undefined` unless {@link IFunctionBuilder.invokeOnDeploy} was called.
|
|
154
|
+
*
|
|
155
|
+
* Exposed so a sibling can be ordered against the invocation — e.g.
|
|
156
|
+
* `deploymentTrigger.executeBefore(...)` to gate another resource on the
|
|
157
|
+
* call having succeeded.
|
|
158
|
+
*
|
|
159
|
+
* Optional, unlike the always-present `alarms` / `eventSources` beside it:
|
|
160
|
+
* there is no empty `Trigger` to stand in for the absence of one.
|
|
161
|
+
*/
|
|
162
|
+
deploymentTrigger?: Trigger;
|
|
134
163
|
}
|
|
135
164
|
/**
|
|
136
165
|
* A fluent builder for configuring and creating an AWS Lambda function.
|
|
@@ -239,6 +268,48 @@ declare class FunctionBuilder implements Lifecycle<FunctionBuilderResult> {
|
|
|
239
268
|
* Mutually exclusive with {@link role} and {@link configureRole}.
|
|
240
269
|
*/
|
|
241
270
|
useCdkAutoRole(): this;
|
|
271
|
+
/**
|
|
272
|
+
* Invoke this function once during deployment, and **fail the deployment if
|
|
273
|
+
* it fails** — a domain action for work that must happen as part of shipping
|
|
274
|
+
* the stack, such as registering the release with an external service,
|
|
275
|
+
* verifying the deployed system answers correctly, or seeding reference data
|
|
276
|
+
* through a service API (ADR-0016).
|
|
277
|
+
*
|
|
278
|
+
* The deployment waits for the handler's response. If the handler throws or
|
|
279
|
+
* times out, the stack fails and rolls back, and the handler's error message
|
|
280
|
+
* reaches the CloudFormation stack events.
|
|
281
|
+
*
|
|
282
|
+
* **The handler must throw to fail the deployment.** Returning an error
|
|
283
|
+
* object — an HTTP-shaped `{ statusCode: 500 }`, or a caught error swallowed
|
|
284
|
+
* into the response — is a *successful* invocation as far as Lambda is
|
|
285
|
+
* concerned, and the deployment goes green.
|
|
286
|
+
*
|
|
287
|
+
* Ordering is data: the function's own execution role is always waited for,
|
|
288
|
+
* and anything else the call needs is declared with
|
|
289
|
+
* {@link InvokeOnDeployOptions.after}.
|
|
290
|
+
*
|
|
291
|
+
* The deployment waits for this function's own `timeout` plus 30s, rather
|
|
292
|
+
* than the flat 2 minutes CDK's `Trigger` defaults to, so a handler that runs
|
|
293
|
+
* to its limit reports *its* error instead of the deployment abandoning the
|
|
294
|
+
* call first. The wait is capped at 14m30s — see
|
|
295
|
+
* {@link InvokeOnDeployOptions.timeout}, which throws above that rather than
|
|
296
|
+
* clamping.
|
|
297
|
+
*
|
|
298
|
+
* Calling this more than once replaces the previous options. The resulting
|
|
299
|
+
* custom resource is exposed on
|
|
300
|
+
* {@link FunctionBuilderResult.deploymentTrigger}.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```ts
|
|
304
|
+
* createFunctionBuilder()
|
|
305
|
+
* .runtime(Runtime.NODEJS_22_X)
|
|
306
|
+
* .handler("index.handler")
|
|
307
|
+
* .code(Code.fromAsset("register"))
|
|
308
|
+
* .timeout(Duration.seconds(30))
|
|
309
|
+
* .invokeOnDeploy({ after: [ref("api", (r: RestApiBuilderResult) => r.api)] });
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
invokeOnDeploy(options?: InvokeOnDeployOptions): this;
|
|
242
313
|
/**
|
|
243
314
|
* Grant this function's execution role access to a resource built by a
|
|
244
315
|
* sibling component.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function-builder.d.ts","sourceRoot":"","sources":["../../src/function-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,KAAK,EAAiB,MAAM,qBAAqB,CAAC;AACjF,OAAO,EACL,QAAQ,IAAI,cAAc,EAC1B,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"function-builder.d.ts","sourceRoot":"","sources":["../../src/function-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ const function_alarms_js_1 = require("./function-alarms.js");
|
|
|
12
12
|
const defaults_js_1 = require("./defaults.js");
|
|
13
13
|
const composure_event_source_js_1 = require("./event-sources/composure-event-source.js");
|
|
14
14
|
const event_source_relationship_guards_js_1 = require("./event-sources/event-source-relationship-guards.js");
|
|
15
|
+
const invoke_on_deploy_js_1 = require("./invoke-on-deploy.js");
|
|
15
16
|
const LOGS_WRITER_POLICY_NAME = "LogsWriter";
|
|
16
17
|
/**
|
|
17
18
|
* The log group's ARN, wherever the installed `aws-cdk-lib` keeps it.
|
|
@@ -45,6 +46,7 @@ class FunctionBuilder {
|
|
|
45
46
|
#grants = new core_1.GrantQueue();
|
|
46
47
|
#configureRole;
|
|
47
48
|
#useCdkAutoRole = false;
|
|
49
|
+
#invokeOnDeploy;
|
|
48
50
|
addAlarm(key, configure) {
|
|
49
51
|
this.#customAlarms.push(configure(new cloudwatch_1.AlarmDefinitionBuilder(key)));
|
|
50
52
|
return this;
|
|
@@ -108,6 +110,51 @@ class FunctionBuilder {
|
|
|
108
110
|
this.#useCdkAutoRole = true;
|
|
109
111
|
return this;
|
|
110
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Invoke this function once during deployment, and **fail the deployment if
|
|
115
|
+
* it fails** — a domain action for work that must happen as part of shipping
|
|
116
|
+
* the stack, such as registering the release with an external service,
|
|
117
|
+
* verifying the deployed system answers correctly, or seeding reference data
|
|
118
|
+
* through a service API (ADR-0016).
|
|
119
|
+
*
|
|
120
|
+
* The deployment waits for the handler's response. If the handler throws or
|
|
121
|
+
* times out, the stack fails and rolls back, and the handler's error message
|
|
122
|
+
* reaches the CloudFormation stack events.
|
|
123
|
+
*
|
|
124
|
+
* **The handler must throw to fail the deployment.** Returning an error
|
|
125
|
+
* object — an HTTP-shaped `{ statusCode: 500 }`, or a caught error swallowed
|
|
126
|
+
* into the response — is a *successful* invocation as far as Lambda is
|
|
127
|
+
* concerned, and the deployment goes green.
|
|
128
|
+
*
|
|
129
|
+
* Ordering is data: the function's own execution role is always waited for,
|
|
130
|
+
* and anything else the call needs is declared with
|
|
131
|
+
* {@link InvokeOnDeployOptions.after}.
|
|
132
|
+
*
|
|
133
|
+
* The deployment waits for this function's own `timeout` plus 30s, rather
|
|
134
|
+
* than the flat 2 minutes CDK's `Trigger` defaults to, so a handler that runs
|
|
135
|
+
* to its limit reports *its* error instead of the deployment abandoning the
|
|
136
|
+
* call first. The wait is capped at 14m30s — see
|
|
137
|
+
* {@link InvokeOnDeployOptions.timeout}, which throws above that rather than
|
|
138
|
+
* clamping.
|
|
139
|
+
*
|
|
140
|
+
* Calling this more than once replaces the previous options. The resulting
|
|
141
|
+
* custom resource is exposed on
|
|
142
|
+
* {@link FunctionBuilderResult.deploymentTrigger}.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* createFunctionBuilder()
|
|
147
|
+
* .runtime(Runtime.NODEJS_22_X)
|
|
148
|
+
* .handler("index.handler")
|
|
149
|
+
* .code(Code.fromAsset("register"))
|
|
150
|
+
* .timeout(Duration.seconds(30))
|
|
151
|
+
* .invokeOnDeploy({ after: [ref("api", (r: RestApiBuilderResult) => r.api)] });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
invokeOnDeploy(options = {}) {
|
|
155
|
+
this.#invokeOnDeploy = options;
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
111
158
|
/**
|
|
112
159
|
* Grant this function's execution role access to a resource built by a
|
|
113
160
|
* sibling component.
|
|
@@ -138,9 +185,10 @@ class FunctionBuilder {
|
|
|
138
185
|
this.#grants.copyInto(target.#grants);
|
|
139
186
|
target.#configureRole = this.#configureRole;
|
|
140
187
|
target.#useCdkAutoRole = this.#useCdkAutoRole;
|
|
188
|
+
target.#invokeOnDeploy = this.#invokeOnDeploy;
|
|
141
189
|
}
|
|
142
190
|
build(scope, id, context = {}) {
|
|
143
|
-
const { role: roleResolvable, environmentEncryption, recommendedAlarms: alarmConfig, ...functionProps } = this.props;
|
|
191
|
+
const { role: roleResolvable, environmentEncryption, environment, recommendedAlarms: alarmConfig, ...functionProps } = this.props;
|
|
144
192
|
const seamCount = (roleResolvable !== undefined ? 1 : 0) +
|
|
145
193
|
(this.#configureRole !== undefined ? 1 : 0) +
|
|
146
194
|
(this.#useCdkAutoRole ? 1 : 0);
|
|
@@ -168,6 +216,7 @@ class FunctionBuilder {
|
|
|
168
216
|
...(environmentEncryption !== undefined
|
|
169
217
|
? { environmentEncryption: (0, core_1.resolve)(environmentEncryption, context) }
|
|
170
218
|
: {}),
|
|
219
|
+
...(environment !== undefined ? { environment: (0, core_1.resolve)((0, core_1.combine)(environment), context) } : {}),
|
|
171
220
|
};
|
|
172
221
|
const fn = new aws_lambda_1.Function(scope, id, mergedProps);
|
|
173
222
|
this.#grants.applyTo(fn, context);
|
|
@@ -207,7 +256,12 @@ class FunctionBuilder {
|
|
|
207
256
|
if (!resolvedRole) {
|
|
208
257
|
throw new Error(`FunctionBuilder "${id}": Lambda function has no execution role.`);
|
|
209
258
|
}
|
|
210
|
-
|
|
259
|
+
// Built last so the invocation is ordered after everything the builder
|
|
260
|
+
// attached to the function — grants included.
|
|
261
|
+
const deploymentTrigger = this.#invokeOnDeploy
|
|
262
|
+
? (0, invoke_on_deploy_js_1.createDeploymentTrigger)(scope, id, fn, resolvedRole, this.#invokeOnDeploy, context)
|
|
263
|
+
: undefined;
|
|
264
|
+
return { function: fn, role: resolvedRole, logGroup, alarms, eventSources, deploymentTrigger };
|
|
211
265
|
}
|
|
212
266
|
#buildDefaultRole(scope, id, context, logGroup) {
|
|
213
267
|
if (!logGroup) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function-builder.js","sourceRoot":"","sources":["../../src/function-builder.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"function-builder.js","sourceRoot":"","sources":["../../src/function-builder.ts"],"names":[],"mappings":"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"}
|
package/dist/commonjs/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { createFunctionBuilder, type FunctionBuilderProps, type FunctionBuilderResult, type IFunctionBuilder, } from "./function-builder.js";
|
|
2
2
|
export { functionGrants } from "./grants.js";
|
|
3
3
|
export { FUNCTION_DEFAULTS } from "./defaults.js";
|
|
4
|
+
export { INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID, INVOKE_ON_DEPLOY_DEFAULTS, type InvokeOnDeployOptions, } from "./invoke-on-deploy.js";
|
|
4
5
|
export { type FunctionAlarmConfig, type PercentageAlarmConfig } from "./alarm-config.js";
|
|
5
6
|
export { FUNCTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
6
7
|
export { type ComposureEventSource, type EventSourceKind, } from "./event-sources/composure-event-source.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,cAAc,EACd,8BAA8B,GAC/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,qDAAqD,CAAC;AAC7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,iDAAiD,CAAC;AACpG,OAAO,EACL,iBAAiB,EACjB,iCAAiC,EACjC,KAAK,4BAA4B,GAClC,MAAM,0CAA0C,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EACL,mCAAmC,EACnC,yBAAyB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,cAAc,EACd,8BAA8B,GAC/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,qDAAqD,CAAC;AAC7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,iDAAiD,CAAC;AACpG,OAAO,EACL,iBAAiB,EACjB,iCAAiC,EACjC,KAAK,4BAA4B,GAClC,MAAM,0CAA0C,CAAC"}
|
package/dist/commonjs/index.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_DYNAMO_EVENT_SOURCE_PROPS = exports.dynamoEventSource = exports.DEFAULT_STREAM_EVENT_SOURCE_PROPS = exports.STREAM_DLQ_WARNING_ID = exports.SQS_VISIBILITY_TIMEOUT_WARNING_ID = exports.DEFAULT_SQS_EVENT_SOURCE_PROPS = exports.sqsEventSource = exports.FUNCTION_ALARM_DEFAULTS = exports.FUNCTION_DEFAULTS = exports.functionGrants = exports.createFunctionBuilder = void 0;
|
|
3
|
+
exports.DEFAULT_DYNAMO_EVENT_SOURCE_PROPS = exports.dynamoEventSource = exports.DEFAULT_STREAM_EVENT_SOURCE_PROPS = exports.STREAM_DLQ_WARNING_ID = exports.SQS_VISIBILITY_TIMEOUT_WARNING_ID = exports.DEFAULT_SQS_EVENT_SOURCE_PROPS = exports.sqsEventSource = exports.FUNCTION_ALARM_DEFAULTS = exports.INVOKE_ON_DEPLOY_DEFAULTS = exports.INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID = exports.FUNCTION_DEFAULTS = exports.functionGrants = exports.createFunctionBuilder = void 0;
|
|
4
4
|
var function_builder_js_1 = require("./function-builder.js");
|
|
5
5
|
Object.defineProperty(exports, "createFunctionBuilder", { enumerable: true, get: function () { return function_builder_js_1.createFunctionBuilder; } });
|
|
6
6
|
var grants_js_1 = require("./grants.js");
|
|
7
7
|
Object.defineProperty(exports, "functionGrants", { enumerable: true, get: function () { return grants_js_1.functionGrants; } });
|
|
8
8
|
var defaults_js_1 = require("./defaults.js");
|
|
9
9
|
Object.defineProperty(exports, "FUNCTION_DEFAULTS", { enumerable: true, get: function () { return defaults_js_1.FUNCTION_DEFAULTS; } });
|
|
10
|
+
var invoke_on_deploy_js_1 = require("./invoke-on-deploy.js");
|
|
11
|
+
Object.defineProperty(exports, "INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID", { enumerable: true, get: function () { return invoke_on_deploy_js_1.INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID; } });
|
|
12
|
+
Object.defineProperty(exports, "INVOKE_ON_DEPLOY_DEFAULTS", { enumerable: true, get: function () { return invoke_on_deploy_js_1.INVOKE_ON_DEPLOY_DEFAULTS; } });
|
|
10
13
|
var alarm_defaults_js_1 = require("./alarm-defaults.js");
|
|
11
14
|
Object.defineProperty(exports, "FUNCTION_ALARM_DEFAULTS", { enumerable: true, get: function () { return alarm_defaults_js_1.FUNCTION_ALARM_DEFAULTS; } });
|
|
12
15
|
var sqs_event_source_js_1 = require("./event-sources/sqs-event-source.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,6DAK+B;AAJ7B,4HAAA,qBAAqB,OAAA;AAKvB,yCAA6C;AAApC,2GAAA,cAAc,OAAA;AACvB,6CAAkD;AAAzC,gHAAA,iBAAiB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,6DAK+B;AAJ7B,4HAAA,qBAAqB,OAAA;AAKvB,yCAA6C;AAApC,2GAAA,cAAc,OAAA;AACvB,6CAAkD;AAAzC,gHAAA,iBAAiB,OAAA;AAC1B,6DAI+B;AAH7B,0IAAA,mCAAmC,OAAA;AACnC,gIAAA,yBAAyB,OAAA;AAI3B,yDAA8D;AAArD,4HAAA,uBAAuB,OAAA;AAKhC,2EAG6C;AAF3C,qHAAA,cAAc,OAAA;AACd,qIAAA,8BAA8B,OAAA;AAEhC,2GAG6D;AAF3D,wJAAA,iCAAiC,OAAA;AACjC,4IAAA,qBAAqB,OAAA;AAEvB,mGAAoG;AAA3F,oJAAA,iCAAiC,OAAA;AAC1C,qFAIkD;AAHhD,6HAAA,iBAAiB,OAAA;AACjB,6IAAA,iCAAiC,OAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Duration } from "aws-cdk-lib";
|
|
2
|
+
import type { Function as LambdaFunction } from "aws-cdk-lib/aws-lambda";
|
|
3
|
+
import { Trigger } from "aws-cdk-lib/triggers";
|
|
4
|
+
import type { IConstruct } from "constructs";
|
|
5
|
+
import { type DependencySource } from "@composurecdk/core";
|
|
6
|
+
/**
|
|
7
|
+
* Suppression id for the deploy-time invocation timeout guard. Stable and part
|
|
8
|
+
* of the public surface — silence the warning with
|
|
9
|
+
* `Annotations.of(scope).acknowledgeWarning(INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID)`,
|
|
10
|
+
* so it must not be renamed casually.
|
|
11
|
+
*/
|
|
12
|
+
export declare const INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID = "@composurecdk/lambda:invoke-on-deploy-timeout";
|
|
13
|
+
/**
|
|
14
|
+
* How {@link IFunctionBuilder.invokeOnDeploy | `.invokeOnDeploy()`} derives the
|
|
15
|
+
* wait when the caller sets no {@link InvokeOnDeployOptions.timeout}. A public
|
|
16
|
+
* mirror of this module's constants, exported for visibility and testing — the
|
|
17
|
+
* rationale for each value is on the constant it mirrors.
|
|
18
|
+
*/
|
|
19
|
+
export declare const INVOKE_ON_DEPLOY_DEFAULTS: {
|
|
20
|
+
/** @see {@link TIMEOUT_MARGIN} */
|
|
21
|
+
readonly timeoutMargin: Duration;
|
|
22
|
+
/** @see {@link FALLBACK_TIMEOUT} */
|
|
23
|
+
readonly fallbackTimeout: Duration;
|
|
24
|
+
/** @see {@link MAX_TIMEOUT} */
|
|
25
|
+
readonly maxTimeout: Duration;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Options for {@link IFunctionBuilder.invokeOnDeploy | `.invokeOnDeploy()`}.
|
|
29
|
+
*/
|
|
30
|
+
export interface InvokeOnDeployOptions {
|
|
31
|
+
/**
|
|
32
|
+
* What must be fully provisioned before the handler runs — see
|
|
33
|
+
* {@link DependencySource} for the shapes it takes and what each one reaches.
|
|
34
|
+
*
|
|
35
|
+
* The function's own execution role, and therefore every policy attached to
|
|
36
|
+
* it by `.grant()` or `.configureRole()`, is already waited for. This is for
|
|
37
|
+
* everything else the call depends on: the API it will call, the table it
|
|
38
|
+
* will seed — and the resource behind any grant that writes a *resource*
|
|
39
|
+
* policy rather than an identity one, such as a KMS key, since that half is
|
|
40
|
+
* not attached to the role and so is not covered.
|
|
41
|
+
*/
|
|
42
|
+
readonly after?: DependencySource[];
|
|
43
|
+
/**
|
|
44
|
+
* How long the deployment waits for the handler before failing the stack.
|
|
45
|
+
*
|
|
46
|
+
* Defaults to the function's own `timeout` plus
|
|
47
|
+
* {@link INVOKE_ON_DEPLOY_DEFAULTS.timeoutMargin}, capped at
|
|
48
|
+
* {@link INVOKE_ON_DEPLOY_DEFAULTS.maxTimeout}. Setting it at or below the
|
|
49
|
+
* function's timeout warns under {@link INVOKE_ON_DEPLOY_TIMEOUT_WARNING_ID};
|
|
50
|
+
* setting it above `maxTimeout` throws, because the provider would not
|
|
51
|
+
* survive the wait to report anything.
|
|
52
|
+
*/
|
|
53
|
+
readonly timeout?: Duration;
|
|
54
|
+
/**
|
|
55
|
+
* Re-invoke the handler whenever its code or configuration changes.
|
|
56
|
+
*
|
|
57
|
+
* `true` (the default) binds the invocation to the function's current
|
|
58
|
+
* version, so it re-runs on a handler change and is a no-op on unrelated
|
|
59
|
+
* stack updates — right for an idempotent registration. `false` invokes only
|
|
60
|
+
* on the stack's *first* deployment. Neither setting invokes on every
|
|
61
|
+
* deployment; that is not something CDK's `Trigger` offers.
|
|
62
|
+
*/
|
|
63
|
+
readonly executeOnHandlerChange?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Creates the custom resource that invokes `handler` during deployment and
|
|
67
|
+
* fails the stack if it errors.
|
|
68
|
+
*
|
|
69
|
+
* The invocation is ordered after the function's execution role, so the policies
|
|
70
|
+
* attached *to it* by `.grant()` / `.configureRole()` — which CloudFormation
|
|
71
|
+
* does not otherwise sequence ahead of a custom resource — exist by the time the
|
|
72
|
+
* handler runs.
|
|
73
|
+
*
|
|
74
|
+
* That reaches the identity half of a grant only: one that also writes a
|
|
75
|
+
* resource policy (a KMS key policy, a cross-account bucket policy) leaves that
|
|
76
|
+
* half in the granting resource's tree, and an imported role contributes no
|
|
77
|
+
* resources to sequence at all. Both are the consumer's to declare through
|
|
78
|
+
* {@link InvokeOnDeployOptions.after}, as is anything else the call needs.
|
|
79
|
+
*
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
export declare function createDeploymentTrigger(scope: IConstruct, id: string, handler: LambdaFunction, executionRole: IConstruct, options: InvokeOnDeployOptions, context: Record<string, object>): Trigger;
|
|
83
|
+
//# sourceMappingURL=invoke-on-deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke-on-deploy.d.ts","sourceRoot":"","sources":["../../src/invoke-on-deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,QAAQ,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAkB,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,kDAAkD,CAAC;AA6CnG;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;IACpC,kCAAkC;;IAGlC,oCAAoC;;IAGpC,+BAA+B;;CAEvB,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEpC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAE5B;;;;;;;;OAQG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,UAAU,EACzB,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAaT"}
|