From 75212ebc7a30d822097223ea39a0d58da6fe8d43 Mon Sep 17 00:00:00 2001
From: WinterYukky <49480575+WinterYukky@users.noreply.github.com>
Date: Fri, 5 May 2023 23:46:15 +0900
Subject: [PATCH] fix(elasticloadbalancingv2): ALB auth return internal server
error (#24510)
## Summary
Allow HTTPS outbound traffic for security groups attached to the Application Load Balancer if the Application Load Balancer is configured with an authentication configuration.
## Why is this PR needed?
Application Load Balancer authentication requires HTTPS outbound traffic.
However, the security group attached to the ApplicationLoadBalancer does not allow traffic to the outside, so the code as described in the documentation will not work by itself.
This issue is also documented.
https://aws.amazon.com/premiumsupport/knowledge-center/elb-configure-authentication-alb/?nc1=h_ls
## Related issues
Following opened issues were fixed by #21939, but related this PR.
Closes #19035 #18944.
----
*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
.../test/alb-cognito-signin-handler/index.ts | 31 +
.../index.d.ts | 1 +
.../index.js | 34 +
.../index.ts | 31 +
.../index.js | 256 +++
.../index.js | 1295 ++++++++++++
.../test/integ.cognito.js.snapshot/cdk.out | 2 +-
.../integ-cognito.assets.json | 32 +-
.../integ-cognito.template.json | 451 +++-
.../test/integ.cognito.js.snapshot/integ.json | 2 +-
...efaultTestDeployAssert6F2623C9.assets.json | 19 +-
...aultTestDeployAssert6F2623C9.template.json | 142 ++
.../integ.cognito.js.snapshot/manifest.json | 109 +-
.../test/integ.cognito.js.snapshot/tree.json | 796 ++++++-
.../test/integ.cognito.ts | 157 +-
.../test/alb-oidc-signin-handler/index.ts | 31 +
.../IntegAlbOidc.assets.json | 58 +
.../IntegAlbOidc.template.json | 1286 ++++++++++++
...efaultTestDeployAssert2476ECB6.assets.json | 32 +
...aultTestDeployAssert2476ECB6.template.json | 178 ++
.../index.d.ts | 1 +
.../index.js | 34 +
.../index.ts | 31 +
.../index.js | 1296 ++++++++++++
.../index.js | 256 +++
.../__entrypoint__.js | 147 ++
.../index.js | 81 +
.../test/integ.alb.oidc.js.snapshot/cdk.out | 1 +
.../integ.alb.oidc.js.snapshot/integ.json | 12 +
.../integ.alb.oidc.js.snapshot/manifest.json | 412 ++++
.../test/integ.alb.oidc.js.snapshot/tree.json | 1860 +++++++++++++++++
.../test/integ.alb.oidc.ts | 198 ++
.../test/integ.alb2.js.snapshot/cdk.out | 2 +-
.../lib/cognito-action.ts | 24 +
.../test/cognito.test.ts | 110 +-
.../lib/alb/application-listener-action.ts | 81 +-
.../test/alb/actions.test.ts | 81 +
37 files changed, 9406 insertions(+), 164 deletions(-)
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/alb-cognito-signin-handler/index.ts
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3.bundle/index.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/alb-oidc-signin-handler/index.ts
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.assets.json
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.template.json
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets.json
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.template.json
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4.bundle/index.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/__entrypoint__.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/index.js
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/cdk.out
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/integ.json
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/manifest.json
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/tree.json
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.ts
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/alb-cognito-signin-handler/index.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/alb-cognito-signin-handler/index.ts
new file mode 100644
index 0000000000000..9e79dd3fb247a
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/alb-cognito-signin-handler/index.ts
@@ -0,0 +1,31 @@
+/* eslint-disable @typescript-eslint/no-require-imports */
+import { execSync } from 'child_process';
+
+const url = process.env.TEST_URL;
+const setupBrowser = async () => {
+ execSync('HOME=/tmp npm install puppeteer-core @sparticuz/chromium --omit=dev --no-package-lock --no-save --prefix /tmp');
+ const puppeteer = require('/tmp/node_modules/puppeteer-core');
+ const chromium = require('/tmp/node_modules/@sparticuz/chromium');
+ const browser = await puppeteer.launch({
+ args: chromium.args,
+ defaultViewport: chromium.defaultViewport,
+ executablePath: await chromium.executablePath(),
+ headless: chromium.headless,
+ });
+ return browser;
+};
+
+export const handler: AWSLambda.Handler = async (_event) => {
+ const browser = await setupBrowser();
+ const page = await browser.newPage();
+ await page.goto(url, {
+ waitUntil: ['load', 'networkidle0'],
+ timeout: 30000,
+ });
+ await page.type("div.visible-lg input[name='username']", process.env.TEST_USERNAME);
+ await page.type("div.visible-lg input[name='password']", process.env.TEST_PASSWORD);
+ await page.click("div.visible-lg input[type='submit']");
+ const body = await page.waitForSelector('body');
+ const textContent = await body.evaluate((el: any) => el.textContent);
+ return textContent;
+};
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts
new file mode 100644
index 0000000000000..da5565949aa48
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts
@@ -0,0 +1 @@
+export declare const handler: AWSLambda.Handler;
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js
new file mode 100644
index 0000000000000..78672677bf37d
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js
@@ -0,0 +1,34 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.handler = void 0;
+/* eslint-disable @typescript-eslint/no-require-imports */
+const child_process_1 = require("child_process");
+const url = process.env.TEST_URL;
+const setupBrowser = async () => {
+ (0, child_process_1.execSync)('HOME=/tmp npm install puppeteer-core @sparticuz/chromium --omit=dev --no-package-lock --no-save --prefix /tmp');
+ const puppeteer = require('/tmp/node_modules/puppeteer-core');
+ const chromium = require('/tmp/node_modules/@sparticuz/chromium');
+ const browser = await puppeteer.launch({
+ args: chromium.args,
+ defaultViewport: chromium.defaultViewport,
+ executablePath: await chromium.executablePath(),
+ headless: chromium.headless,
+ });
+ return browser;
+};
+const handler = async (_event) => {
+ const browser = await setupBrowser();
+ const page = await browser.newPage();
+ await page.goto(url, {
+ waitUntil: ['load', 'networkidle0'],
+ timeout: 30000,
+ });
+ await page.type("div.visible-lg input[name='username']", process.env.TEST_USERNAME);
+ await page.type("div.visible-lg input[name='password']", process.env.TEST_PASSWORD);
+ await page.click("div.visible-lg input[type='submit']");
+ const body = await page.waitForSelector('body');
+ const textContent = await body.evaluate((el) => el.textContent);
+ return textContent;
+};
+exports.handler = handler;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwwREFBMEQ7QUFDMUQsaURBQXlDO0FBRXpDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO0FBQ2pDLE1BQU0sWUFBWSxHQUFHLEtBQUssSUFBSSxFQUFFO0lBQzlCLElBQUEsd0JBQVEsRUFBQywrR0FBK0csQ0FBQyxDQUFDO0lBQzFILE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO0lBQzlELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUNyQyxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUk7UUFDbkIsZUFBZSxFQUFFLFFBQVEsQ0FBQyxlQUFlO1FBQ3pDLGNBQWMsRUFBRSxNQUFNLFFBQVEsQ0FBQyxjQUFjLEVBQUU7UUFDL0MsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRO0tBQzVCLENBQUMsQ0FBQztJQUNILE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMsQ0FBQztBQUVLLE1BQU0sT0FBTyxHQUFzQixLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7SUFDekQsTUFBTSxPQUFPLEdBQUcsTUFBTSxZQUFZLEVBQUUsQ0FBQztJQUNyQyxNQUFNLElBQUksR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNyQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO1FBQ25CLFNBQVMsRUFBRSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUM7UUFDbkMsT0FBTyxFQUFFLEtBQUs7S0FDZixDQUFDLENBQUM7SUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsdUNBQXVDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNwRixNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsdUNBQXVDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNwRixNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztJQUN4RCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEQsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckUsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDO0FBYlcsUUFBQSxPQUFPLFdBYWxCIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAqL1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcblxuY29uc3QgdXJsID0gcHJvY2Vzcy5lbnYuVEVTVF9VUkw7XG5jb25zdCBzZXR1cEJyb3dzZXIgPSBhc3luYyAoKSA9PiB7XG4gIGV4ZWNTeW5jKCdIT01FPS90bXAgbnBtIGluc3RhbGwgcHVwcGV0ZWVyLWNvcmUgQHNwYXJ0aWN1ei9jaHJvbWl1bSAtLW9taXQ9ZGV2IC0tbm8tcGFja2FnZS1sb2NrIC0tbm8tc2F2ZSAtLXByZWZpeCAvdG1wJyk7XG4gIGNvbnN0IHB1cHBldGVlciA9IHJlcXVpcmUoJy90bXAvbm9kZV9tb2R1bGVzL3B1cHBldGVlci1jb3JlJyk7XG4gIGNvbnN0IGNocm9taXVtID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvQHNwYXJ0aWN1ei9jaHJvbWl1bScpO1xuICBjb25zdCBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaCh7XG4gICAgYXJnczogY2hyb21pdW0uYXJncyxcbiAgICBkZWZhdWx0Vmlld3BvcnQ6IGNocm9taXVtLmRlZmF1bHRWaWV3cG9ydCxcbiAgICBleGVjdXRhYmxlUGF0aDogYXdhaXQgY2hyb21pdW0uZXhlY3V0YWJsZVBhdGgoKSxcbiAgICBoZWFkbGVzczogY2hyb21pdW0uaGVhZGxlc3MsXG4gIH0pO1xuICByZXR1cm4gYnJvd3Nlcjtcbn07XG5cbmV4cG9ydCBjb25zdCBoYW5kbGVyOiBBV1NMYW1iZGEuSGFuZGxlciA9IGFzeW5jIChfZXZlbnQpID0+IHtcbiAgY29uc3QgYnJvd3NlciA9IGF3YWl0IHNldHVwQnJvd3NlcigpO1xuICBjb25zdCBwYWdlID0gYXdhaXQgYnJvd3Nlci5uZXdQYWdlKCk7XG4gIGF3YWl0IHBhZ2UuZ290byh1cmwsIHtcbiAgICB3YWl0VW50aWw6IFsnbG9hZCcsICduZXR3b3JraWRsZTAnXSxcbiAgICB0aW1lb3V0OiAzMDAwMCxcbiAgfSk7XG4gIGF3YWl0IHBhZ2UudHlwZShcImRpdi52aXNpYmxlLWxnIGlucHV0W25hbWU9J3VzZXJuYW1lJ11cIiwgcHJvY2Vzcy5lbnYuVEVTVF9VU0VSTkFNRSk7XG4gIGF3YWl0IHBhZ2UudHlwZShcImRpdi52aXNpYmxlLWxnIGlucHV0W25hbWU9J3Bhc3N3b3JkJ11cIiwgcHJvY2Vzcy5lbnYuVEVTVF9QQVNTV09SRCk7XG4gIGF3YWl0IHBhZ2UuY2xpY2soXCJkaXYudmlzaWJsZS1sZyBpbnB1dFt0eXBlPSdzdWJtaXQnXVwiKTtcbiAgY29uc3QgYm9keSA9IGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKCdib2R5Jyk7XG4gIGNvbnN0IHRleHRDb250ZW50ID0gYXdhaXQgYm9keS5ldmFsdWF0ZSgoZWw6IGFueSkgPT4gZWwudGV4dENvbnRlbnQpO1xuICByZXR1cm4gdGV4dENvbnRlbnQ7XG59O1xuIl19
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts
new file mode 100644
index 0000000000000..9e79dd3fb247a
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts
@@ -0,0 +1,31 @@
+/* eslint-disable @typescript-eslint/no-require-imports */
+import { execSync } from 'child_process';
+
+const url = process.env.TEST_URL;
+const setupBrowser = async () => {
+ execSync('HOME=/tmp npm install puppeteer-core @sparticuz/chromium --omit=dev --no-package-lock --no-save --prefix /tmp');
+ const puppeteer = require('/tmp/node_modules/puppeteer-core');
+ const chromium = require('/tmp/node_modules/@sparticuz/chromium');
+ const browser = await puppeteer.launch({
+ args: chromium.args,
+ defaultViewport: chromium.defaultViewport,
+ executablePath: await chromium.executablePath(),
+ headless: chromium.headless,
+ });
+ return browser;
+};
+
+export const handler: AWSLambda.Handler = async (_event) => {
+ const browser = await setupBrowser();
+ const page = await browser.newPage();
+ await page.goto(url, {
+ waitUntil: ['load', 'networkidle0'],
+ timeout: 30000,
+ });
+ await page.type("div.visible-lg input[name='username']", process.env.TEST_USERNAME);
+ await page.type("div.visible-lg input[name='password']", process.env.TEST_PASSWORD);
+ await page.click("div.visible-lg input[type='submit']");
+ const body = await page.waitForSelector('body');
+ const textContent = await body.evaluate((el: any) => el.textContent);
+ return textContent;
+};
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js
new file mode 100644
index 0000000000000..8237c98f2cc96
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js
@@ -0,0 +1,256 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.handler = exports.forceSdkInstallation = exports.flatten = exports.PHYSICAL_RESOURCE_ID_REFERENCE = void 0;
+/* eslint-disable no-console */
+const child_process_1 = require("child_process");
+const fs = require("fs");
+const path_1 = require("path");
+/**
+ * Serialized form of the physical resource id for use in the operation parameters
+ */
+exports.PHYSICAL_RESOURCE_ID_REFERENCE = 'PHYSICAL:RESOURCEID:';
+/**
+ * Flattens a nested object
+ *
+ * @param object the object to be flattened
+ * @returns a flat object with path as keys
+ */
+function flatten(object) {
+ return Object.assign({}, ...function _flatten(child, path = []) {
+ return [].concat(...Object.keys(child)
+ .map(key => {
+ const childKey = Buffer.isBuffer(child[key]) ? child[key].toString('utf8') : child[key];
+ return typeof childKey === 'object' && childKey !== null
+ ? _flatten(childKey, path.concat([key]))
+ : ({ [path.concat([key]).join('.')]: childKey });
+ }));
+ }(object));
+}
+exports.flatten = flatten;
+/**
+ * Decodes encoded special values (physicalResourceId)
+ */
+function decodeSpecialValues(object, physicalResourceId) {
+ return JSON.parse(JSON.stringify(object), (_k, v) => {
+ switch (v) {
+ case exports.PHYSICAL_RESOURCE_ID_REFERENCE:
+ return physicalResourceId;
+ default:
+ return v;
+ }
+ });
+}
+/**
+ * Filters the keys of an object.
+ */
+function filterKeys(object, pred) {
+ return Object.entries(object)
+ .reduce((acc, [k, v]) => pred(k)
+ ? { ...acc, [k]: v }
+ : acc, {});
+}
+let latestSdkInstalled = false;
+function forceSdkInstallation() {
+ latestSdkInstalled = false;
+}
+exports.forceSdkInstallation = forceSdkInstallation;
+/**
+ * Installs latest AWS SDK v2
+ */
+function installLatestSdk() {
+ console.log('Installing latest AWS SDK v2');
+ // Both HOME and --prefix are needed here because /tmp is the only writable location
+ (0, child_process_1.execSync)('HOME=/tmp npm install aws-sdk@2 --production --no-package-lock --no-save --prefix /tmp');
+ latestSdkInstalled = true;
+}
+// no currently patched services
+const patchedServices = [];
+/**
+ * Patches the AWS SDK by loading service models in the same manner as the actual SDK
+ */
+function patchSdk(awsSdk) {
+ const apiLoader = awsSdk.apiLoader;
+ patchedServices.forEach(({ serviceName, apiVersions }) => {
+ const lowerServiceName = serviceName.toLowerCase();
+ if (!awsSdk.Service.hasService(lowerServiceName)) {
+ apiLoader.services[lowerServiceName] = {};
+ awsSdk[serviceName] = awsSdk.Service.defineService(lowerServiceName, apiVersions);
+ }
+ else {
+ awsSdk.Service.addVersions(awsSdk[serviceName], apiVersions);
+ }
+ apiVersions.forEach(apiVersion => {
+ Object.defineProperty(apiLoader.services[lowerServiceName], apiVersion, {
+ get: function get() {
+ const modelFilePrefix = `aws-sdk-patch/${lowerServiceName}-${apiVersion}`;
+ const model = JSON.parse(fs.readFileSync((0, path_1.join)(__dirname, `${modelFilePrefix}.service.json`), 'utf-8'));
+ model.paginators = JSON.parse(fs.readFileSync((0, path_1.join)(__dirname, `${modelFilePrefix}.paginators.json`), 'utf-8')).pagination;
+ return model;
+ },
+ enumerable: true,
+ configurable: true,
+ });
+ });
+ });
+ return awsSdk;
+}
+/* eslint-disable @typescript-eslint/no-require-imports, import/no-extraneous-dependencies */
+async function handler(event, context) {
+ try {
+ let AWS;
+ if (!latestSdkInstalled && event.ResourceProperties.InstallLatestAwsSdk === 'true') {
+ try {
+ installLatestSdk();
+ AWS = require('/tmp/node_modules/aws-sdk');
+ }
+ catch (e) {
+ console.log(`Failed to install latest AWS SDK v2: ${e}`);
+ AWS = require('aws-sdk'); // Fallback to pre-installed version
+ }
+ }
+ else if (latestSdkInstalled) {
+ AWS = require('/tmp/node_modules/aws-sdk');
+ }
+ else {
+ AWS = require('aws-sdk');
+ }
+ try {
+ AWS = patchSdk(AWS);
+ }
+ catch (e) {
+ console.log(`Failed to patch AWS SDK: ${e}. Proceeding with the installed copy.`);
+ }
+ console.log(JSON.stringify({ ...event, ResponseURL: '...' }));
+ console.log('AWS SDK VERSION: ' + AWS.VERSION);
+ event.ResourceProperties.Create = decodeCall(event.ResourceProperties.Create);
+ event.ResourceProperties.Update = decodeCall(event.ResourceProperties.Update);
+ event.ResourceProperties.Delete = decodeCall(event.ResourceProperties.Delete);
+ // Default physical resource id
+ let physicalResourceId;
+ switch (event.RequestType) {
+ case 'Create':
+ physicalResourceId = event.ResourceProperties.Create?.physicalResourceId?.id ??
+ event.ResourceProperties.Update?.physicalResourceId?.id ??
+ event.ResourceProperties.Delete?.physicalResourceId?.id ??
+ event.LogicalResourceId;
+ break;
+ case 'Update':
+ case 'Delete':
+ physicalResourceId = event.ResourceProperties[event.RequestType]?.physicalResourceId?.id ?? event.PhysicalResourceId;
+ break;
+ }
+ let flatData = {};
+ let data = {};
+ const call = event.ResourceProperties[event.RequestType];
+ if (call) {
+ let credentials;
+ if (call.assumedRoleArn) {
+ const timestamp = (new Date()).getTime();
+ const params = {
+ RoleArn: call.assumedRoleArn,
+ RoleSessionName: `${timestamp}-${physicalResourceId}`.substring(0, 64),
+ };
+ credentials = new AWS.ChainableTemporaryCredentials({
+ params: params,
+ stsConfig: { stsRegionalEndpoints: 'regional' },
+ });
+ }
+ if (!Object.prototype.hasOwnProperty.call(AWS, call.service)) {
+ throw Error(`Service ${call.service} does not exist in AWS SDK version ${AWS.VERSION}.`);
+ }
+ const awsService = new AWS[call.service]({
+ apiVersion: call.apiVersion,
+ credentials: credentials,
+ region: call.region,
+ });
+ try {
+ const response = await awsService[call.action](call.parameters && decodeSpecialValues(call.parameters, physicalResourceId)).promise();
+ flatData = {
+ apiVersion: awsService.config.apiVersion,
+ region: awsService.config.region,
+ ...flatten(response),
+ };
+ let outputPaths;
+ if (call.outputPath) {
+ outputPaths = [call.outputPath];
+ }
+ else if (call.outputPaths) {
+ outputPaths = call.outputPaths;
+ }
+ if (outputPaths) {
+ data = filterKeys(flatData, startsWithOneOf(outputPaths));
+ }
+ else {
+ data = flatData;
+ }
+ }
+ catch (e) {
+ if (!call.ignoreErrorCodesMatching || !new RegExp(call.ignoreErrorCodesMatching).test(e.code)) {
+ throw e;
+ }
+ }
+ if (call.physicalResourceId?.responsePath) {
+ physicalResourceId = flatData[call.physicalResourceId.responsePath];
+ }
+ }
+ await respond('SUCCESS', 'OK', physicalResourceId, data);
+ }
+ catch (e) {
+ console.log(e);
+ await respond('FAILED', e.message || 'Internal Error', context.logStreamName, {});
+ }
+ function respond(responseStatus, reason, physicalResourceId, data) {
+ const responseBody = JSON.stringify({
+ Status: responseStatus,
+ Reason: reason,
+ PhysicalResourceId: physicalResourceId,
+ StackId: event.StackId,
+ RequestId: event.RequestId,
+ LogicalResourceId: event.LogicalResourceId,
+ NoEcho: false,
+ Data: data,
+ });
+ console.log('Responding', responseBody);
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const parsedUrl = require('url').parse(event.ResponseURL);
+ const requestOptions = {
+ hostname: parsedUrl.hostname,
+ path: parsedUrl.path,
+ method: 'PUT',
+ headers: {
+ 'content-type': '',
+ 'content-length': Buffer.byteLength(responseBody, 'utf8'),
+ },
+ };
+ return new Promise((resolve, reject) => {
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const request = require('https').request(requestOptions, resolve);
+ request.on('error', reject);
+ request.write(responseBody);
+ request.end();
+ }
+ catch (e) {
+ reject(e);
+ }
+ });
+ }
+}
+exports.handler = handler;
+function decodeCall(call) {
+ if (!call) {
+ return undefined;
+ }
+ return JSON.parse(call);
+}
+function startsWithOneOf(searchStrings) {
+ return function (string) {
+ for (const searchString of searchStrings) {
+ if (string.startsWith(searchString)) {
+ return true;
+ }
+ }
+ return false;
+ };
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsaURBQXlDO0FBQ3pDLHlCQUF5QjtBQUN6QiwrQkFBNEI7QUFTNUI7O0dBRUc7QUFDVSxRQUFBLDhCQUE4QixHQUFHLHNCQUFzQixDQUFDO0FBRXJFOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLE1BQWM7SUFDcEMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQixFQUFFLEVBQ0YsR0FBRyxTQUFTLFFBQVEsQ0FBQyxLQUFVLEVBQUUsT0FBaUIsRUFBRTtRQUNsRCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEYsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksUUFBUSxLQUFLLElBQUk7Z0JBQ3RELENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUNWLENBQUM7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QUUsRUFBRTtZQUNyQyxJQUFJO2dCQUNGLGlFQUFpRTtnQkFDakUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2xFLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM1QixPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7YUFDZjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNYO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQztBQXJKRCwwQkFxSkM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxJQUF3QjtJQUMxQyxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQUUsT0FBTyxTQUFTLENBQUM7S0FBRTtJQUNoQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLGFBQXVCO0lBQzlDLE9BQU8sVUFBUyxNQUFjO1FBQzVCLEtBQUssTUFBTSxZQUFZLElBQUksYUFBYSxFQUFFO1lBQ3hDLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFDbkMsT0FBTyxJQUFJLENBQUM7YUFDYjtTQUNGO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbi8vIGltcG9ydCB0aGUgQVdTTGFtYmRhIHBhY2thZ2UgZXhwbGljaXRseSxcbi8vIHdoaWNoIGlzIGdsb2JhbGx5IGF2YWlsYWJsZSBpbiB0aGUgTGFtYmRhIHJ1bnRpbWUsXG4vLyBhcyBvdGhlcndpc2UgbGlua2luZyB0aGlzIHJlcG9zaXRvcnkgd2l0aCBsaW5rLWFsbC5zaFxuLy8gZmFpbHMgaW4gdGhlIENESyBhcHAgZXhlY3V0ZWQgd2l0aCB0cy1ub2RlXG4vKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzLGltcG9ydC9uby11bnJlc29sdmVkICovXG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBBd3NTZGtDYWxsIH0gZnJvbSAnLi4vYXdzLWN1c3RvbS1yZXNvdXJjZSc7XG5cbi8qKlxuICogU2VyaWFsaXplZCBmb3JtIG9mIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBpZCBmb3IgdXNlIGluIHRoZSBvcGVyYXRpb24gcGFyYW1ldGVyc1xuICovXG5leHBvcnQgY29uc3QgUEhZU0lDQUxfUkVTT1VSQ0VfSURfUkVGRVJFTkNFID0gJ1BIWVNJQ0FMOlJFU09VUkNFSUQ6JztcblxuLyoqXG4gKiBGbGF0dGVucyBhIG5lc3RlZCBvYmplY3RcbiAqXG4gKiBAcGFyYW0gb2JqZWN0IHRoZSBvYmplY3QgdG8gYmUgZmxhdHRlbmVkXG4gKiBAcmV0dXJucyBhIGZsYXQgb2JqZWN0IHdpdGggcGF0aCBhcyBrZXlzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuKG9iamVjdDogb2JqZWN0KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKFxuICAgIHt9LFxuICAgIC4uLmZ1bmN0aW9uIF9mbGF0dGVuKGNoaWxkOiBhbnksIHBhdGg6IHN0cmluZ1tdID0gW10pOiBhbnkge1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdCguLi5PYmplY3Qua2V5cyhjaGlsZClcbiAgICAgICAgLm1hcChrZXkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkS2V5ID0gQnVmZmVyLmlzQnVmZmVyKGNoaWxkW2tleV0pID8gY2hpbGRba2V5XS50b1N0cmluZygndXRmOCcpIDogY2hpbGRba2V5XTtcbiAgICAgICAgICByZXR1cm4gdHlwZW9mIGNoaWxkS2V5ID09PSAnb2JqZWN0JyAmJiBjaGlsZEtleSAhPT0gbnVsbFxuICAgICAgICAgICAgPyBfZmxhdHRlbihjaGlsZEtleSwgcGF0aC5jb25jYXQoW2tleV0pKVxuICAgICAgICAgICAgOiAoeyBbcGF0aC5jb25jYXQoW2tleV0pLmpvaW4oJy4nKV06IGNoaWxkS2V5IH0pO1xuICAgICAgICB9KSk7XG4gICAgfShvYmplY3QpLFxuICApO1xufVxuXG4vKipcbiAqIERlY29kZXMgZW5jb2RlZCBzcGVjaWFsIHZhbHVlcyAocGh5c2ljYWxSZXNvdXJjZUlkKVxuICovXG5mdW5jdGlvbiBkZWNvZGVTcGVjaWFsVmFsdWVzKG9iamVjdDogb2JqZWN0LCBwaHlzaWNhbFJlc291cmNlSWQ6IHN0cmluZykge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmplY3QpLCAoX2ssIHYpID0+IHtcbiAgICBzd2l0Y2ggKHYpIHtcbiAgICAgIGNhc2UgUEhZU0lDQUxfUkVTT1VSQ0VfSURfUkVGRVJFTkNFOlxuICAgICAgICByZXR1cm4gcGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHY7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBGaWx0ZXJzIHRoZSBrZXlzIG9mIGFuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZmlsdGVyS2V5cyhvYmplY3Q6IG9iamVjdCwgcHJlZDogKGtleTogc3RyaW5nKSA9PiBib29sZWFuKSB7XG4gIHJldHVybiBPYmplY3QuZW50cmllcyhvYmplY3QpXG4gICAgLnJlZHVjZShcbiAgICAgIChhY2MsIFtrLCB2XSkgPT4gcHJlZChrKVxuICAgICAgICA/IHsgLi4uYWNjLCBba106IHYgfVxuICAgICAgICA6IGFjYyxcbiAgICAgIHt9LFxuICAgICk7XG59XG5cbmxldCBsYXRlc3RTZGtJbnN0YWxsZWQgPSBmYWxzZTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZvcmNlU2RrSW5zdGFsbGF0aW9uKCkge1xuICBsYXRlc3RTZGtJbnN0YWxsZWQgPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBJbnN0YWxscyBsYXRlc3QgQVdTIFNESyB2MlxuICovXG5mdW5jdGlvbiBpbnN0YWxsTGF0ZXN0U2RrKCk6IHZvaWQge1xuICBjb25zb2xlLmxvZygnSW5zdGFsbGluZyBsYXRlc3QgQVdTIFNESyB2MicpO1xuICAvLyBCb3RoIEhPTUUgYW5kIC0tcHJlZml4IGFyZSBuZWVkZWQgaGVyZSBiZWNhdXNlIC90bXAgaXMgdGhlIG9ubHkgd3JpdGFibGUgbG9jYXRpb25cbiAgZXhlY1N5bmMoJ0hPTUU9L3RtcCBucG0gaW5zdGFsbCBhd3Mtc2RrQDIgLS1wcm9kdWN0aW9uIC0tbm8tcGFja2FnZS1sb2NrIC0tbm8tc2F2ZSAtLXByZWZpeCAvdG1wJyk7XG4gIGxhdGVzdFNka0luc3RhbGxlZCA9IHRydWU7XG59XG5cbi8vIG5vIGN1cnJlbnRseSBwYXRjaGVkIHNlcnZpY2VzXG5jb25zdCBwYXRjaGVkU2VydmljZXM6IHsgc2VydmljZU5hbWU6IHN0cmluZzsgYXBpVmVyc2lvbnM6IHN0cmluZ1tdIH1bXSA9IFtdO1xuLyoqXG4gKiBQYXRjaGVzIHRoZSBBV1MgU0RLIGJ5IGxvYWRpbmcgc2VydmljZSBtb2RlbHMgaW4gdGhlIHNhbWUgbWFubmVyIGFzIHRoZSBhY3R1YWwgU0RLXG4gKi9cbmZ1bmN0aW9uIHBhdGNoU2RrKGF3c1NkazogYW55KTogYW55IHtcbiAgY29uc3QgYXBpTG9hZGVyID0gYXdzU2RrLmFwaUxvYWRlcjtcbiAgcGF0Y2hlZFNlcnZpY2VzLmZvckVhY2goKHsgc2VydmljZU5hbWUsIGFwaVZlcnNpb25zIH0pID0+IHtcbiAgICBjb25zdCBsb3dlclNlcnZpY2VOYW1lID0gc2VydmljZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoIWF3c1Nkay5TZXJ2aWNlLmhhc1NlcnZpY2UobG93ZXJTZXJ2aWNlTmFtZSkpIHtcbiAgICAgIGFwaUxvYWRlci5zZXJ2aWNlc1tsb3dlclNlcnZpY2VOYW1lXSA9IHt9O1xuICAgICAgYXdzU2RrW3NlcnZpY2VOYW1lXSA9IGF3c1Nkay5TZXJ2aWNlLmRlZmluZVNlcnZpY2UobG93ZXJTZXJ2aWNlTmFtZSwgYXBpVmVyc2lvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd3NTZGsuU2VydmljZS5hZGRWZXJzaW9ucyhhd3NTZGtbc2VydmljZU5hbWVdLCBhcGlWZXJzaW9ucyk7XG4gICAgfVxuICAgIGFwaVZlcnNpb25zLmZvckVhY2goYXBpVmVyc2lvbiA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXBpTG9hZGVyLnNlcnZpY2VzW2xvd2VyU2VydmljZU5hbWVdLCBhcGlWZXJzaW9uLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgIGNvbnN0IG1vZGVsRmlsZVByZWZpeCA9IGBhd3Mtc2RrLXBhdGNoLyR7bG93ZXJTZXJ2aWNlTmFtZX0tJHthcGlWZXJzaW9ufWA7XG4gICAgICAgICAgY29uc3QgbW9kZWwgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgYCR7bW9kZWxGaWxlUHJlZml4fS5zZXJ2aWNlLmpzb25gKSwgJ3V0Zi04JykpO1xuICAgICAgICAgIG1vZGVsLnBhZ2luYXRvcnMgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgYCR7bW9kZWxGaWxlUHJlZml4fS5wYWdpbmF0b3JzLmpzb25gKSwgJ3V0Zi04JykpLnBhZ2luYXRpb247XG4gICAgICAgICAgcmV0dXJuIG1vZGVsO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBhd3NTZGs7XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMsIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIHRyeSB7XG4gICAgbGV0IEFXUzogYW55O1xuICAgIGlmICghbGF0ZXN0U2RrSW5zdGFsbGVkICYmIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5JbnN0YWxsTGF0ZXN0QXdzU2RrID09PSAndHJ1ZScpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGluc3RhbGxMYXRlc3RTZGsoKTtcbiAgICAgICAgQVdTID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvYXdzLXNkaycpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgRmFpbGVkIHRvIGluc3RhbGwgbGF0ZXN0IEFXUyBTREsgdjI6ICR7ZX1gKTtcbiAgICAgICAgQVdTID0gcmVxdWlyZSgnYXdzLXNkaycpOyAvLyBGYWxsYmFjayB0byBwcmUtaW5zdGFsbGVkIHZlcnNpb25cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxhdGVzdFNka0luc3RhbGxlZCkge1xuICAgICAgQVdTID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvYXdzLXNkaycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBBV1MgPSByZXF1aXJlKCdhd3Mtc2RrJyk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBBV1MgPSBwYXRjaFNkayhBV1MpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUubG9nKGBGYWlsZWQgdG8gcGF0Y2ggQVdTIFNESzogJHtlfS4gUHJvY2VlZGluZyB3aXRoIHRoZSBpbnN0YWxsZWQgY29weS5gKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh7IC4uLmV2ZW50LCBSZXNwb25zZVVSTDogJy4uLicgfSkpO1xuICAgIGNvbnNvbGUubG9nKCdBV1MgU0RLIFZFUlNJT046ICcgKyBBV1MuVkVSU0lPTik7XG5cbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ3JlYXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ3JlYXRlKTtcbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlKTtcbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlKTtcbiAgICAvLyBEZWZhdWx0IHBoeXNpY2FsIHJlc291cmNlIGlkXG4gICAgbGV0IHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nO1xuICAgIHN3aXRjaCAoZXZlbnQuUmVxdWVzdFR5cGUpIHtcbiAgICAgIGNhc2UgJ0NyZWF0ZSc6XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGU/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLlVwZGF0ZT8ucGh5c2ljYWxSZXNvdXJjZUlkPy5pZCA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1VwZGF0ZSc6XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXNbZXZlbnQuUmVxdWVzdFR5cGVdPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgbGV0IGZsYXREYXRhOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgbGV0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBjYWxsOiBBd3NTZGtDYWxsIHwgdW5kZWZpbmVkID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzW2V2ZW50LlJlcXVlc3RUeXBlXTtcblxuICAgIGlmIChjYWxsKSB7XG5cbiAgICAgIGxldCBjcmVkZW50aWFscztcbiAgICAgIGlmIChjYWxsLmFzc3VtZWRSb2xlQXJuKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIFJvbGVBcm46IGNhbGwuYXNzdW1lZFJvbGVBcm4sXG4gICAgICAgICAgUm9sZVNlc3Npb25OYW1lOiBgJHt0aW1lc3RhbXB9LSR7cGh5c2ljYWxSZXNvdXJjZUlkfWAuc3Vic3RyaW5nKDAsIDY0KSxcbiAgICAgICAgfTtcblxuICAgICAgICBjcmVkZW50aWFscyA9IG5ldyBBV1MuQ2hhaW5hYmxlVGVtcG9yYXJ5Q3JlZGVudGlhbHMoe1xuICAgICAgICAgIHBhcmFtczogcGFyYW1zLFxuICAgICAgICAgIHN0c0NvbmZpZzogeyBzdHNSZWdpb25hbEVuZHBvaW50czogJ3JlZ2lvbmFsJyB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoQVdTLCBjYWxsLnNlcnZpY2UpKSB7XG4gICAgICAgIHRocm93IEVycm9yKGBTZXJ2aWNlICR7Y2FsbC5zZXJ2aWNlfSBkb2VzIG5vdCBleGlzdCBpbiBBV1MgU0RLIHZlcnNpb24gJHtBV1MuVkVSU0lPTn0uYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBhd3NTZXJ2aWNlID0gbmV3IChBV1MgYXMgYW55KVtjYWxsLnNlcnZpY2VdKHtcbiAgICAgICAgYXBpVmVyc2lvbjogY2FsbC5hcGlWZXJzaW9uLFxuICAgICAgICBjcmVkZW50aWFsczogY3JlZGVudGlhbHMsXG4gICAgICAgIHJlZ2lvbjogY2FsbC5yZWdpb24sXG4gICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBhd3NTZXJ2aWNlW2NhbGwuYWN0aW9uXShcbiAgICAgICAgICBjYWxsLnBhcmFtZXRlcnMgJiYgZGVjb2RlU3BlY2lhbFZhbHVlcyhjYWxsLnBhcmFtZXRlcnMsIHBoeXNpY2FsUmVzb3VyY2VJZCkpLnByb21pc2UoKTtcbiAgICAgICAgZmxhdERhdGEgPSB7XG4gICAgICAgICAgYXBpVmVyc2lvbjogYXdzU2VydmljZS5jb25maWcuYXBpVmVyc2lvbiwgLy8gRm9yIHRlc3QgcHVycG9zZXM6IGNoZWNrIGlmIGFwaVZlcnNpb24gd2FzIGNvcnJlY3RseSBwYXNzZWQuXG4gICAgICAgICAgcmVnaW9uOiBhd3NTZXJ2aWNlLmNvbmZpZy5yZWdpb24sIC8vIEZvciB0ZXN0IHB1cnBvc2VzOiBjaGVjayBpZiByZWdpb24gd2FzIGNvcnJlY3RseSBwYXNzZWQuXG4gICAgICAgICAgLi4uZmxhdHRlbihyZXNwb25zZSksXG4gICAgICAgIH07XG5cbiAgICAgICAgbGV0IG91dHB1dFBhdGhzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGNhbGwub3V0cHV0UGF0aCkge1xuICAgICAgICAgIG91dHB1dFBhdGhzID0gW2NhbGwub3V0cHV0UGF0aF07XG4gICAgICAgIH0gZWxzZSBpZiAoY2FsbC5vdXRwdXRQYXRocykge1xuICAgICAgICAgIG91dHB1dFBhdGhzID0gY2FsbC5vdXRwdXRQYXRocztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvdXRwdXRQYXRocykge1xuICAgICAgICAgIGRhdGEgPSBmaWx0ZXJLZXlzKGZsYXREYXRhLCBzdGFydHNXaXRoT25lT2Yob3V0cHV0UGF0aHMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhID0gZmxhdERhdGE7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBpZiAoIWNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nIHx8ICFuZXcgUmVnRXhwKGNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nKS50ZXN0KGUuY29kZSkpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjYWxsLnBoeXNpY2FsUmVzb3VyY2VJZD8ucmVzcG9uc2VQYXRoKSB7XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGZsYXREYXRhW2NhbGwucGh5c2ljYWxSZXNvdXJjZUlkLnJlc3BvbnNlUGF0aF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgcmVzcG9uZCgnU1VDQ0VTUycsICdPSycsIHBoeXNpY2FsUmVzb3VyY2VJZCwgZGF0YSk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNvbnNvbGUubG9nKGUpO1xuICAgIGF3YWl0IHJlc3BvbmQoJ0ZBSUxFRCcsIGUubWVzc2FnZSB8fCAnSW50ZXJuYWwgRXJyb3InLCBjb250ZXh0LmxvZ1N0cmVhbU5hbWUsIHt9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3BvbmQocmVzcG9uc2VTdGF0dXM6IHN0cmluZywgcmVhc29uOiBzdHJpbmcsIHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nLCBkYXRhOiBhbnkpIHtcbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBTdGF0dXM6IHJlc3BvbnNlU3RhdHVzLFxuICAgICAgUmVhc29uOiByZWFzb24sXG4gICAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCxcbiAgICAgIE5vRWNobzogZmFsc2UsXG4gICAgICBEYXRhOiBkYXRhLFxuICAgIH0pO1xuXG4gICAgY29uc29sZS5sb2coJ1Jlc3BvbmRpbmcnLCByZXNwb25zZUJvZHkpO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCBwYXJzZWRVcmwgPSByZXF1aXJlKCd1cmwnKS5wYXJzZShldmVudC5SZXNwb25zZVVSTCk7XG4gICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgICAgcGF0aDogcGFyc2VkVXJsLnBhdGgsXG4gICAgICBtZXRob2Q6ICdQVVQnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnY29udGVudC10eXBlJzogJycsXG4gICAgICAgICdjb250ZW50LWxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHJlc3BvbnNlQm9keSwgJ3V0ZjgnKSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnaHR0cHMnKS5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCByZXNvbHZlKTtcbiAgICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWNvZGVDYWxsKGNhbGw6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICBpZiAoIWNhbGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICByZXR1cm4gSlNPTi5wYXJzZShjYWxsKTtcbn1cblxuZnVuY3Rpb24gc3RhcnRzV2l0aE9uZU9mKHNlYXJjaFN0cmluZ3M6IHN0cmluZ1tdKTogKHN0cmluZzogc3RyaW5nKSA9PiBib29sZWFuIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBzZWFyY2hTdHJpbmcgb2Ygc2VhcmNoU3RyaW5ncykge1xuICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKHNlYXJjaFN0cmluZykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbn1cbiJdfQ==
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3.bundle/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3.bundle/index.js
new file mode 100644
index 0000000000000..a54f75c9c3747
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/asset.ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3.bundle/index.js
@@ -0,0 +1,1295 @@
+var __create = Object.create;
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __getProtoOf = Object.getPrototypeOf;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __esm = (fn, res) => function __init() {
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
+};
+var __commonJS = (cb, mod) => function __require() {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
+ // If the importer is in node compatibility mode or this is not an ESM
+ // file that has been converted to a CommonJS file using a Babel-
+ // compatible transform (i.e. "__esModule" has not been set), then set
+ // "default" to the CommonJS "module.exports" for node compatibility.
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
+ mod
+));
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// ../../aws-cdk-lib/assertions/lib/matcher.ts
+var matcher_exports = {};
+__export(matcher_exports, {
+ MatchResult: () => MatchResult,
+ Matcher: () => Matcher
+});
+function* range(n) {
+ for (let i = 0; i < n; i++) {
+ yield i;
+ }
+}
+function* enumFirst(xs) {
+ let first = true;
+ for (const x of xs) {
+ yield [first, x];
+ first = false;
+ }
+}
+var Matcher, MatchResult;
+var init_matcher = __esm({
+ "../../aws-cdk-lib/assertions/lib/matcher.ts"() {
+ "use strict";
+ Matcher = class {
+ /**
+ * Check whether the provided object is a subtype of the `IMatcher`.
+ */
+ static isMatcher(x) {
+ return x && x instanceof Matcher;
+ }
+ };
+ MatchResult = class {
+ constructor(target) {
+ this.failuresHere = /* @__PURE__ */ new Map();
+ this.captures = /* @__PURE__ */ new Map();
+ this.finalized = false;
+ this.innerMatchFailures = /* @__PURE__ */ new Map();
+ this._hasFailed = false;
+ this._failCount = 0;
+ this._cost = 0;
+ this.target = target;
+ }
+ /**
+ * DEPRECATED
+ * @deprecated use recordFailure()
+ */
+ push(matcher, path, message) {
+ return this.recordFailure({ matcher, path, message });
+ }
+ /**
+ * Record a new failure into this result at a specific path.
+ */
+ recordFailure(failure) {
+ const failKey = failure.path.join(".");
+ let list = this.failuresHere.get(failKey);
+ if (!list) {
+ list = [];
+ this.failuresHere.set(failKey, list);
+ }
+ this._failCount += 1;
+ this._cost += failure.cost ?? 1;
+ list.push(failure);
+ this._hasFailed = true;
+ return this;
+ }
+ /** Whether the match is a success */
+ get isSuccess() {
+ return !this._hasFailed;
+ }
+ /** Does the result contain any failures. If not, the result is a success */
+ hasFailed() {
+ return this._hasFailed;
+ }
+ /** The number of failures */
+ get failCount() {
+ return this._failCount;
+ }
+ /** The cost of the failures so far */
+ get failCost() {
+ return this._cost;
+ }
+ /**
+ * Compose the results of a previous match as a subtree.
+ * @param id the id of the parent tree.
+ */
+ compose(id, inner) {
+ if (inner.hasFailed()) {
+ this._hasFailed = true;
+ this._failCount += inner.failCount;
+ this._cost += inner._cost;
+ this.innerMatchFailures.set(id, inner);
+ }
+ inner.captures.forEach((vals, capture) => {
+ vals.forEach((value) => this.recordCapture({ capture, value }));
+ });
+ return this;
+ }
+ /**
+ * Prepare the result to be analyzed.
+ * This API *must* be called prior to analyzing these results.
+ */
+ finished() {
+ if (this.finalized) {
+ return this;
+ }
+ if (this.failCount === 0) {
+ this.captures.forEach((vals, cap) => cap._captured.push(...vals));
+ }
+ this.finalized = true;
+ return this;
+ }
+ /**
+ * Render the failed match in a presentable way
+ *
+ * Prefer using `renderMismatch` over this method. It is left for backwards
+ * compatibility for test suites that expect it, but `renderMismatch()` will
+ * produce better output.
+ */
+ toHumanStrings() {
+ const failures = new Array();
+ debugger;
+ recurse(this, []);
+ return failures.map((r) => {
+ const loc = r.path.length === 0 ? "" : ` at /${r.path.join("/")}`;
+ return "" + r.message + loc + ` (using ${r.matcher.name} matcher)`;
+ });
+ function recurse(x, prefix) {
+ for (const fail of Array.from(x.failuresHere.values()).flat()) {
+ failures.push({
+ matcher: fail.matcher,
+ message: fail.message,
+ path: [...prefix, ...fail.path]
+ });
+ }
+ for (const [key, inner] of x.innerMatchFailures.entries()) {
+ recurse(inner, [...prefix, key]);
+ }
+ }
+ }
+ /**
+ * Do a deep render of the match result, showing the structure mismatches in context
+ */
+ renderMismatch() {
+ if (!this.hasFailed()) {
+ return "";
+ }
+ const parts = new Array();
+ const indents = new Array();
+ emitFailures(this, "");
+ recurse(this);
+ return moveMarkersToFront(parts.join("").trimEnd());
+ function emit(x) {
+ if (x === void 0) {
+ debugger;
+ }
+ parts.push(x.replace(/\n/g, `
+${indents.join("")}`));
+ }
+ function emitFailures(r, path, scrapSet) {
+ for (const fail of r.failuresHere.get(path) ?? []) {
+ emit(`!! ${fail.message}
+`);
+ }
+ scrapSet == null ? void 0 : scrapSet.delete(path);
+ }
+ function recurse(r) {
+ const remainingFailures = new Set(Array.from(r.failuresHere.keys()).filter((x) => x !== ""));
+ if (Array.isArray(r.target)) {
+ indents.push(" ");
+ emit("[\n");
+ for (const [first, i] of enumFirst(range(r.target.length))) {
+ if (!first) {
+ emit(",\n");
+ }
+ emitFailures(r, `${i}`, remainingFailures);
+ const innerMatcher = r.innerMatchFailures.get(`${i}`);
+ if (innerMatcher) {
+ emitFailures(innerMatcher, "");
+ recurseComparingValues(innerMatcher, r.target[i]);
+ } else {
+ emit(renderAbridged(r.target[i]));
+ }
+ }
+ emitRemaining();
+ indents.pop();
+ emit("\n]");
+ return;
+ }
+ if (r.target && typeof r.target === "object") {
+ indents.push(" ");
+ emit("{\n");
+ const keys = Array.from(/* @__PURE__ */ new Set([
+ ...Object.keys(r.target),
+ ...Array.from(remainingFailures)
+ ])).sort();
+ for (const [first, key] of enumFirst(keys)) {
+ if (!first) {
+ emit(",\n");
+ }
+ emitFailures(r, key, remainingFailures);
+ const innerMatcher = r.innerMatchFailures.get(key);
+ if (innerMatcher) {
+ emitFailures(innerMatcher, "");
+ emit(`${jsonify(key)}: `);
+ recurseComparingValues(innerMatcher, r.target[key]);
+ } else {
+ emit(`${jsonify(key)}: `);
+ emit(renderAbridged(r.target[key]));
+ }
+ }
+ emitRemaining();
+ indents.pop();
+ emit("\n}");
+ return;
+ }
+ emitRemaining();
+ emit(jsonify(r.target));
+ function emitRemaining() {
+ if (remainingFailures.size > 0) {
+ emit("\n");
+ }
+ for (const key of remainingFailures) {
+ emitFailures(r, key);
+ }
+ }
+ }
+ function recurseComparingValues(inner, actualValue) {
+ if (inner.target === actualValue) {
+ return recurse(inner);
+ }
+ emit(renderAbridged(actualValue));
+ emit(" <*> ");
+ recurse(inner);
+ }
+ function renderAbridged(x) {
+ if (Array.isArray(x)) {
+ switch (x.length) {
+ case 0:
+ return "[]";
+ case 1:
+ return `[ ${renderAbridged(x[0])} ]`;
+ case 2:
+ if (x.every((e) => ["number", "boolean", "string"].includes(typeof e))) {
+ return `[ ${x.map(renderAbridged).join(", ")} ]`;
+ }
+ return "[ ... ]";
+ default:
+ return "[ ... ]";
+ }
+ }
+ if (x && typeof x === "object") {
+ const keys = Object.keys(x);
+ switch (keys.length) {
+ case 0:
+ return "{}";
+ case 1:
+ return `{ ${JSON.stringify(keys[0])}: ${renderAbridged(x[keys[0]])} }`;
+ default:
+ return "{ ... }";
+ }
+ }
+ return jsonify(x);
+ }
+ function jsonify(x) {
+ return JSON.stringify(x) ?? "undefined";
+ }
+ function moveMarkersToFront(x) {
+ const re = /^(\s+)!!/gm;
+ return x.replace(re, (_, spaces) => `!!${spaces.substring(0, spaces.length - 2)}`);
+ }
+ }
+ /**
+ * Record a capture against in this match result.
+ */
+ recordCapture(options) {
+ let values = this.captures.get(options.capture);
+ if (values === void 0) {
+ values = [];
+ }
+ values.push(options.value);
+ this.captures.set(options.capture, values);
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/matchers/absent.ts
+var AbsentMatch;
+var init_absent = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/matchers/absent.ts"() {
+ "use strict";
+ init_matcher();
+ AbsentMatch = class extends Matcher {
+ constructor(name) {
+ super();
+ this.name = name;
+ }
+ test(actual) {
+ const result = new MatchResult(actual);
+ if (actual !== void 0) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Received ${actual}, but key should be absent`
+ });
+ }
+ return result;
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/sorting.ts
+function sortKeyComparator(keyFn) {
+ return (a, b) => {
+ const ak = keyFn(a);
+ const bk = keyFn(b);
+ for (let i = 0; i < ak.length && i < bk.length; i++) {
+ const av = ak[i];
+ const bv = bk[i];
+ let diff = 0;
+ if (typeof av === "number" && typeof bv === "number") {
+ diff = av - bv;
+ } else if (typeof av === "string" && typeof bv === "string") {
+ diff = av.localeCompare(bv);
+ }
+ if (diff !== 0) {
+ return diff;
+ }
+ }
+ return bk.length - ak.length;
+ };
+}
+var init_sorting = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/sorting.ts"() {
+ "use strict";
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/sparse-matrix.ts
+var SparseMatrix;
+var init_sparse_matrix = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/sparse-matrix.ts"() {
+ "use strict";
+ SparseMatrix = class {
+ constructor() {
+ this.matrix = /* @__PURE__ */ new Map();
+ }
+ get(row, col) {
+ var _a;
+ return (_a = this.matrix.get(row)) == null ? void 0 : _a.get(col);
+ }
+ row(row) {
+ var _a;
+ return Array.from(((_a = this.matrix.get(row)) == null ? void 0 : _a.entries()) ?? []);
+ }
+ set(row, col, value) {
+ let r = this.matrix.get(row);
+ if (!r) {
+ r = /* @__PURE__ */ new Map();
+ this.matrix.set(row, r);
+ }
+ r.set(col, value);
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/type.ts
+function getType(obj) {
+ return Array.isArray(obj) ? "array" : typeof obj;
+}
+var init_type = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/type.ts"() {
+ "use strict";
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/match.ts
+var match_exports = {};
+__export(match_exports, {
+ Match: () => Match
+});
+var Match, LiteralMatch, ArrayMatch, ObjectMatch, SerializedJson, NotMatch, AnyMatch, StringLikeRegexpMatch;
+var init_match = __esm({
+ "../../aws-cdk-lib/assertions/lib/match.ts"() {
+ "use strict";
+ init_matcher();
+ init_absent();
+ init_sorting();
+ init_sparse_matrix();
+ init_type();
+ Match = class {
+ /**
+ * Use this matcher in the place of a field's value, if the field must not be present.
+ */
+ static absent() {
+ return new AbsentMatch("absent");
+ }
+ /**
+ * Matches the specified pattern with the array found in the same relative path of the target.
+ * The set of elements (or matchers) must be in the same order as would be found.
+ * @param pattern the pattern to match
+ */
+ static arrayWith(pattern) {
+ return new ArrayMatch("arrayWith", pattern);
+ }
+ /**
+ * Matches the specified pattern with the array found in the same relative path of the target.
+ * The set of elements (or matchers) must match exactly and in order.
+ * @param pattern the pattern to match
+ */
+ static arrayEquals(pattern) {
+ return new ArrayMatch("arrayEquals", pattern, { subsequence: false });
+ }
+ /**
+ * Deep exact matching of the specified pattern to the target.
+ * @param pattern the pattern to match
+ */
+ static exact(pattern) {
+ return new LiteralMatch("exact", pattern, { partialObjects: false });
+ }
+ /**
+ * Matches the specified pattern to an object found in the same relative path of the target.
+ * The keys and their values (or matchers) must be present in the target but the target can be a superset.
+ * @param pattern the pattern to match
+ */
+ static objectLike(pattern) {
+ return new ObjectMatch("objectLike", pattern);
+ }
+ /**
+ * Matches the specified pattern to an object found in the same relative path of the target.
+ * The keys and their values (or matchers) must match exactly with the target.
+ * @param pattern the pattern to match
+ */
+ static objectEquals(pattern) {
+ return new ObjectMatch("objectEquals", pattern, { partial: false });
+ }
+ /**
+ * Matches any target which does NOT follow the specified pattern.
+ * @param pattern the pattern to NOT match
+ */
+ static not(pattern) {
+ return new NotMatch("not", pattern);
+ }
+ /**
+ * Matches any string-encoded JSON and applies the specified pattern after parsing it.
+ * @param pattern the pattern to match after parsing the encoded JSON.
+ */
+ static serializedJson(pattern) {
+ return new SerializedJson("serializedJson", pattern);
+ }
+ /**
+ * Matches any non-null value at the target.
+ */
+ static anyValue() {
+ return new AnyMatch("anyValue");
+ }
+ /**
+ * Matches targets according to a regular expression
+ */
+ static stringLikeRegexp(pattern) {
+ return new StringLikeRegexpMatch("stringLikeRegexp", pattern);
+ }
+ };
+ LiteralMatch = class extends Matcher {
+ constructor(name, pattern, options = {}) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ this.partialObjects = options.partialObjects ?? false;
+ if (Matcher.isMatcher(this.pattern)) {
+ throw new Error("LiteralMatch cannot directly contain another matcher. Remove the top-level matcher or nest it more deeply.");
+ }
+ }
+ test(actual) {
+ if (Array.isArray(this.pattern)) {
+ return new ArrayMatch(this.name, this.pattern, { subsequence: false, partialObjects: this.partialObjects }).test(actual);
+ }
+ if (typeof this.pattern === "object") {
+ return new ObjectMatch(this.name, this.pattern, { partial: this.partialObjects }).test(actual);
+ }
+ const result = new MatchResult(actual);
+ if (typeof this.pattern !== typeof actual) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected type ${typeof this.pattern} but received ${getType(actual)}`
+ });
+ return result;
+ }
+ if (actual !== this.pattern) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected ${this.pattern} but received ${actual}`
+ });
+ }
+ return result;
+ }
+ };
+ ArrayMatch = class extends Matcher {
+ constructor(name, pattern, options = {}) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ this.subsequence = options.subsequence ?? true;
+ this.partialObjects = options.partialObjects ?? false;
+ }
+ test(actual) {
+ if (!Array.isArray(actual)) {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected type array but received ${getType(actual)}`
+ });
+ }
+ return this.subsequence ? this.testSubsequence(actual) : this.testFullArray(actual);
+ }
+ testFullArray(actual) {
+ const result = new MatchResult(actual);
+ let i = 0;
+ for (; i < this.pattern.length && i < actual.length; i++) {
+ const patternElement = this.pattern[i];
+ const matcher = Matcher.isMatcher(patternElement) ? patternElement : new LiteralMatch(this.name, patternElement, { partialObjects: this.partialObjects });
+ const innerResult = matcher.test(actual[i]);
+ result.compose(`${i}`, innerResult);
+ }
+ if (i < this.pattern.length) {
+ result.recordFailure({
+ matcher: this,
+ message: `Not enough elements in array (expecting ${this.pattern.length}, got ${actual.length})`,
+ path: [`${i}`]
+ });
+ }
+ if (i < actual.length) {
+ result.recordFailure({
+ matcher: this,
+ message: `Too many elements in array (expecting ${this.pattern.length}, got ${actual.length})`,
+ path: [`${i}`]
+ });
+ }
+ return result;
+ }
+ testSubsequence(actual) {
+ const result = new MatchResult(actual);
+ let patternIdx = 0;
+ let actualIdx = 0;
+ const matches = new SparseMatrix();
+ while (patternIdx < this.pattern.length && actualIdx < actual.length) {
+ const patternElement = this.pattern[patternIdx];
+ const matcher = Matcher.isMatcher(patternElement) ? patternElement : new LiteralMatch(this.name, patternElement, { partialObjects: this.partialObjects });
+ const matcherName = matcher.name;
+ if (matcherName == "absent" || matcherName == "anyValue") {
+ throw new Error(`The Matcher ${matcherName}() cannot be nested within arrayWith()`);
+ }
+ const innerResult = matcher.test(actual[actualIdx]);
+ matches.set(patternIdx, actualIdx, innerResult);
+ actualIdx++;
+ if (innerResult.isSuccess) {
+ result.compose(`${actualIdx}`, innerResult);
+ patternIdx++;
+ }
+ }
+ if (patternIdx < this.pattern.length) {
+ for (let spi = 0; spi < patternIdx; spi++) {
+ const foundMatch = matches.row(spi).find(([, r]) => r.isSuccess);
+ if (!foundMatch) {
+ continue;
+ }
+ const [index] = foundMatch;
+ result.compose(`${index}`, new MatchResult(actual[index]).recordFailure({
+ matcher: this,
+ message: `arrayWith pattern ${spi} matched here`,
+ path: [],
+ cost: 0
+ // This is an informational message so it would be unfair to assign it cost
+ }));
+ }
+ const failedMatches = matches.row(patternIdx);
+ failedMatches.sort(sortKeyComparator(([i, r]) => [r.failCost, i]));
+ if (failedMatches.length > 0) {
+ const [index, innerResult] = failedMatches[0];
+ result.recordFailure({
+ matcher: this,
+ message: `Could not match arrayWith pattern ${patternIdx}. This is the closest match`,
+ path: [`${index}`],
+ cost: 0
+ // Informational message
+ });
+ result.compose(`${index}`, innerResult);
+ } else {
+ result.recordFailure({
+ matcher: this,
+ message: `Could not match arrayWith pattern ${patternIdx}. No more elements to try`,
+ path: [`${actual.length}`]
+ });
+ }
+ }
+ return result;
+ }
+ };
+ ObjectMatch = class extends Matcher {
+ constructor(name, pattern, options = {}) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ this.partial = options.partial ?? true;
+ }
+ test(actual) {
+ if (typeof actual !== "object" || Array.isArray(actual)) {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected type object but received ${getType(actual)}`
+ });
+ }
+ const result = new MatchResult(actual);
+ if (!this.partial) {
+ for (const a of Object.keys(actual)) {
+ if (!(a in this.pattern)) {
+ result.recordFailure({
+ matcher: this,
+ path: [a],
+ message: `Unexpected key ${a}`
+ });
+ }
+ }
+ }
+ for (const [patternKey, patternVal] of Object.entries(this.pattern)) {
+ if (!(patternKey in actual) && !(patternVal instanceof AbsentMatch)) {
+ result.recordFailure({
+ matcher: this,
+ path: [patternKey],
+ message: `Missing key '${patternKey}'`
+ });
+ continue;
+ }
+ const matcher = Matcher.isMatcher(patternVal) ? patternVal : new LiteralMatch(this.name, patternVal, { partialObjects: this.partial });
+ const inner = matcher.test(actual[patternKey]);
+ result.compose(patternKey, inner);
+ }
+ return result;
+ }
+ };
+ SerializedJson = class extends Matcher {
+ constructor(name, pattern) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ }
+ test(actual) {
+ if (getType(actual) !== "string") {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected JSON as a string but found ${getType(actual)}`
+ });
+ }
+ let parsed;
+ try {
+ parsed = JSON.parse(actual);
+ } catch (err) {
+ if (err instanceof SyntaxError) {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Invalid JSON string: ${actual}`
+ });
+ } else {
+ throw err;
+ }
+ }
+ const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern);
+ const innerResult = matcher.test(parsed);
+ if (innerResult.hasFailed()) {
+ innerResult.recordFailure({
+ matcher: this,
+ path: [],
+ message: "Encoded JSON value does not match"
+ });
+ }
+ return innerResult;
+ }
+ };
+ NotMatch = class extends Matcher {
+ constructor(name, pattern) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ }
+ test(actual) {
+ const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern);
+ const innerResult = matcher.test(actual);
+ const result = new MatchResult(actual);
+ if (innerResult.failCount === 0) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Found unexpected match: ${JSON.stringify(actual, void 0, 2)}`
+ });
+ }
+ return result;
+ }
+ };
+ AnyMatch = class extends Matcher {
+ constructor(name) {
+ super();
+ this.name = name;
+ }
+ test(actual) {
+ const result = new MatchResult(actual);
+ if (actual == null) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: "Expected a value but found none"
+ });
+ }
+ return result;
+ }
+ };
+ StringLikeRegexpMatch = class extends Matcher {
+ constructor(name, pattern) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ }
+ test(actual) {
+ const result = new MatchResult(actual);
+ const regex = new RegExp(this.pattern, "gm");
+ if (typeof actual !== "string") {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected a string, but got '${typeof actual}'`
+ });
+ }
+ if (!regex.test(actual)) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `String '${actual}' did not match pattern '${this.pattern}'`
+ });
+ }
+ return result;
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/helpers-internal/index.js
+var require_helpers_internal = __commonJS({
+ "../../aws-cdk-lib/assertions/lib/helpers-internal/index.js"(exports) {
+ "use strict";
+ var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
+ if (k2 === void 0)
+ k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() {
+ return m[k];
+ } };
+ }
+ Object.defineProperty(o, k2, desc);
+ } : function(o, m, k, k2) {
+ if (k2 === void 0)
+ k2 = k;
+ o[k2] = m[k];
+ });
+ var __exportStar = exports && exports.__exportStar || function(m, exports2) {
+ for (var p in m)
+ if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
+ __createBinding(exports2, m, p);
+ };
+ Object.defineProperty(exports, "__esModule", { value: true });
+ __exportStar((init_match(), __toCommonJS(match_exports)), exports);
+ __exportStar((init_matcher(), __toCommonJS(matcher_exports)), exports);
+ }
+});
+
+// lib/assertions/providers/lambda-handler/index.ts
+var lambda_handler_exports = {};
+__export(lambda_handler_exports, {
+ handler: () => handler,
+ isComplete: () => isComplete,
+ onTimeout: () => onTimeout
+});
+module.exports = __toCommonJS(lambda_handler_exports);
+
+// lib/assertions/providers/lambda-handler/assertion.ts
+var import_helpers_internal = __toESM(require_helpers_internal());
+
+// lib/assertions/providers/lambda-handler/base.ts
+var https = __toESM(require("https"));
+var url = __toESM(require("url"));
+var AWS = __toESM(require("aws-sdk"));
+var CustomResourceHandler = class {
+ constructor(event, context) {
+ this.event = event;
+ this.context = context;
+ this.timedOut = false;
+ this.timeout = setTimeout(async () => {
+ await this.respond({
+ status: "FAILED",
+ reason: "Lambda Function Timeout",
+ data: this.context.logStreamName
+ });
+ this.timedOut = true;
+ }, context.getRemainingTimeInMillis() - 1200);
+ this.event = event;
+ this.physicalResourceId = extractPhysicalResourceId(event);
+ }
+ /**
+ * Handles executing the custom resource event. If `stateMachineArn` is present
+ * in the props then trigger the waiter statemachine
+ */
+ async handle() {
+ try {
+ if ("stateMachineArn" in this.event.ResourceProperties) {
+ const req = {
+ stateMachineArn: this.event.ResourceProperties.stateMachineArn,
+ name: this.event.RequestId,
+ input: JSON.stringify(this.event)
+ };
+ await this.startExecution(req);
+ return;
+ } else {
+ const response = await this.processEvent(this.event.ResourceProperties);
+ return response;
+ }
+ } catch (e) {
+ console.log(e);
+ throw e;
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ }
+ /**
+ * Handle async requests from the waiter state machine
+ */
+ async handleIsComplete() {
+ try {
+ const result = await this.processEvent(this.event.ResourceProperties);
+ return result;
+ } catch (e) {
+ console.log(e);
+ return;
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ }
+ /**
+ * Start a step function state machine which will wait for the request
+ * to be successful.
+ */
+ async startExecution(req) {
+ try {
+ const sfn = new AWS.StepFunctions();
+ await sfn.startExecution(req).promise();
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ }
+ respond(response) {
+ if (this.timedOut) {
+ return;
+ }
+ const cfResponse = {
+ Status: response.status,
+ Reason: response.reason,
+ PhysicalResourceId: this.physicalResourceId,
+ StackId: this.event.StackId,
+ RequestId: this.event.RequestId,
+ LogicalResourceId: this.event.LogicalResourceId,
+ NoEcho: false,
+ Data: response.data
+ };
+ const responseBody = JSON.stringify(cfResponse);
+ console.log("Responding to CloudFormation", responseBody);
+ const parsedUrl = url.parse(this.event.ResponseURL);
+ const requestOptions = {
+ hostname: parsedUrl.hostname,
+ path: parsedUrl.path,
+ method: "PUT",
+ headers: {
+ "content-type": "",
+ "content-length": Buffer.byteLength(responseBody, "utf8")
+ }
+ };
+ return new Promise((resolve, reject) => {
+ try {
+ const request2 = https.request(requestOptions, resolve);
+ request2.on("error", reject);
+ request2.write(responseBody);
+ request2.end();
+ } catch (e) {
+ reject(e);
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ });
+ }
+};
+function extractPhysicalResourceId(event) {
+ switch (event.RequestType) {
+ case "Create":
+ return event.LogicalResourceId;
+ case "Update":
+ case "Delete":
+ return event.PhysicalResourceId;
+ }
+}
+
+// lib/assertions/providers/lambda-handler/assertion.ts
+var AssertionHandler = class extends CustomResourceHandler {
+ async processEvent(request2) {
+ let actual = decodeCall(request2.actual);
+ const expected = decodeCall(request2.expected);
+ let result;
+ const matcher = new MatchCreator(expected).getMatcher();
+ console.log(`Testing equality between ${JSON.stringify(request2.actual)} and ${JSON.stringify(request2.expected)}`);
+ const matchResult = matcher.test(actual);
+ matchResult.finished();
+ if (matchResult.hasFailed()) {
+ result = {
+ failed: true,
+ assertion: JSON.stringify({
+ status: "fail",
+ message: matchResult.renderMismatch()
+ })
+ };
+ if (request2.failDeployment) {
+ throw new Error(result.assertion);
+ }
+ } else {
+ result = {
+ assertion: JSON.stringify({
+ status: "success"
+ })
+ };
+ }
+ return result;
+ }
+};
+var MatchCreator = class {
+ constructor(obj) {
+ this.parsedObj = {
+ matcher: obj
+ };
+ }
+ /**
+ * Return a Matcher that can be tested against the actual results.
+ * This will convert the encoded matchers into their corresponding
+ * assertions matcher.
+ *
+ * For example:
+ *
+ * ExpectedResult.objectLike({
+ * Messages: [{
+ * Body: Match.objectLike({
+ * Elements: Match.arrayWith([{ Asdf: 3 }]),
+ * Payload: Match.serializedJson({ key: 'value' }),
+ * }),
+ * }],
+ * });
+ *
+ * Will be encoded as:
+ * {
+ * $ObjectLike: {
+ * Messages: [{
+ * Body: {
+ * $ObjectLike: {
+ * Elements: {
+ * $ArrayWith: [{ Asdf: 3 }],
+ * },
+ * Payload: {
+ * $SerializedJson: { key: 'value' }
+ * }
+ * },
+ * },
+ * }],
+ * },
+ * }
+ *
+ * Which can then be parsed by this function. For each key (recursively)
+ * the parser will check if the value has one of the encoded matchers as a key
+ * and if so, it will set the value as the Matcher. So,
+ *
+ * {
+ * Body: {
+ * $ObjectLike: {
+ * Elements: {
+ * $ArrayWith: [{ Asdf: 3 }],
+ * },
+ * Payload: {
+ * $SerializedJson: { key: 'value' }
+ * }
+ * },
+ * },
+ * }
+ *
+ * Will be converted to
+ * {
+ * Body: Match.objectLike({
+ * Elements: Match.arrayWith([{ Asdf: 3 }]),
+ * Payload: Match.serializedJson({ key: 'value' }),
+ * }),
+ * }
+ */
+ getMatcher() {
+ try {
+ const final = JSON.parse(JSON.stringify(this.parsedObj), function(_k, v) {
+ const nested = Object.keys(v)[0];
+ switch (nested) {
+ case "$ArrayWith":
+ return import_helpers_internal.Match.arrayWith(v[nested]);
+ case "$ObjectLike":
+ return import_helpers_internal.Match.objectLike(v[nested]);
+ case "$StringLike":
+ return import_helpers_internal.Match.stringLikeRegexp(v[nested]);
+ case "$SerializedJson":
+ return import_helpers_internal.Match.serializedJson(v[nested]);
+ default:
+ return v;
+ }
+ });
+ if (import_helpers_internal.Matcher.isMatcher(final.matcher)) {
+ return final.matcher;
+ }
+ return import_helpers_internal.Match.exact(final.matcher);
+ } catch {
+ return import_helpers_internal.Match.exact(this.parsedObj.matcher);
+ }
+ }
+};
+function decodeCall(call) {
+ if (!call) {
+ return void 0;
+ }
+ try {
+ const parsed = JSON.parse(call);
+ return parsed;
+ } catch {
+ return call;
+ }
+}
+
+// lib/assertions/providers/lambda-handler/utils.ts
+function decode(object) {
+ return JSON.parse(JSON.stringify(object), (_k, v) => {
+ switch (v) {
+ case "TRUE:BOOLEAN":
+ return true;
+ case "FALSE:BOOLEAN":
+ return false;
+ default:
+ return v;
+ }
+ });
+}
+
+// lib/assertions/providers/lambda-handler/sdk.ts
+function flatten(object) {
+ return Object.assign(
+ {},
+ ...function _flatten(child, path = []) {
+ return [].concat(...Object.keys(child).map((key) => {
+ let childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key];
+ if (typeof childKey === "string") {
+ childKey = isJsonString(childKey);
+ }
+ return typeof childKey === "object" && childKey !== null ? _flatten(childKey, path.concat([key])) : { [path.concat([key]).join(".")]: childKey };
+ }));
+ }(object)
+ );
+}
+var AwsApiCallHandler = class extends CustomResourceHandler {
+ async processEvent(request2) {
+ const AWS2 = require("aws-sdk");
+ console.log(`AWS SDK VERSION: ${AWS2.VERSION}`);
+ if (!Object.prototype.hasOwnProperty.call(AWS2, request2.service)) {
+ throw Error(`Service ${request2.service} does not exist in AWS SDK version ${AWS2.VERSION}.`);
+ }
+ const service = new AWS2[request2.service]();
+ const response = await service[request2.api](request2.parameters && decode(request2.parameters)).promise();
+ console.log(`SDK response received ${JSON.stringify(response)}`);
+ delete response.ResponseMetadata;
+ const respond = {
+ apiCallResponse: response
+ };
+ const flatData = {
+ ...flatten(respond)
+ };
+ let resp = respond;
+ if (request2.outputPaths) {
+ resp = filterKeys(flatData, request2.outputPaths);
+ } else if (request2.flattenResponse === "true") {
+ resp = flatData;
+ }
+ console.log(`Returning result ${JSON.stringify(resp)}`);
+ return resp;
+ }
+};
+function filterKeys(object, searchStrings) {
+ return Object.entries(object).reduce((filteredObject, [key, value]) => {
+ for (const searchString of searchStrings) {
+ if (key.startsWith(`apiCallResponse.${searchString}`)) {
+ filteredObject[key] = value;
+ }
+ }
+ return filteredObject;
+ }, {});
+}
+function isJsonString(value) {
+ try {
+ return JSON.parse(value);
+ } catch {
+ return value;
+ }
+}
+
+// lib/assertions/providers/lambda-handler/types.ts
+var ASSERT_RESOURCE_TYPE = "Custom::DeployAssert@AssertEquals";
+var SDK_RESOURCE_TYPE_PREFIX = "Custom::DeployAssert@SdkCall";
+
+// lib/assertions/providers/lambda-handler/index.ts
+async function handler(event, context) {
+ console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`);
+ const provider = createResourceHandler(event, context);
+ try {
+ if (event.RequestType === "Delete") {
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK"
+ });
+ return;
+ }
+ const result = await provider.handle();
+ if ("stateMachineArn" in event.ResourceProperties) {
+ console.info('Found "stateMachineArn", waiter statemachine started');
+ return;
+ } else if ("expected" in event.ResourceProperties) {
+ console.info('Found "expected", testing assertions');
+ const actualPath = event.ResourceProperties.actualPath;
+ const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse;
+ const assertion = new AssertionHandler({
+ ...event,
+ ResourceProperties: {
+ ServiceToken: event.ServiceToken,
+ actual,
+ expected: event.ResourceProperties.expected
+ }
+ }, context);
+ try {
+ const assertionResult = await assertion.handle();
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ // return both the result of the API call _and_ the assertion results
+ data: {
+ ...assertionResult,
+ ...result
+ }
+ });
+ return;
+ } catch (e) {
+ await provider.respond({
+ status: "FAILED",
+ reason: e.message ?? "Internal Error"
+ });
+ return;
+ }
+ }
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ data: result
+ });
+ } catch (e) {
+ await provider.respond({
+ status: "FAILED",
+ reason: e.message ?? "Internal Error"
+ });
+ return;
+ }
+ return;
+}
+async function onTimeout(timeoutEvent) {
+ const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage);
+ const provider = createResourceHandler(isCompleteRequest, standardContext);
+ await provider.respond({
+ status: "FAILED",
+ reason: "Operation timed out: " + JSON.stringify(isCompleteRequest)
+ });
+}
+async function isComplete(event, context) {
+ console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`);
+ const provider = createResourceHandler(event, context);
+ try {
+ const result = await provider.handleIsComplete();
+ const actualPath = event.ResourceProperties.actualPath;
+ if (result) {
+ const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse;
+ if ("expected" in event.ResourceProperties) {
+ const assertion = new AssertionHandler({
+ ...event,
+ ResourceProperties: {
+ ServiceToken: event.ServiceToken,
+ actual,
+ expected: event.ResourceProperties.expected
+ }
+ }, context);
+ const assertionResult = await assertion.handleIsComplete();
+ if (!(assertionResult == null ? void 0 : assertionResult.failed)) {
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ data: {
+ ...assertionResult,
+ ...result
+ }
+ });
+ return;
+ } else {
+ console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`);
+ throw new Error(JSON.stringify(event));
+ }
+ }
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ data: result
+ });
+ } else {
+ console.log("No result");
+ throw new Error(JSON.stringify(event));
+ }
+ return;
+ } catch (e) {
+ console.log(e);
+ throw new Error(JSON.stringify(event));
+ }
+}
+function createResourceHandler(event, context) {
+ if (event.ResourceType.startsWith(SDK_RESOURCE_TYPE_PREFIX)) {
+ return new AwsApiCallHandler(event, context);
+ } else if (event.ResourceType.startsWith(ASSERT_RESOURCE_TYPE)) {
+ return new AssertionHandler(event, context);
+ } else {
+ throw new Error(`Unsupported resource type "${event.ResourceType}`);
+ }
+}
+var standardContext = {
+ getRemainingTimeInMillis: () => 9e4
+};
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+ handler,
+ isComplete,
+ onTimeout
+});
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/cdk.out
index 588d7b269d34f..7925065efbcc4 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/cdk.out
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/cdk.out
@@ -1 +1 @@
-{"version":"20.0.0"}
\ No newline at end of file
+{"version":"31.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.assets.json
index 43427a41c1b2d..9ed63729ef5da 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.assets.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.assets.json
@@ -1,7 +1,33 @@
{
- "version": "30.1.0",
+ "version": "31.0.0",
"files": {
- "0c2d0def6db3389453a3efadab8db4804f46dd1e84431da6a970923085b33a51": {
+ "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce": {
+ "source": {
+ "path": "asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce",
+ "packaging": "zip"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce.zip",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ },
+ "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302": {
+ "source": {
+ "path": "asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302",
+ "packaging": "zip"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302.zip",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ },
+ "93a95925d84976f569101a57c8168f573c9082576c798f93def25e662e00852d": {
"source": {
"path": "integ-cognito.template.json",
"packaging": "file"
@@ -9,7 +35,7 @@
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
- "objectKey": "0c2d0def6db3389453a3efadab8db4804f46dd1e84431da6a970923085b33a51.json",
+ "objectKey": "93a95925d84976f569101a57c8168f573c9082576c798f93def25e662e00852d.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.template.json
index 8ebe942ac8060..f412df5d4fe5d 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.template.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ-cognito.template.json
@@ -391,6 +391,25 @@
}
}
},
+ "Certificate4E7ABB08": {
+ "Type": "AWS::CertificateManager::Certificate",
+ "Properties": {
+ "DomainName": "*.example.com",
+ "DomainValidationOptions": [
+ {
+ "DomainName": "*.example.com",
+ "HostedZoneId": "Z23ABC4XYZL05B"
+ }
+ ],
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "integ-cognito/Certificate"
+ }
+ ],
+ "ValidationMethod": "DNS"
+ }
+ },
"LB8A12904C": {
"Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
"Properties": {
@@ -432,11 +451,11 @@
"GroupDescription": "Automatically created Security Group for ELB integcognitoLBFBBBA626",
"SecurityGroupEgress": [
{
- "CidrIp": "255.255.255.255/32",
- "Description": "Disallow all traffic",
- "FromPort": 252,
- "IpProtocol": "icmp",
- "ToPort": 86
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow to IdP endpoint",
+ "FromPort": 443,
+ "IpProtocol": "tcp",
+ "ToPort": 443
}
],
"SecurityGroupIngress": [
@@ -491,7 +510,9 @@
},
"Certificates": [
{
- "CertificateArn": ""
+ "CertificateArn": {
+ "Ref": "Certificate4E7ABB08"
+ }
}
],
"Port": 443,
@@ -541,10 +562,10 @@
}
}
],
+ "Priority": 1,
"ListenerArn": {
"Ref": "LBListener49E825B4"
- },
- "Priority": 1
+ }
}
},
"UserPool6BA7E5F2": {
@@ -575,8 +596,8 @@
"SmsMessage": "The verification code to your new account is {####}"
}
},
- "UpdateReplacePolicy": "Retain",
- "DeletionPolicy": "Retain"
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
},
"Client4A7F64DF": {
"Type": "AWS::Cognito::UserPoolClient",
@@ -593,21 +614,7 @@
"openid"
],
"CallbackURLs": [
- {
- "Fn::Join": [
- "",
- [
- "https://",
- {
- "Fn::GetAtt": [
- "LB8A12904C",
- "DNSName"
- ]
- },
- "/oauth2/idpresponse"
- ]
- ]
- }
+ "https://*.example.com/oauth2/idpresponse"
],
"ExplicitAuthFlows": [
"ALLOW_USER_PASSWORD_AUTH",
@@ -623,20 +630,404 @@
"Domain66AC69E0": {
"Type": "AWS::Cognito::UserPoolDomain",
"Properties": {
- "Domain": "test-cdk-prefix",
+ "Domain": "z23abc4xyzl05b",
"UserPoolId": {
"Ref": "UserPool6BA7E5F2"
}
}
+ },
+ "ARecordE7B57761": {
+ "Type": "AWS::Route53::RecordSet",
+ "Properties": {
+ "Name": "example.com.",
+ "Type": "A",
+ "AliasTarget": {
+ "DNSName": {
+ "Fn::Join": [
+ "",
+ [
+ "dualstack.",
+ {
+ "Fn::GetAtt": [
+ "LB8A12904C",
+ "DNSName"
+ ]
+ }
+ ]
+ ]
+ },
+ "HostedZoneId": {
+ "Fn::GetAtt": [
+ "LB8A12904C",
+ "CanonicalHostedZoneID"
+ ]
+ }
+ },
+ "HostedZoneId": "Z23ABC4XYZL05B"
+ }
+ },
+ "UserFDDCDD17": {
+ "Type": "Custom::CognitoUser",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd22872D164C4C",
+ "Arn"
+ ]
+ },
+ "Create": {
+ "Fn::Join": [
+ "",
+ [
+ "{\"service\":\"CognitoIdentityServiceProvider\",\"action\":\"adminCreateUser\",\"parameters\":{\"UserPoolId\":\"",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "\",\"Username\":\"test-user@example.com\",\"UserAttributes\":[{\"Name\":\"email\",\"Value\":\"test-user@example.com\"},{\"Name\":\"email_verified\",\"Value\":\"true\"}],\"MessageAction\":\"SUPPRESS\"},\"physicalResourceId\":{\"id\":\"User\"}}"
+ ]
+ ]
+ },
+ "InstallLatestAwsSdk": false
+ },
+ "DependsOn": [
+ "UserCustomResourcePolicyC2EB5139"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "UserCustomResourcePolicyC2EB5139": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminCreateUser",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "UserCustomResourcePolicyC2EB5139",
+ "Roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "UserSetUserPasswordAD2F2A64": {
+ "Type": "Custom::CognitoUserPassword",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd22872D164C4C",
+ "Arn"
+ ]
+ },
+ "Create": {
+ "Fn::Join": [
+ "",
+ [
+ "{\"service\":\"CognitoIdentityServiceProvider\",\"action\":\"adminSetUserPassword\",\"parameters\":{\"UserPoolId\":\"",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "\",\"Username\":\"",
+ {
+ "Fn::GetAtt": [
+ "UserFDDCDD17",
+ "User.Username"
+ ]
+ },
+ "\",\"Password\":\"TestUser@123\",\"Permanent\":true},\"physicalResourceId\":{\"id\":\"SetUserPassword\"}}"
+ ]
+ ]
+ },
+ "InstallLatestAwsSdk": false
+ },
+ "DependsOn": [
+ "UserCustomResourcePolicyC2EB5139",
+ "UserFDDCDD17",
+ "UserSetUserPasswordCustomResourcePolicy7B250C76"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "UserSetUserPasswordCustomResourcePolicy7B250C76": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminSetUserPassword",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "UserSetUserPasswordCustomResourcePolicy7B250C76",
+ "Roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ },
+ "DependsOn": [
+ "UserCustomResourcePolicyC2EB5139",
+ "UserFDDCDD17"
+ ]
+ },
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "AWS679f53fac002430cb0da5b7982bd22872D164C4C": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "S3Key": "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce.zip"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
+ "Arn"
+ ]
+ },
+ "Handler": "index.handler",
+ "Runtime": {
+ "Fn::FindInMap": [
+ "DefaultCrNodeVersionMap",
+ {
+ "Ref": "AWS::Region"
+ },
+ "value"
+ ]
+ },
+ "Timeout": 120
+ },
+ "DependsOn": [
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ ]
+ },
+ "SigninServiceRole24B8BB32": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "Signin352C80E6": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "S3Key": "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302.zip"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "SigninServiceRole24B8BB32",
+ "Arn"
+ ]
+ },
+ "Environment": {
+ "Variables": {
+ "TEST_USERNAME": "test-user@example.com",
+ "TEST_PASSWORD": "TestUser@123",
+ "TEST_URL": "https://*.example.com"
+ }
+ },
+ "FunctionName": "cdk-integ-alb-cognito-signin-handler",
+ "Handler": "index.handler",
+ "MemorySize": 1024,
+ "Runtime": "nodejs18.x",
+ "Timeout": 300
+ },
+ "DependsOn": [
+ "SigninServiceRole24B8BB32"
+ ]
}
},
"Outputs": {
"DNS": {
+ "Value": "*.example.com"
+ },
+ "ExportsOutputRefSignin352C80E64BA58F71": {
"Value": {
- "Fn::GetAtt": [
- "LB8A12904C",
- "DNSName"
- ]
+ "Ref": "Signin352C80E6"
+ },
+ "Export": {
+ "Name": "integ-cognito:ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ }
+ },
+ "Mappings": {
+ "DefaultCrNodeVersionMap": {
+ "af-south-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-east-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-northeast-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-northeast-2": {
+ "value": "nodejs16.x"
+ },
+ "ap-northeast-3": {
+ "value": "nodejs16.x"
+ },
+ "ap-south-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-south-2": {
+ "value": "nodejs16.x"
+ },
+ "ap-southeast-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-southeast-2": {
+ "value": "nodejs16.x"
+ },
+ "ap-southeast-3": {
+ "value": "nodejs16.x"
+ },
+ "ca-central-1": {
+ "value": "nodejs16.x"
+ },
+ "cn-north-1": {
+ "value": "nodejs16.x"
+ },
+ "cn-northwest-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-central-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-central-2": {
+ "value": "nodejs16.x"
+ },
+ "eu-north-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-south-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-south-2": {
+ "value": "nodejs16.x"
+ },
+ "eu-west-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-west-2": {
+ "value": "nodejs16.x"
+ },
+ "eu-west-3": {
+ "value": "nodejs16.x"
+ },
+ "me-central-1": {
+ "value": "nodejs16.x"
+ },
+ "me-south-1": {
+ "value": "nodejs16.x"
+ },
+ "sa-east-1": {
+ "value": "nodejs16.x"
+ },
+ "us-east-1": {
+ "value": "nodejs16.x"
+ },
+ "us-east-2": {
+ "value": "nodejs16.x"
+ },
+ "us-gov-east-1": {
+ "value": "nodejs16.x"
+ },
+ "us-gov-west-1": {
+ "value": "nodejs16.x"
+ },
+ "us-iso-east-1": {
+ "value": "nodejs14.x"
+ },
+ "us-iso-west-1": {
+ "value": "nodejs14.x"
+ },
+ "us-isob-east-1": {
+ "value": "nodejs14.x"
+ },
+ "us-west-1": {
+ "value": "nodejs16.x"
+ },
+ "us-west-2": {
+ "value": "nodejs16.x"
}
}
},
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ.json
index e2c6ee0c8b902..205c6b624a598 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integ.json
@@ -1,5 +1,5 @@
{
- "version": "30.1.0",
+ "version": "31.0.0",
"testCases": {
"integ-test-cognito/DefaultTest": {
"stacks": [
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.assets.json
index be07bf072ac9a..288d6677e1937 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.assets.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.assets.json
@@ -1,7 +1,20 @@
{
- "version": "30.1.0",
+ "version": "31.0.0",
"files": {
- "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
+ "ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3": {
+ "source": {
+ "path": "asset.ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3.bundle",
+ "packaging": "zip"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3.zip",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ },
+ "75262cd26d1fd97ddeebfb8c87fca618b3702c38903dcb56c597df6865739b49": {
"source": {
"path": "integtestcognitoDefaultTestDeployAssert6F2623C9.template.json",
"packaging": "file"
@@ -9,7 +22,7 @@
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
- "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
+ "objectKey": "75262cd26d1fd97ddeebfb8c87fca618b3702c38903dcb56c597df6865739b49.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.template.json
index ad9d0fb73d1dd..7e1c2a99bdbc9 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.template.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/integtestcognitoDefaultTestDeployAssert6F2623C9.template.json
@@ -1,4 +1,146 @@
{
+ "Resources": {
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd": {
+ "Type": "Custom::DeployAssert@SdkCallLambdainvoke",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F",
+ "Arn"
+ ]
+ },
+ "service": "Lambda",
+ "api": "invoke",
+ "expected": "{\"$ObjectLike\":{\"Payload\":\"\\\"Authenticated\\\"\"}}",
+ "parameters": {
+ "FunctionName": {
+ "Fn::ImportValue": "integ-cognito:ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ },
+ "flattenResponse": "false",
+ "salt": "1682915835545"
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bdInvoke5A72F915": {
+ "Type": "AWS::Lambda::Permission",
+ "Properties": {
+ "Action": "lambda:InvokeFunction",
+ "FunctionName": {
+ "Fn::ImportValue": "integ-cognito:ExportsOutputRefSignin352C80E64BA58F71"
+ },
+ "Principal": {
+ "Fn::GetAtt": [
+ "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ]
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ }
+ ],
+ "Policies": [
+ {
+ "PolicyName": "Inline",
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": [
+ "lambda:Invoke"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ "*"
+ ]
+ },
+ {
+ "Action": [
+ "lambda:InvokeFunction"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":lambda:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":function:",
+ {
+ "Fn::ImportValue": "integ-cognito:ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Runtime": "nodejs14.x",
+ "Code": {
+ "S3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "S3Key": "ae370e1010629b78f494346f49ceef3ab2875718f20e6c808114e6aa770c7bf3.zip"
+ },
+ "Timeout": 120,
+ "Handler": "index.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73",
+ "Arn"
+ ]
+ }
+ }
+ }
+ },
+ "Outputs": {
+ "AssertionResultsLambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd": {
+ "Value": {
+ "Fn::GetAtt": [
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd",
+ "assertion"
+ ]
+ }
+ }
+ },
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value",
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/manifest.json
index 6754548507bfd..1f891dbfbc1c7 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/manifest.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/manifest.json
@@ -1,5 +1,5 @@
{
- "version": "30.1.0",
+ "version": "31.0.0",
"artifacts": {
"integ-cognito.assets": {
"type": "cdk:asset-manifest",
@@ -17,7 +17,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
- "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/0c2d0def6db3389453a3efadab8db4804f46dd1e84431da6a970923085b33a51.json",
+ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/93a95925d84976f569101a57c8168f573c9082576c798f93def25e662e00852d.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
@@ -171,6 +171,12 @@
"data": "StackVPCGWFFCB6290"
}
],
+ "/integ-cognito/Certificate/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Certificate4E7ABB08"
+ }
+ ],
"/integ-cognito/LB/Resource": [
{
"type": "aws:cdk:logicalId",
@@ -213,12 +219,78 @@
"data": "Domain66AC69E0"
}
],
+ "/integ-cognito/ARecord/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ARecordE7B57761"
+ }
+ ],
"/integ-cognito/DNS": [
{
"type": "aws:cdk:logicalId",
"data": "DNS"
}
],
+ "/integ-cognito/User/Resource/Resource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserFDDCDD17"
+ }
+ ],
+ "/integ-cognito/User/Resource/CustomResourcePolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserCustomResourcePolicyC2EB5139"
+ }
+ ],
+ "/integ-cognito/User/SetUserPassword/Resource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserSetUserPasswordAD2F2A64"
+ }
+ ],
+ "/integ-cognito/User/SetUserPassword/CustomResourcePolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserSetUserPasswordCustomResourcePolicy7B250C76"
+ }
+ ],
+ "/integ-cognito/DefaultCrNodeVersionMap": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DefaultCrNodeVersionMap"
+ }
+ ],
+ "/integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ],
+ "/integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AWS679f53fac002430cb0da5b7982bd22872D164C4C"
+ }
+ ],
+ "/integ-cognito/Signin/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "SigninServiceRole24B8BB32"
+ }
+ ],
+ "/integ-cognito/Signin/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Signin352C80E6"
+ }
+ ],
+ "/integ-cognito/Exports/Output{\"Ref\":\"Signin352C80E6\"}": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ ],
"/integ-cognito/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
@@ -250,7 +322,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
- "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
+ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/75262cd26d1fd97ddeebfb8c87fca618b3702c38903dcb56c597df6865739b49.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
@@ -263,9 +335,40 @@
}
},
"dependencies": [
+ "integ-cognito",
"integtestcognitoDefaultTestDeployAssert6F2623C9.assets"
],
"metadata": {
+ "/integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Default/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd"
+ }
+ ],
+ "/integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Invoke": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bdInvoke5A72F915"
+ }
+ ],
+ "/integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/AssertionResults": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssertionResultsLambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd"
+ }
+ ],
+ "/integ-test-cognito/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73"
+ }
+ ],
+ "/integ-test-cognito/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F"
+ }
+ ],
"/integ-test-cognito/DefaultTest/DeployAssert/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/tree.json
index 4a24b167bc0c6..3c3761a1092b3 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/tree.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.js.snapshot/tree.json
@@ -31,7 +31,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnVPC",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnVPC",
"version": "0.0.0"
}
},
@@ -75,7 +75,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
"version": "0.0.0"
}
},
@@ -83,7 +83,7 @@
"id": "Acl",
"path": "integ-cognito/Stack/PublicSubnet1/Acl",
"constructInfo": {
- "fqn": "@aws-cdk/core.Resource",
+ "fqn": "aws-cdk-lib.Resource",
"version": "0.0.0"
}
},
@@ -105,7 +105,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
"version": "0.0.0"
}
},
@@ -124,7 +124,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
"version": "0.0.0"
}
},
@@ -144,7 +144,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
"version": "0.0.0"
}
},
@@ -164,7 +164,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnEIP",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnEIP",
"version": "0.0.0"
}
},
@@ -192,13 +192,13 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnNatGateway",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.PublicSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet",
"version": "0.0.0"
}
},
@@ -242,7 +242,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
"version": "0.0.0"
}
},
@@ -250,7 +250,7 @@
"id": "Acl",
"path": "integ-cognito/Stack/PublicSubnet2/Acl",
"constructInfo": {
- "fqn": "@aws-cdk/core.Resource",
+ "fqn": "aws-cdk-lib.Resource",
"version": "0.0.0"
}
},
@@ -272,7 +272,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
"version": "0.0.0"
}
},
@@ -291,7 +291,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
"version": "0.0.0"
}
},
@@ -311,7 +311,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
"version": "0.0.0"
}
},
@@ -331,7 +331,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnEIP",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnEIP",
"version": "0.0.0"
}
},
@@ -359,13 +359,13 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnNatGateway",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.PublicSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet",
"version": "0.0.0"
}
},
@@ -409,7 +409,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
"version": "0.0.0"
}
},
@@ -417,7 +417,7 @@
"id": "Acl",
"path": "integ-cognito/Stack/PrivateSubnet1/Acl",
"constructInfo": {
- "fqn": "@aws-cdk/core.Resource",
+ "fqn": "aws-cdk-lib.Resource",
"version": "0.0.0"
}
},
@@ -439,7 +439,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
"version": "0.0.0"
}
},
@@ -458,7 +458,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
"version": "0.0.0"
}
},
@@ -478,13 +478,13 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.PrivateSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet",
"version": "0.0.0"
}
},
@@ -528,7 +528,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
"version": "0.0.0"
}
},
@@ -536,7 +536,7 @@
"id": "Acl",
"path": "integ-cognito/Stack/PrivateSubnet2/Acl",
"constructInfo": {
- "fqn": "@aws-cdk/core.Resource",
+ "fqn": "aws-cdk-lib.Resource",
"version": "0.0.0"
}
},
@@ -558,7 +558,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRouteTable",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
"version": "0.0.0"
}
},
@@ -577,7 +577,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
"version": "0.0.0"
}
},
@@ -597,13 +597,13 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnRoute",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.PrivateSubnet",
+ "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet",
"version": "0.0.0"
}
},
@@ -622,7 +622,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnInternetGateway",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway",
"version": "0.0.0"
}
},
@@ -641,13 +641,58 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnVPCGatewayAttachment",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.Vpc",
+ "fqn": "aws-cdk-lib.aws_ec2.Vpc",
+ "version": "0.0.0"
+ }
+ },
+ "HostedZone": {
+ "id": "HostedZone",
+ "path": "integ-cognito/HostedZone",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "Certificate": {
+ "id": "Certificate",
+ "path": "integ-cognito/Certificate",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/Certificate/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::CertificateManager::Certificate",
+ "aws:cdk:cloudformation:props": {
+ "domainName": "*.example.com",
+ "domainValidationOptions": [
+ {
+ "domainName": "*.example.com",
+ "hostedZoneId": "Z23ABC4XYZL05B"
+ }
+ ],
+ "tags": [
+ {
+ "key": "Name",
+ "value": "integ-cognito/Certificate"
+ }
+ ],
+ "validationMethod": "DNS"
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_certificatemanager.CfnCertificate",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_certificatemanager.Certificate",
"version": "0.0.0"
}
},
@@ -688,7 +733,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-elasticloadbalancingv2.CfnLoadBalancer",
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer",
"version": "0.0.0"
}
},
@@ -705,11 +750,11 @@
"groupDescription": "Automatically created Security Group for ELB integcognitoLBFBBBA626",
"securityGroupEgress": [
{
- "cidrIp": "255.255.255.255/32",
- "description": "Disallow all traffic",
- "ipProtocol": "icmp",
- "fromPort": 252,
- "toPort": 86
+ "cidrIp": "0.0.0.0/0",
+ "ipProtocol": "tcp",
+ "fromPort": 443,
+ "toPort": 443,
+ "description": "Allow to IdP endpoint"
}
],
"securityGroupIngress": [
@@ -727,13 +772,13 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup",
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ec2.SecurityGroup",
+ "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup",
"version": "0.0.0"
}
},
@@ -782,7 +827,9 @@
},
"certificates": [
{
- "certificateArn": ""
+ "certificateArn": {
+ "Ref": "Certificate4E7ABB08"
+ }
}
],
"port": 443,
@@ -790,7 +837,7 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-elasticloadbalancingv2.CfnListener",
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnListener",
"version": "0.0.0"
}
},
@@ -844,32 +891,32 @@
}
}
],
+ "priority": 1,
"listenerArn": {
"Ref": "LBListener49E825B4"
- },
- "priority": 1
+ }
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-elasticloadbalancingv2.CfnListenerRule",
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnListenerRule",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerRule",
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationListenerRule",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationListener",
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationListener",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-elasticloadbalancingv2.ApplicationLoadBalancer",
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer",
"version": "0.0.0"
}
},
@@ -910,13 +957,13 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-cognito.CfnUserPool",
+ "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-cognito.UserPool",
+ "fqn": "aws-cdk-lib.aws_cognito.UserPool",
"version": "0.0.0"
}
},
@@ -942,21 +989,7 @@
"openid"
],
"callbackUrLs": [
- {
- "Fn::Join": [
- "",
- [
- "https://",
- {
- "Fn::GetAtt": [
- "LB8A12904C",
- "DNSName"
- ]
- },
- "/oauth2/idpresponse"
- ]
- ]
- }
+ "https://*.example.com/oauth2/idpresponse"
],
"explicitAuthFlows": [
"ALLOW_USER_PASSWORD_AUTH",
@@ -969,13 +1002,13 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-cognito.CfnUserPoolClient",
+ "fqn": "aws-cdk-lib.aws_cognito.CfnUserPoolClient",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-cognito.UserPoolClient",
+ "fqn": "aws-cdk-lib.aws_cognito.UserPoolClient",
"version": "0.0.0"
}
},
@@ -989,20 +1022,68 @@
"attributes": {
"aws:cdk:cloudformation:type": "AWS::Cognito::UserPoolDomain",
"aws:cdk:cloudformation:props": {
- "domain": "test-cdk-prefix",
+ "domain": "z23abc4xyzl05b",
"userPoolId": {
"Ref": "UserPool6BA7E5F2"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-cognito.CfnUserPoolDomain",
+ "fqn": "aws-cdk-lib.aws_cognito.CfnUserPoolDomain",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_cognito.UserPoolDomain",
+ "version": "0.0.0"
+ }
+ },
+ "ARecord": {
+ "id": "ARecord",
+ "path": "integ-cognito/ARecord",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/ARecord/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet",
+ "aws:cdk:cloudformation:props": {
+ "name": "example.com.",
+ "type": "A",
+ "aliasTarget": {
+ "hostedZoneId": {
+ "Fn::GetAtt": [
+ "LB8A12904C",
+ "CanonicalHostedZoneID"
+ ]
+ },
+ "dnsName": {
+ "Fn::Join": [
+ "",
+ [
+ "dualstack.",
+ {
+ "Fn::GetAtt": [
+ "LB8A12904C",
+ "DNSName"
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "hostedZoneId": "Z23ABC4XYZL05B"
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_route53.CfnRecordSet",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-cognito.UserPoolDomain",
+ "fqn": "aws-cdk-lib.aws_route53.ARecord",
"version": "0.0.0"
}
},
@@ -1010,15 +1091,470 @@
"id": "DNS",
"path": "integ-cognito/DNS",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnOutput",
+ "fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
+ "User": {
+ "id": "User",
+ "path": "integ-cognito/User",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/User/Resource",
+ "children": {
+ "Provider": {
+ "id": "Provider",
+ "path": "integ-cognito/User/Resource/Provider",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/User/Resource/Resource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "integ-cognito/User/Resource/Resource/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourcePolicy": {
+ "id": "CustomResourcePolicy",
+ "path": "integ-cognito/User/Resource/CustomResourcePolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/User/Resource/CustomResourcePolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminCreateUser",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "UserCustomResourcePolicyC2EB5139",
+ "roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.custom_resources.AwsCustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "SetUserPassword": {
+ "id": "SetUserPassword",
+ "path": "integ-cognito/User/SetUserPassword",
+ "children": {
+ "Provider": {
+ "id": "Provider",
+ "path": "integ-cognito/User/SetUserPassword/Provider",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/User/SetUserPassword/Resource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "integ-cognito/User/SetUserPassword/Resource/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourcePolicy": {
+ "id": "CustomResourcePolicy",
+ "path": "integ-cognito/User/SetUserPassword/CustomResourcePolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/User/SetUserPassword/CustomResourcePolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminSetUserPassword",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "UserSetUserPasswordCustomResourcePolicy7B250C76",
+ "roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.custom_resources.AwsCustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.1.270"
+ }
+ },
+ "DefaultCrNodeVersionMap": {
+ "id": "DefaultCrNodeVersionMap",
+ "path": "integ-cognito/DefaultCrNodeVersionMap",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnMapping",
+ "version": "0.0.0"
+ }
+ },
+ "AWS679f53fac002430cb0da5b7982bd2287": {
+ "id": "AWS679f53fac002430cb0da5b7982bd2287",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole",
+ "children": {
+ "ImportServiceRole": {
+ "id": "ImportServiceRole",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/ImportServiceRole",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnRole",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Code": {
+ "id": "Code",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/Code/Stage",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3_assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/AWS679f53fac002430cb0da5b7982bd2287/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "s3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "s3Key": "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce.zip"
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
+ "Arn"
+ ]
+ },
+ "handler": "index.handler",
+ "runtime": {
+ "Fn::FindInMap": [
+ "DefaultCrNodeVersionMap",
+ {
+ "Ref": "AWS::Region"
+ },
+ "value"
+ ]
+ },
+ "timeout": 120
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.Function",
+ "version": "0.0.0"
+ }
+ },
+ "Signin": {
+ "id": "Signin",
+ "path": "integ-cognito/Signin",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "integ-cognito/Signin/ServiceRole",
+ "children": {
+ "ImportServiceRole": {
+ "id": "ImportServiceRole",
+ "path": "integ-cognito/Signin/ServiceRole/ImportServiceRole",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/Signin/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnRole",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Code": {
+ "id": "Code",
+ "path": "integ-cognito/Signin/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "integ-cognito/Signin/Code/Stage",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "integ-cognito/Signin/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3_assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "integ-cognito/Signin/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "s3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "s3Key": "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302.zip"
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "SigninServiceRole24B8BB32",
+ "Arn"
+ ]
+ },
+ "environment": {
+ "variables": {
+ "TEST_USERNAME": "test-user@example.com",
+ "TEST_PASSWORD": "TestUser@123",
+ "TEST_URL": "https://*.example.com"
+ }
+ },
+ "functionName": "cdk-integ-alb-cognito-signin-handler",
+ "handler": "index.handler",
+ "memorySize": 1024,
+ "runtime": "nodejs18.x",
+ "timeout": 300
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.Function",
+ "version": "0.0.0"
+ }
+ },
+ "Exports": {
+ "id": "Exports",
+ "path": "integ-cognito/Exports",
+ "children": {
+ "Output{\"Ref\":\"Signin352C80E6\"}": {
+ "id": "Output{\"Ref\":\"Signin352C80E6\"}",
+ "path": "integ-cognito/Exports/Output{\"Ref\":\"Signin352C80E6\"}",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnOutput",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.1.270"
+ }
+ },
"BootstrapVersion": {
"id": "BootstrapVersion",
"path": "integ-cognito/BootstrapVersion",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnParameter",
+ "fqn": "aws-cdk-lib.CfnParameter",
"version": "0.0.0"
}
},
@@ -1026,13 +1562,13 @@
"id": "CheckBootstrapVersion",
"path": "integ-cognito/CheckBootstrapVersion",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnRule",
+ "fqn": "aws-cdk-lib.CfnRule",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/core.Stack",
+ "fqn": "aws-cdk-lib.Stack",
"version": "0.0.0"
}
},
@@ -1049,18 +1585,114 @@
"path": "integ-test-cognito/DefaultTest/Default",
"constructInfo": {
"fqn": "constructs.Construct",
- "version": "10.1.264"
+ "version": "10.1.270"
}
},
"DeployAssert": {
"id": "DeployAssert",
"path": "integ-test-cognito/DefaultTest/DeployAssert",
"children": {
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd": {
+ "id": "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd",
+ "children": {
+ "SdkProvider": {
+ "id": "SdkProvider",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/SdkProvider",
+ "children": {
+ "AssertionsProvider": {
+ "id": "AssertionsProvider",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/SdkProvider/AssertionsProvider",
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.1.270"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/integ-tests-alpha.AssertionsProvider",
+ "version": "0.0.0"
+ }
+ },
+ "Default": {
+ "id": "Default",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Default",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Default/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "Invoke": {
+ "id": "Invoke",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Invoke",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ },
+ "AssertionResults": {
+ "id": "AssertionResults",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/AssertionResults",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnOutput",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/integ-tests-alpha.LambdaInvokeFunction",
+ "version": "0.0.0"
+ }
+ },
+ "SingletonFunction1488541a7b23466481b69b4408076b81": {
+ "id": "SingletonFunction1488541a7b23466481b69b4408076b81",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81",
+ "children": {
+ "Staging": {
+ "id": "Staging",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Staging",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "Role": {
+ "id": "Role",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ },
+ "Handler": {
+ "id": "Handler",
+ "path": "integ-test-cognito/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.1.270"
+ }
+ },
"BootstrapVersion": {
"id": "BootstrapVersion",
"path": "integ-test-cognito/DefaultTest/DeployAssert/BootstrapVersion",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnParameter",
+ "fqn": "aws-cdk-lib.CfnParameter",
"version": "0.0.0"
}
},
@@ -1068,25 +1700,25 @@
"id": "CheckBootstrapVersion",
"path": "integ-test-cognito/DefaultTest/DeployAssert/CheckBootstrapVersion",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnRule",
+ "fqn": "aws-cdk-lib.CfnRule",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/core.Stack",
+ "fqn": "aws-cdk-lib.Stack",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/integ-tests.IntegTestCase",
+ "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/integ-tests.IntegTest",
+ "fqn": "@aws-cdk/integ-tests-alpha.IntegTest",
"version": "0.0.0"
}
},
@@ -1095,12 +1727,12 @@
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
- "version": "10.1.264"
+ "version": "10.1.270"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/core.App",
+ "fqn": "aws-cdk-lib.App",
"version": "0.0.0"
}
}
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.ts
index a512e3ff20587..0e81a15a77592 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.ts
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-actions/test/integ.cognito.ts
@@ -1,33 +1,117 @@
import * as cognito from 'aws-cdk-lib/aws-cognito';
+import * as acm from 'aws-cdk-lib/aws-certificatemanager';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
-import { App, CfnOutput, Duration, Stack } from 'aws-cdk-lib/core';
+import { App, CfnOutput, Duration, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib/core';
import * as integ from '@aws-cdk/integ-tests-alpha';
import { Construct } from 'constructs';
import * as actions from 'aws-cdk-lib/aws-elasticloadbalancingv2-actions';
+import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from 'aws-cdk-lib/custom-resources';
+import * as iam from 'aws-cdk-lib/aws-iam';
+import * as lambda from 'aws-cdk-lib/aws-lambda';
+import * as route53 from 'aws-cdk-lib/aws-route53';
+import * as route53targets from 'aws-cdk-lib/aws-route53-targets';
+
+interface CognitoUserProps {
+ userPool: cognito.UserPool
+ username: string
+ password: string
+}
+/**
+ * Cognito User for testing
+ */
+class CognitoUser extends Construct {
+ readonly username: string;
+ readonly password: string;
+ constructor(scope: Construct, id: string, props: CognitoUserProps) {
+ super(scope, id);
+ const user = new AwsCustomResource(this, 'Resource', {
+ resourceType: 'Custom::CognitoUser',
+ onCreate: {
+ service: 'CognitoIdentityServiceProvider',
+ action: 'adminCreateUser',
+ parameters: {
+ UserPoolId: props.userPool.userPoolId,
+ Username: props.username,
+ UserAttributes: [
+ {
+ Name: 'email',
+ Value: props.username,
+ },
+ {
+ Name: 'email_verified',
+ Value: 'true',
+ },
+ ],
+ MessageAction: 'SUPPRESS',
+ },
+ physicalResourceId: PhysicalResourceId.of('User'),
+ },
+ policy: AwsCustomResourcePolicy.fromStatements([new iam.PolicyStatement({
+ actions: ['cognito-idp:AdminCreateUser'],
+ resources: [props.userPool.userPoolArn],
+ })]),
+ });
+
+ new AwsCustomResource(this, 'SetUserPassword', {
+ resourceType: 'Custom::CognitoUserPassword',
+ onCreate: {
+ service: 'CognitoIdentityServiceProvider',
+ action: 'adminSetUserPassword',
+ parameters: {
+ UserPoolId: props.userPool.userPoolId,
+ Username: user.getResponseField('User.Username'),
+ Password: props.password,
+ Permanent: true,
+ },
+ physicalResourceId: PhysicalResourceId.of('SetUserPassword'),
+ },
+ policy: AwsCustomResourcePolicy.fromStatements([new iam.PolicyStatement({
+ actions: ['cognito-idp:AdminSetUserPassword'],
+ resources: [props.userPool.userPoolArn],
+ })]),
+ }).node.addDependency(user);
+ this.password = props.password;
+ this.username = props.username;
+ }
+}
+
+interface CognitoStackProps extends StackProps {
+ hostedZoneId: string
+ hostedZoneName: string
+ domainName: string
+}
// This test can only be run as a dry-run at this time due to requiring a certificate
class CognitoStack extends Stack {
+ public readonly userPool: cognito.UserPool;
- constructor(scope: Construct, id: string) {
+ constructor(scope: Construct, id: string, props: CognitoStackProps) {
super(scope, id);
const vpc = new ec2.Vpc(this, 'Stack', {
maxAzs: 2, restrictDefaultSecurityGroup: false,
});
- const certificate: elbv2.IListenerCertificate = {
- certificateArn: process.env.SELF_SIGNED_CERT_ARN ?? '',
- };
+ const hostedZone = route53.PublicHostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
+ hostedZoneId: props.hostedZoneId,
+ zoneName: props.hostedZoneName,
+ });
+ const certificate = new acm.Certificate(this, 'Certificate', {
+ domainName: props.domainName,
+ validation: acm.CertificateValidation.fromDns(hostedZone),
+ });
const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
vpc,
internetFacing: true,
});
- const userPool = new cognito.UserPool(this, 'UserPool');
+ this.userPool = new cognito.UserPool(this, 'UserPool', {
+ removalPolicy: RemovalPolicy.DESTROY,
+ });
const userPoolClient = new cognito.UserPoolClient(this, 'Client', {
- userPool,
+ userPool: this.userPool,
// Required minimal configuration for use with an ELB
generateSecret: true,
@@ -40,7 +124,7 @@ class CognitoStack extends Stack {
},
scopes: [cognito.OAuthScope.EMAIL],
callbackUrls: [
- `https://${lb.loadBalancerDnsName}/oauth2/idpresponse`,
+ `https://${props.domainName}/oauth2/idpresponse`,
],
},
});
@@ -49,13 +133,13 @@ class CognitoStack extends Stack {
cfnClient.addPropertyOverride('SupportedIdentityProviders', ['COGNITO']);
const userPoolDomain = new cognito.UserPoolDomain(this, 'Domain', {
- userPool,
+ userPool: this.userPool,
cognitoDomain: {
- domainPrefix: 'test-cdk-prefix',
+ domainPrefix: props.hostedZoneId.toLowerCase(),
},
});
const action = new actions.AuthenticateCognitoAction({
- userPool,
+ userPool: this.userPool,
userPoolClient,
userPoolDomain,
sessionTimeout: Duration.days(1),
@@ -74,17 +158,62 @@ class CognitoStack extends Stack {
conditions: [elbv2.ListenerCondition.pathPatterns(['action2*'])],
action,
});
+ new route53.ARecord(this, 'ARecord', {
+ target: route53.RecordTarget.fromAlias(new route53targets.LoadBalancerTarget(lb)),
+ zone: hostedZone,
+ });
new CfnOutput(this, 'DNS', {
- value: lb.loadBalancerDnsName,
+ value: props.domainName,
});
}
}
+/**
+ * In order to test this you need to have a valid public hosted zone that you can use
+ * to request certificates for.
+ *
+*/
+const hostedZoneId = process.env.CDK_INTEG_HOSTED_ZONE_ID ?? process.env.HOSTED_ZONE_ID;
+if (!hostedZoneId) throw new Error('For this test you must provide your own HostedZoneId as an env var "HOSTED_ZONE_ID"');
+const hostedZoneName = process.env.CDK_INTEG_HOSTED_ZONE_NAME ?? process.env.HOSTED_ZONE_NAME;
+if (!hostedZoneName) throw new Error('For this test you must provide your own HostedZoneName as an env var "HOSTED_ZONE_NAME"');
+const domainName = process.env.CDK_INTEG_DOMAIN_NAME ?? process.env.DOMAIN_NAME;
+if (!domainName) throw new Error('For this test you must provide your own Domain Name as an env var "DOMAIN_NAME"');
+
const app = new App();
-const testCase = new CognitoStack(app, 'integ-cognito');
-new integ.IntegTest(app, 'integ-test-cognito', {
+const testCase = new CognitoStack(app, 'integ-cognito', {
+ hostedZoneId,
+ hostedZoneName,
+ domainName,
+});
+const test = new integ.IntegTest(app, 'integ-test-cognito', {
testCases: [testCase],
});
+const testUser = new CognitoUser(testCase, 'User', {
+ userPool: testCase.userPool,
+ username: 'test-user@example.com',
+ password: 'TestUser@123',
+});
+// this function signs in to the website and returns text content of the authenticated page body
+const signinFunction = new lambda.Function(testCase, 'Signin', {
+ functionName: 'cdk-integ-alb-cognito-signin-handler',
+ code: lambda.Code.fromAsset('alb-cognito-signin-handler'),
+ handler: 'index.handler',
+ runtime: lambda.Runtime.NODEJS_18_X,
+ environment: {
+ TEST_USERNAME: testUser.username,
+ TEST_PASSWORD: testUser.password,
+ TEST_URL: `https://${domainName}`,
+ },
+ memorySize: 1024,
+ timeout: Duration.minutes(5),
+});
+const invoke = test.assertions.invokeFunction({
+ functionName: signinFunction.functionName,
+});
+invoke.expect(integ.ExpectedResult.objectLike({
+ Payload: '"Authenticated"',
+}));
app.synth();
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/alb-oidc-signin-handler/index.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/alb-oidc-signin-handler/index.ts
new file mode 100644
index 0000000000000..9e79dd3fb247a
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/alb-oidc-signin-handler/index.ts
@@ -0,0 +1,31 @@
+/* eslint-disable @typescript-eslint/no-require-imports */
+import { execSync } from 'child_process';
+
+const url = process.env.TEST_URL;
+const setupBrowser = async () => {
+ execSync('HOME=/tmp npm install puppeteer-core @sparticuz/chromium --omit=dev --no-package-lock --no-save --prefix /tmp');
+ const puppeteer = require('/tmp/node_modules/puppeteer-core');
+ const chromium = require('/tmp/node_modules/@sparticuz/chromium');
+ const browser = await puppeteer.launch({
+ args: chromium.args,
+ defaultViewport: chromium.defaultViewport,
+ executablePath: await chromium.executablePath(),
+ headless: chromium.headless,
+ });
+ return browser;
+};
+
+export const handler: AWSLambda.Handler = async (_event) => {
+ const browser = await setupBrowser();
+ const page = await browser.newPage();
+ await page.goto(url, {
+ waitUntil: ['load', 'networkidle0'],
+ timeout: 30000,
+ });
+ await page.type("div.visible-lg input[name='username']", process.env.TEST_USERNAME);
+ await page.type("div.visible-lg input[name='password']", process.env.TEST_PASSWORD);
+ await page.click("div.visible-lg input[type='submit']");
+ const body = await page.waitForSelector('body');
+ const textContent = await body.evaluate((el: any) => el.textContent);
+ return textContent;
+};
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.assets.json
new file mode 100644
index 0000000000000..40060bdb0c368
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.assets.json
@@ -0,0 +1,58 @@
+{
+ "version": "31.0.0",
+ "files": {
+ "ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd": {
+ "source": {
+ "path": "asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd",
+ "packaging": "zip"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd.zip",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ },
+ "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce": {
+ "source": {
+ "path": "asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce",
+ "packaging": "zip"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce.zip",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ },
+ "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302": {
+ "source": {
+ "path": "asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302",
+ "packaging": "zip"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302.zip",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ },
+ "3533112c00a18f9eedd48cded520f3b4577ba46223123b31d79cf6b23b508640": {
+ "source": {
+ "path": "IntegAlbOidc.template.json",
+ "packaging": "file"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "3533112c00a18f9eedd48cded520f3b4577ba46223123b31d79cf6b23b508640.json",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ }
+ },
+ "dockerImages": {}
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.template.json
new file mode 100644
index 0000000000000..5cd2a858c1382
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegAlbOidc.template.json
@@ -0,0 +1,1286 @@
+{
+ "Resources": {
+ "Vpc8378EB38": {
+ "Type": "AWS::EC2::VPC",
+ "Properties": {
+ "CidrBlock": "10.0.0.0/16",
+ "EnableDnsHostnames": true,
+ "EnableDnsSupport": true,
+ "InstanceTenancy": "default",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc"
+ }
+ ]
+ }
+ },
+ "VpcPublicSubnet1Subnet5C2D37C4": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.0.0/18",
+ "MapPublicIpOnLaunch": true,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Public"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Public"
+ },
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "VpcPublicSubnet1RouteTable6C95E38E": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "VpcPublicSubnet1RouteTableAssociation97140677": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+ },
+ "SubnetId": {
+ "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+ }
+ }
+ },
+ "VpcPublicSubnet1DefaultRoute3DA9E72A": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "GatewayId": {
+ "Ref": "VpcIGWD7BA715C"
+ }
+ },
+ "DependsOn": [
+ "VpcVPCGWBF912B6E"
+ ]
+ },
+ "VpcPublicSubnet1EIPD7E02669": {
+ "Type": "AWS::EC2::EIP",
+ "Properties": {
+ "Domain": "vpc",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "VpcPublicSubnet1NATGateway4D7517AA": {
+ "Type": "AWS::EC2::NatGateway",
+ "Properties": {
+ "SubnetId": {
+ "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+ },
+ "AllocationId": {
+ "Fn::GetAtt": [
+ "VpcPublicSubnet1EIPD7E02669",
+ "AllocationId"
+ ]
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ },
+ "DependsOn": [
+ "VpcPublicSubnet1DefaultRoute3DA9E72A",
+ "VpcPublicSubnet1RouteTableAssociation97140677"
+ ]
+ },
+ "VpcPublicSubnet2Subnet691E08A3": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.64.0/18",
+ "MapPublicIpOnLaunch": true,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Public"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Public"
+ },
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "VpcPublicSubnet2RouteTable94F7E489": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "VpcPublicSubnet2RouteTableAssociationDD5762D8": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+ },
+ "SubnetId": {
+ "Ref": "VpcPublicSubnet2Subnet691E08A3"
+ }
+ }
+ },
+ "VpcPublicSubnet2DefaultRoute97F91067": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "GatewayId": {
+ "Ref": "VpcIGWD7BA715C"
+ }
+ },
+ "DependsOn": [
+ "VpcVPCGWBF912B6E"
+ ]
+ },
+ "VpcPublicSubnet2EIP3C605A87": {
+ "Type": "AWS::EC2::EIP",
+ "Properties": {
+ "Domain": "vpc",
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "VpcPublicSubnet2NATGateway9182C01D": {
+ "Type": "AWS::EC2::NatGateway",
+ "Properties": {
+ "SubnetId": {
+ "Ref": "VpcPublicSubnet2Subnet691E08A3"
+ },
+ "AllocationId": {
+ "Fn::GetAtt": [
+ "VpcPublicSubnet2EIP3C605A87",
+ "AllocationId"
+ ]
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ },
+ "DependsOn": [
+ "VpcPublicSubnet2DefaultRoute97F91067",
+ "VpcPublicSubnet2RouteTableAssociationDD5762D8"
+ ]
+ },
+ "VpcPrivateSubnet1Subnet536B997A": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.128.0/18",
+ "MapPublicIpOnLaunch": false,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Private"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Private"
+ },
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "VpcPrivateSubnet1RouteTableB2C5B500": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "VpcPrivateSubnet1RouteTableAssociation70C59FA6": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+ },
+ "SubnetId": {
+ "Ref": "VpcPrivateSubnet1Subnet536B997A"
+ }
+ }
+ },
+ "VpcPrivateSubnet1DefaultRouteBE02A9ED": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "NatGatewayId": {
+ "Ref": "VpcPublicSubnet1NATGateway4D7517AA"
+ }
+ }
+ },
+ "VpcPrivateSubnet2Subnet3788AAA1": {
+ "Type": "AWS::EC2::Subnet",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "AvailabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "CidrBlock": "10.0.192.0/18",
+ "MapPublicIpOnLaunch": false,
+ "Tags": [
+ {
+ "Key": "aws-cdk:subnet-name",
+ "Value": "Private"
+ },
+ {
+ "Key": "aws-cdk:subnet-type",
+ "Value": "Private"
+ },
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "VpcPrivateSubnet2RouteTableA678073B": {
+ "Type": "AWS::EC2::RouteTable",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "VpcPrivateSubnet2RouteTableAssociationA89CAD56": {
+ "Type": "AWS::EC2::SubnetRouteTableAssociation",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+ },
+ "SubnetId": {
+ "Ref": "VpcPrivateSubnet2Subnet3788AAA1"
+ }
+ }
+ },
+ "VpcPrivateSubnet2DefaultRoute060D2087": {
+ "Type": "AWS::EC2::Route",
+ "Properties": {
+ "RouteTableId": {
+ "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+ },
+ "DestinationCidrBlock": "0.0.0.0/0",
+ "NatGatewayId": {
+ "Ref": "VpcPublicSubnet2NATGateway9182C01D"
+ }
+ }
+ },
+ "VpcIGWD7BA715C": {
+ "Type": "AWS::EC2::InternetGateway",
+ "Properties": {
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Vpc"
+ }
+ ]
+ }
+ },
+ "VpcVPCGWBF912B6E": {
+ "Type": "AWS::EC2::VPCGatewayAttachment",
+ "Properties": {
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "InternetGatewayId": {
+ "Ref": "VpcIGWD7BA715C"
+ }
+ }
+ },
+ "VpcRestrictDefaultSecurityGroupCustomResourceC73DA2BE": {
+ "Type": "Custom::VpcRestrictDefaultSG",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E",
+ "Arn"
+ ]
+ },
+ "DefaultSecurityGroupId": {
+ "Fn::GetAtt": [
+ "Vpc8378EB38",
+ "DefaultSecurityGroup"
+ ]
+ },
+ "Account": {
+ "Ref": "AWS::AccountId"
+ }
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ]
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ }
+ ],
+ "Policies": [
+ {
+ "PolicyName": "Inline",
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": [
+ "ec2:AuthorizeSecurityGroupIngress",
+ "ec2:AuthorizeSecurityGroupEgress",
+ "ec2:RevokeSecurityGroupIngress",
+ "ec2:RevokeSecurityGroupEgress"
+ ],
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":ec2:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":security-group/",
+ {
+ "Fn::GetAtt": [
+ "Vpc8378EB38",
+ "DefaultSecurityGroup"
+ ]
+ }
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "S3Key": "ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd.zip"
+ },
+ "Timeout": 900,
+ "MemorySize": 128,
+ "Handler": "__entrypoint__.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0",
+ "Arn"
+ ]
+ },
+ "Runtime": "nodejs16.x",
+ "Description": "Lambda function for removing all inbound/outbound rules from the VPC default security group"
+ },
+ "DependsOn": [
+ "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0"
+ ]
+ },
+ "Certificate4E7ABB08": {
+ "Type": "AWS::CertificateManager::Certificate",
+ "Properties": {
+ "DomainName": "*.example.com",
+ "DomainValidationOptions": [
+ {
+ "DomainName": "*.example.com",
+ "HostedZoneId": "Z23ABC4XYZL05B"
+ }
+ ],
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "IntegAlbOidc/Certificate"
+ }
+ ],
+ "ValidationMethod": "DNS"
+ }
+ },
+ "UserPool6BA7E5F2": {
+ "Type": "AWS::Cognito::UserPool",
+ "Properties": {
+ "AccountRecoverySetting": {
+ "RecoveryMechanisms": [
+ {
+ "Name": "verified_phone_number",
+ "Priority": 1
+ },
+ {
+ "Name": "verified_email",
+ "Priority": 2
+ }
+ ]
+ },
+ "AdminCreateUserConfig": {
+ "AllowAdminCreateUserOnly": true
+ },
+ "AutoVerifiedAttributes": [
+ "email"
+ ],
+ "EmailVerificationMessage": "The verification code to your new account is {####}",
+ "EmailVerificationSubject": "Verify your new account",
+ "SmsVerificationMessage": "The verification code to your new account is {####}",
+ "UsernameAttributes": [
+ "email"
+ ],
+ "VerificationMessageTemplate": {
+ "DefaultEmailOption": "CONFIRM_WITH_CODE",
+ "EmailMessage": "The verification code to your new account is {####}",
+ "EmailSubject": "Verify your new account",
+ "SmsMessage": "The verification code to your new account is {####}"
+ }
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "UserPoolDomainD0EA232A": {
+ "Type": "AWS::Cognito::UserPoolDomain",
+ "Properties": {
+ "Domain": "z23abc4xyzl05b",
+ "UserPoolId": {
+ "Ref": "UserPool6BA7E5F2"
+ }
+ }
+ },
+ "UserPoolUserPoolClient40176907": {
+ "Type": "AWS::Cognito::UserPoolClient",
+ "Properties": {
+ "UserPoolId": {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "AllowedOAuthFlows": [
+ "code"
+ ],
+ "AllowedOAuthFlowsUserPoolClient": true,
+ "AllowedOAuthScopes": [
+ "profile",
+ "phone",
+ "email",
+ "openid",
+ "aws.cognito.signin.user.admin"
+ ],
+ "CallbackURLs": [
+ "https://*.example.com/oauth2/idpresponse"
+ ],
+ "GenerateSecret": true,
+ "SupportedIdentityProviders": [
+ "COGNITO"
+ ]
+ }
+ },
+ "UserPoolUserPoolClientDescribeCognitoUserPoolClientA6EA22D2": {
+ "Type": "Custom::DescribeCognitoUserPoolClient",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd22872D164C4C",
+ "Arn"
+ ]
+ },
+ "Create": {
+ "Fn::Join": [
+ "",
+ [
+ "{\"region\":\"",
+ {
+ "Ref": "AWS::Region"
+ },
+ "\",\"service\":\"CognitoIdentityServiceProvider\",\"action\":\"describeUserPoolClient\",\"parameters\":{\"UserPoolId\":\"",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "\",\"ClientId\":\"",
+ {
+ "Ref": "UserPoolUserPoolClient40176907"
+ },
+ "\"},\"physicalResourceId\":{\"id\":\"",
+ {
+ "Ref": "UserPoolUserPoolClient40176907"
+ },
+ "\"}}"
+ ]
+ ]
+ },
+ "Update": {
+ "Fn::Join": [
+ "",
+ [
+ "{\"region\":\"",
+ {
+ "Ref": "AWS::Region"
+ },
+ "\",\"service\":\"CognitoIdentityServiceProvider\",\"action\":\"describeUserPoolClient\",\"parameters\":{\"UserPoolId\":\"",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "\",\"ClientId\":\"",
+ {
+ "Ref": "UserPoolUserPoolClient40176907"
+ },
+ "\"},\"physicalResourceId\":{\"id\":\"",
+ {
+ "Ref": "UserPoolUserPoolClient40176907"
+ },
+ "\"}}"
+ ]
+ ]
+ },
+ "InstallLatestAwsSdk": false
+ },
+ "DependsOn": [
+ "UserPoolUserPoolClientDescribeCognitoUserPoolClientCustomResourcePolicyFFF2174F"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "UserPoolUserPoolClientDescribeCognitoUserPoolClientCustomResourcePolicyFFF2174F": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:DescribeUserPoolClient",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "UserPoolUserPoolClientDescribeCognitoUserPoolClientCustomResourcePolicyFFF2174F",
+ "Roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "LoadBalancerBE9EEC3A": {
+ "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
+ "Properties": {
+ "LoadBalancerAttributes": [
+ {
+ "Key": "deletion_protection.enabled",
+ "Value": "false"
+ }
+ ],
+ "Scheme": "internet-facing",
+ "SecurityGroups": [
+ {
+ "Fn::GetAtt": [
+ "LoadBalancerSecurityGroupA28D6DD7",
+ "GroupId"
+ ]
+ }
+ ],
+ "Subnets": [
+ {
+ "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+ },
+ {
+ "Ref": "VpcPublicSubnet2Subnet691E08A3"
+ }
+ ],
+ "Type": "application"
+ },
+ "DependsOn": [
+ "VpcPublicSubnet1DefaultRoute3DA9E72A",
+ "VpcPublicSubnet1RouteTableAssociation97140677",
+ "VpcPublicSubnet2DefaultRoute97F91067",
+ "VpcPublicSubnet2RouteTableAssociationDD5762D8"
+ ]
+ },
+ "LoadBalancerSecurityGroupA28D6DD7": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Properties": {
+ "GroupDescription": "Automatically created Security Group for ELB IntegAlbOidcLoadBalancer3609D530",
+ "SecurityGroupEgress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow to IdP endpoint",
+ "FromPort": 443,
+ "IpProtocol": "tcp",
+ "ToPort": 443
+ }
+ ],
+ "SecurityGroupIngress": [
+ {
+ "CidrIp": "0.0.0.0/0",
+ "Description": "Allow from anyone on port 443",
+ "FromPort": 443,
+ "IpProtocol": "tcp",
+ "ToPort": 443
+ }
+ ],
+ "VpcId": {
+ "Ref": "Vpc8378EB38"
+ }
+ }
+ },
+ "LoadBalancerListenerE1A099B9": {
+ "Type": "AWS::ElasticLoadBalancingV2::Listener",
+ "Properties": {
+ "DefaultActions": [
+ {
+ "AuthenticateOidcConfig": {
+ "AuthorizationEndpoint": {
+ "Fn::Join": [
+ "",
+ [
+ "https://",
+ {
+ "Ref": "UserPoolDomainD0EA232A"
+ },
+ ".auth.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazoncognito.com/oauth2/authorize"
+ ]
+ ]
+ },
+ "ClientId": {
+ "Ref": "UserPoolUserPoolClient40176907"
+ },
+ "ClientSecret": {
+ "Fn::GetAtt": [
+ "UserPoolUserPoolClientDescribeCognitoUserPoolClientA6EA22D2",
+ "UserPoolClient.ClientSecret"
+ ]
+ },
+ "Issuer": {
+ "Fn::Join": [
+ "",
+ [
+ "https://cognito-idp.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazonaws.com/",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ }
+ ]
+ ]
+ },
+ "TokenEndpoint": {
+ "Fn::Join": [
+ "",
+ [
+ "https://",
+ {
+ "Ref": "UserPoolDomainD0EA232A"
+ },
+ ".auth.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazoncognito.com/oauth2/token"
+ ]
+ ]
+ },
+ "UserInfoEndpoint": {
+ "Fn::Join": [
+ "",
+ [
+ "https://",
+ {
+ "Ref": "UserPoolDomainD0EA232A"
+ },
+ ".auth.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazoncognito.com/oauth2/userInfo"
+ ]
+ ]
+ }
+ },
+ "Order": 1,
+ "Type": "authenticate-oidc"
+ },
+ {
+ "FixedResponseConfig": {
+ "ContentType": "text/plain",
+ "MessageBody": "Authenticated",
+ "StatusCode": "200"
+ },
+ "Order": 2,
+ "Type": "fixed-response"
+ }
+ ],
+ "LoadBalancerArn": {
+ "Ref": "LoadBalancerBE9EEC3A"
+ },
+ "Certificates": [
+ {
+ "CertificateArn": {
+ "Ref": "Certificate4E7ABB08"
+ }
+ }
+ ],
+ "Port": 443,
+ "Protocol": "HTTPS"
+ }
+ },
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "AWS679f53fac002430cb0da5b7982bd22872D164C4C": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "S3Key": "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce.zip"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
+ "Arn"
+ ]
+ },
+ "Handler": "index.handler",
+ "Runtime": {
+ "Fn::FindInMap": [
+ "DefaultCrNodeVersionMap",
+ {
+ "Ref": "AWS::Region"
+ },
+ "value"
+ ]
+ },
+ "Timeout": 120
+ },
+ "DependsOn": [
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ ]
+ },
+ "ARecordE7B57761": {
+ "Type": "AWS::Route53::RecordSet",
+ "Properties": {
+ "Name": "example.com.",
+ "Type": "A",
+ "AliasTarget": {
+ "DNSName": {
+ "Fn::Join": [
+ "",
+ [
+ "dualstack.",
+ {
+ "Fn::GetAtt": [
+ "LoadBalancerBE9EEC3A",
+ "DNSName"
+ ]
+ }
+ ]
+ ]
+ },
+ "HostedZoneId": {
+ "Fn::GetAtt": [
+ "LoadBalancerBE9EEC3A",
+ "CanonicalHostedZoneID"
+ ]
+ }
+ },
+ "HostedZoneId": "Z23ABC4XYZL05B"
+ }
+ },
+ "UserFDDCDD17": {
+ "Type": "Custom::CognitoUser",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd22872D164C4C",
+ "Arn"
+ ]
+ },
+ "Create": {
+ "Fn::Join": [
+ "",
+ [
+ "{\"service\":\"CognitoIdentityServiceProvider\",\"action\":\"adminCreateUser\",\"parameters\":{\"UserPoolId\":\"",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "\",\"Username\":\"test-user@example.com\",\"UserAttributes\":[{\"Name\":\"email\",\"Value\":\"test-user@example.com\"},{\"Name\":\"email_verified\",\"Value\":\"true\"}],\"MessageAction\":\"SUPPRESS\"},\"physicalResourceId\":{\"id\":\"User\"}}"
+ ]
+ ]
+ },
+ "InstallLatestAwsSdk": false
+ },
+ "DependsOn": [
+ "UserCustomResourcePolicyC2EB5139"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "UserCustomResourcePolicyC2EB5139": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminCreateUser",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "UserCustomResourcePolicyC2EB5139",
+ "Roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "UserSetUserPasswordAD2F2A64": {
+ "Type": "Custom::CognitoUserPassword",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd22872D164C4C",
+ "Arn"
+ ]
+ },
+ "Create": {
+ "Fn::Join": [
+ "",
+ [
+ "{\"service\":\"CognitoIdentityServiceProvider\",\"action\":\"adminSetUserPassword\",\"parameters\":{\"UserPoolId\":\"",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "\",\"Username\":\"",
+ {
+ "Fn::GetAtt": [
+ "UserFDDCDD17",
+ "User.Username"
+ ]
+ },
+ "\",\"Password\":\"TestUser@123\",\"Permanent\":true},\"physicalResourceId\":{\"id\":\"SetUserPassword\"}}"
+ ]
+ ]
+ },
+ "InstallLatestAwsSdk": false
+ },
+ "DependsOn": [
+ "UserCustomResourcePolicyC2EB5139",
+ "UserFDDCDD17",
+ "UserSetUserPasswordCustomResourcePolicy7B250C76"
+ ],
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "UserSetUserPasswordCustomResourcePolicy7B250C76": {
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminSetUserPassword",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "PolicyName": "UserSetUserPasswordCustomResourcePolicy7B250C76",
+ "Roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ },
+ "DependsOn": [
+ "UserCustomResourcePolicyC2EB5139",
+ "UserFDDCDD17"
+ ]
+ },
+ "SigninServiceRole24B8BB32": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "Signin352C80E6": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Code": {
+ "S3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "S3Key": "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302.zip"
+ },
+ "Role": {
+ "Fn::GetAtt": [
+ "SigninServiceRole24B8BB32",
+ "Arn"
+ ]
+ },
+ "Environment": {
+ "Variables": {
+ "TEST_USERNAME": "test-user@example.com",
+ "TEST_PASSWORD": "TestUser@123",
+ "TEST_URL": "https://*.example.com"
+ }
+ },
+ "FunctionName": "cdk-integ-alb-oidc-signin-handler",
+ "Handler": "index.handler",
+ "MemorySize": 1024,
+ "Runtime": "nodejs18.x",
+ "Timeout": 300
+ },
+ "DependsOn": [
+ "SigninServiceRole24B8BB32"
+ ]
+ }
+ },
+ "Mappings": {
+ "DefaultCrNodeVersionMap": {
+ "af-south-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-east-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-northeast-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-northeast-2": {
+ "value": "nodejs16.x"
+ },
+ "ap-northeast-3": {
+ "value": "nodejs16.x"
+ },
+ "ap-south-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-south-2": {
+ "value": "nodejs16.x"
+ },
+ "ap-southeast-1": {
+ "value": "nodejs16.x"
+ },
+ "ap-southeast-2": {
+ "value": "nodejs16.x"
+ },
+ "ap-southeast-3": {
+ "value": "nodejs16.x"
+ },
+ "ca-central-1": {
+ "value": "nodejs16.x"
+ },
+ "cn-north-1": {
+ "value": "nodejs16.x"
+ },
+ "cn-northwest-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-central-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-central-2": {
+ "value": "nodejs16.x"
+ },
+ "eu-north-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-south-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-south-2": {
+ "value": "nodejs16.x"
+ },
+ "eu-west-1": {
+ "value": "nodejs16.x"
+ },
+ "eu-west-2": {
+ "value": "nodejs16.x"
+ },
+ "eu-west-3": {
+ "value": "nodejs16.x"
+ },
+ "me-central-1": {
+ "value": "nodejs16.x"
+ },
+ "me-south-1": {
+ "value": "nodejs16.x"
+ },
+ "sa-east-1": {
+ "value": "nodejs16.x"
+ },
+ "us-east-1": {
+ "value": "nodejs16.x"
+ },
+ "us-east-2": {
+ "value": "nodejs16.x"
+ },
+ "us-gov-east-1": {
+ "value": "nodejs16.x"
+ },
+ "us-gov-west-1": {
+ "value": "nodejs16.x"
+ },
+ "us-iso-east-1": {
+ "value": "nodejs14.x"
+ },
+ "us-iso-west-1": {
+ "value": "nodejs14.x"
+ },
+ "us-isob-east-1": {
+ "value": "nodejs14.x"
+ },
+ "us-west-1": {
+ "value": "nodejs16.x"
+ },
+ "us-west-2": {
+ "value": "nodejs16.x"
+ }
+ }
+ },
+ "Outputs": {
+ "ExportsOutputRefSignin352C80E64BA58F71": {
+ "Value": {
+ "Ref": "Signin352C80E6"
+ },
+ "Export": {
+ "Name": "IntegAlbOidc:ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ }
+ },
+ "Parameters": {
+ "BootstrapVersion": {
+ "Type": "AWS::SSM::Parameter::Value",
+ "Default": "/cdk-bootstrap/hnb659fds/version",
+ "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
+ }
+ },
+ "Rules": {
+ "CheckBootstrapVersion": {
+ "Assertions": [
+ {
+ "Assert": {
+ "Fn::Not": [
+ {
+ "Fn::Contains": [
+ [
+ "1",
+ "2",
+ "3",
+ "4",
+ "5"
+ ],
+ {
+ "Ref": "BootstrapVersion"
+ }
+ ]
+ }
+ ]
+ },
+ "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets.json
new file mode 100644
index 0000000000000..d1603451f8caa
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets.json
@@ -0,0 +1,32 @@
+{
+ "version": "31.0.0",
+ "files": {
+ "36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4": {
+ "source": {
+ "path": "asset.36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4.bundle",
+ "packaging": "zip"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4.zip",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ },
+ "8e06e2daf38e95962b941bf8be88c2adb10e55aafddcbd59930a4ef29bc8c79e": {
+ "source": {
+ "path": "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.template.json",
+ "packaging": "file"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+ "objectKey": "8e06e2daf38e95962b941bf8be88c2adb10e55aafddcbd59930a4ef29bc8c79e.json",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
+ }
+ },
+ "dockerImages": {}
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.template.json
new file mode 100644
index 0000000000000..d471bfc1a36fe
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.template.json
@@ -0,0 +1,178 @@
+{
+ "Resources": {
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd": {
+ "Type": "Custom::DeployAssert@SdkCallLambdainvoke",
+ "Properties": {
+ "ServiceToken": {
+ "Fn::GetAtt": [
+ "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F",
+ "Arn"
+ ]
+ },
+ "service": "Lambda",
+ "api": "invoke",
+ "expected": "{\"$ObjectLike\":{\"Payload\":\"\\\"Authenticated\\\"\"}}",
+ "parameters": {
+ "FunctionName": {
+ "Fn::ImportValue": "IntegAlbOidc:ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ },
+ "flattenResponse": "false",
+ "salt": "1683259223329"
+ },
+ "UpdateReplacePolicy": "Delete",
+ "DeletionPolicy": "Delete"
+ },
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bdInvoke5A72F915": {
+ "Type": "AWS::Lambda::Permission",
+ "Properties": {
+ "Action": "lambda:InvokeFunction",
+ "FunctionName": {
+ "Fn::ImportValue": "IntegAlbOidc:ExportsOutputRefSignin352C80E64BA58F71"
+ },
+ "Principal": {
+ "Fn::GetAtt": [
+ "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73",
+ "Arn"
+ ]
+ }
+ }
+ },
+ "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": {
+ "Type": "AWS::IAM::Role",
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ]
+ },
+ "ManagedPolicyArns": [
+ {
+ "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ }
+ ],
+ "Policies": [
+ {
+ "PolicyName": "Inline",
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": [
+ "lambda:Invoke"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ "*"
+ ]
+ },
+ {
+ "Action": [
+ "lambda:InvokeFunction"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":lambda:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":function:",
+ {
+ "Fn::ImportValue": "IntegAlbOidc:ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": {
+ "Type": "AWS::Lambda::Function",
+ "Properties": {
+ "Runtime": "nodejs14.x",
+ "Code": {
+ "S3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "S3Key": "36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4.zip"
+ },
+ "Timeout": 120,
+ "Handler": "index.handler",
+ "Role": {
+ "Fn::GetAtt": [
+ "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73",
+ "Arn"
+ ]
+ }
+ }
+ }
+ },
+ "Outputs": {
+ "AssertionResultsLambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd": {
+ "Value": {
+ "Fn::GetAtt": [
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd",
+ "assertion"
+ ]
+ }
+ }
+ },
+ "Parameters": {
+ "BootstrapVersion": {
+ "Type": "AWS::SSM::Parameter::Value",
+ "Default": "/cdk-bootstrap/hnb659fds/version",
+ "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
+ }
+ },
+ "Rules": {
+ "CheckBootstrapVersion": {
+ "Assertions": [
+ {
+ "Assert": {
+ "Fn::Not": [
+ {
+ "Fn::Contains": [
+ [
+ "1",
+ "2",
+ "3",
+ "4",
+ "5"
+ ],
+ {
+ "Ref": "BootstrapVersion"
+ }
+ ]
+ }
+ ]
+ },
+ "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts
new file mode 100644
index 0000000000000..da5565949aa48
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.d.ts
@@ -0,0 +1 @@
+export declare const handler: AWSLambda.Handler;
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js
new file mode 100644
index 0000000000000..78672677bf37d
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.js
@@ -0,0 +1,34 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.handler = void 0;
+/* eslint-disable @typescript-eslint/no-require-imports */
+const child_process_1 = require("child_process");
+const url = process.env.TEST_URL;
+const setupBrowser = async () => {
+ (0, child_process_1.execSync)('HOME=/tmp npm install puppeteer-core @sparticuz/chromium --omit=dev --no-package-lock --no-save --prefix /tmp');
+ const puppeteer = require('/tmp/node_modules/puppeteer-core');
+ const chromium = require('/tmp/node_modules/@sparticuz/chromium');
+ const browser = await puppeteer.launch({
+ args: chromium.args,
+ defaultViewport: chromium.defaultViewport,
+ executablePath: await chromium.executablePath(),
+ headless: chromium.headless,
+ });
+ return browser;
+};
+const handler = async (_event) => {
+ const browser = await setupBrowser();
+ const page = await browser.newPage();
+ await page.goto(url, {
+ waitUntil: ['load', 'networkidle0'],
+ timeout: 30000,
+ });
+ await page.type("div.visible-lg input[name='username']", process.env.TEST_USERNAME);
+ await page.type("div.visible-lg input[name='password']", process.env.TEST_PASSWORD);
+ await page.click("div.visible-lg input[type='submit']");
+ const body = await page.waitForSelector('body');
+ const textContent = await body.evaluate((el) => el.textContent);
+ return textContent;
+};
+exports.handler = handler;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwwREFBMEQ7QUFDMUQsaURBQXlDO0FBRXpDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO0FBQ2pDLE1BQU0sWUFBWSxHQUFHLEtBQUssSUFBSSxFQUFFO0lBQzlCLElBQUEsd0JBQVEsRUFBQywrR0FBK0csQ0FBQyxDQUFDO0lBQzFILE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO0lBQzlELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUNyQyxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUk7UUFDbkIsZUFBZSxFQUFFLFFBQVEsQ0FBQyxlQUFlO1FBQ3pDLGNBQWMsRUFBRSxNQUFNLFFBQVEsQ0FBQyxjQUFjLEVBQUU7UUFDL0MsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRO0tBQzVCLENBQUMsQ0FBQztJQUNILE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMsQ0FBQztBQUVLLE1BQU0sT0FBTyxHQUFzQixLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7SUFDekQsTUFBTSxPQUFPLEdBQUcsTUFBTSxZQUFZLEVBQUUsQ0FBQztJQUNyQyxNQUFNLElBQUksR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNyQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO1FBQ25CLFNBQVMsRUFBRSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUM7UUFDbkMsT0FBTyxFQUFFLEtBQUs7S0FDZixDQUFDLENBQUM7SUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsdUNBQXVDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNwRixNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsdUNBQXVDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNwRixNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztJQUN4RCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEQsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckUsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDO0FBYlcsUUFBQSxPQUFPLFdBYWxCIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAqL1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcblxuY29uc3QgdXJsID0gcHJvY2Vzcy5lbnYuVEVTVF9VUkw7XG5jb25zdCBzZXR1cEJyb3dzZXIgPSBhc3luYyAoKSA9PiB7XG4gIGV4ZWNTeW5jKCdIT01FPS90bXAgbnBtIGluc3RhbGwgcHVwcGV0ZWVyLWNvcmUgQHNwYXJ0aWN1ei9jaHJvbWl1bSAtLW9taXQ9ZGV2IC0tbm8tcGFja2FnZS1sb2NrIC0tbm8tc2F2ZSAtLXByZWZpeCAvdG1wJyk7XG4gIGNvbnN0IHB1cHBldGVlciA9IHJlcXVpcmUoJy90bXAvbm9kZV9tb2R1bGVzL3B1cHBldGVlci1jb3JlJyk7XG4gIGNvbnN0IGNocm9taXVtID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvQHNwYXJ0aWN1ei9jaHJvbWl1bScpO1xuICBjb25zdCBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaCh7XG4gICAgYXJnczogY2hyb21pdW0uYXJncyxcbiAgICBkZWZhdWx0Vmlld3BvcnQ6IGNocm9taXVtLmRlZmF1bHRWaWV3cG9ydCxcbiAgICBleGVjdXRhYmxlUGF0aDogYXdhaXQgY2hyb21pdW0uZXhlY3V0YWJsZVBhdGgoKSxcbiAgICBoZWFkbGVzczogY2hyb21pdW0uaGVhZGxlc3MsXG4gIH0pO1xuICByZXR1cm4gYnJvd3Nlcjtcbn07XG5cbmV4cG9ydCBjb25zdCBoYW5kbGVyOiBBV1NMYW1iZGEuSGFuZGxlciA9IGFzeW5jIChfZXZlbnQpID0+IHtcbiAgY29uc3QgYnJvd3NlciA9IGF3YWl0IHNldHVwQnJvd3NlcigpO1xuICBjb25zdCBwYWdlID0gYXdhaXQgYnJvd3Nlci5uZXdQYWdlKCk7XG4gIGF3YWl0IHBhZ2UuZ290byh1cmwsIHtcbiAgICB3YWl0VW50aWw6IFsnbG9hZCcsICduZXR3b3JraWRsZTAnXSxcbiAgICB0aW1lb3V0OiAzMDAwMCxcbiAgfSk7XG4gIGF3YWl0IHBhZ2UudHlwZShcImRpdi52aXNpYmxlLWxnIGlucHV0W25hbWU9J3VzZXJuYW1lJ11cIiwgcHJvY2Vzcy5lbnYuVEVTVF9VU0VSTkFNRSk7XG4gIGF3YWl0IHBhZ2UudHlwZShcImRpdi52aXNpYmxlLWxnIGlucHV0W25hbWU9J3Bhc3N3b3JkJ11cIiwgcHJvY2Vzcy5lbnYuVEVTVF9QQVNTV09SRCk7XG4gIGF3YWl0IHBhZ2UuY2xpY2soXCJkaXYudmlzaWJsZS1sZyBpbnB1dFt0eXBlPSdzdWJtaXQnXVwiKTtcbiAgY29uc3QgYm9keSA9IGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKCdib2R5Jyk7XG4gIGNvbnN0IHRleHRDb250ZW50ID0gYXdhaXQgYm9keS5ldmFsdWF0ZSgoZWw6IGFueSkgPT4gZWwudGV4dENvbnRlbnQpO1xuICByZXR1cm4gdGV4dENvbnRlbnQ7XG59O1xuIl19
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts
new file mode 100644
index 0000000000000..9e79dd3fb247a
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302/index.ts
@@ -0,0 +1,31 @@
+/* eslint-disable @typescript-eslint/no-require-imports */
+import { execSync } from 'child_process';
+
+const url = process.env.TEST_URL;
+const setupBrowser = async () => {
+ execSync('HOME=/tmp npm install puppeteer-core @sparticuz/chromium --omit=dev --no-package-lock --no-save --prefix /tmp');
+ const puppeteer = require('/tmp/node_modules/puppeteer-core');
+ const chromium = require('/tmp/node_modules/@sparticuz/chromium');
+ const browser = await puppeteer.launch({
+ args: chromium.args,
+ defaultViewport: chromium.defaultViewport,
+ executablePath: await chromium.executablePath(),
+ headless: chromium.headless,
+ });
+ return browser;
+};
+
+export const handler: AWSLambda.Handler = async (_event) => {
+ const browser = await setupBrowser();
+ const page = await browser.newPage();
+ await page.goto(url, {
+ waitUntil: ['load', 'networkidle0'],
+ timeout: 30000,
+ });
+ await page.type("div.visible-lg input[name='username']", process.env.TEST_USERNAME);
+ await page.type("div.visible-lg input[name='password']", process.env.TEST_PASSWORD);
+ await page.click("div.visible-lg input[type='submit']");
+ const body = await page.waitForSelector('body');
+ const textContent = await body.evaluate((el: any) => el.textContent);
+ return textContent;
+};
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4.bundle/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4.bundle/index.js
new file mode 100644
index 0000000000000..6f5404d473d1b
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.36618132bd37b6b15f9987b57ad1fbf613f1ad937aec72381232b163ed9c44c4.bundle/index.js
@@ -0,0 +1,1296 @@
+"use strict";
+var __create = Object.create;
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __getProtoOf = Object.getPrototypeOf;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __esm = (fn, res) => function __init() {
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
+};
+var __commonJS = (cb, mod) => function __require() {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
+ // If the importer is in node compatibility mode or this is not an ESM
+ // file that has been converted to a CommonJS file using a Babel-
+ // compatible transform (i.e. "__esModule" has not been set), then set
+ // "default" to the CommonJS "module.exports" for node compatibility.
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
+ mod
+));
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// ../../aws-cdk-lib/assertions/lib/matcher.ts
+var matcher_exports = {};
+__export(matcher_exports, {
+ MatchResult: () => MatchResult,
+ Matcher: () => Matcher
+});
+function* range(n) {
+ for (let i = 0; i < n; i++) {
+ yield i;
+ }
+}
+function* enumFirst(xs) {
+ let first = true;
+ for (const x of xs) {
+ yield [first, x];
+ first = false;
+ }
+}
+var Matcher, MatchResult;
+var init_matcher = __esm({
+ "../../aws-cdk-lib/assertions/lib/matcher.ts"() {
+ "use strict";
+ Matcher = class {
+ /**
+ * Check whether the provided object is a subtype of the `IMatcher`.
+ */
+ static isMatcher(x) {
+ return x && x instanceof Matcher;
+ }
+ };
+ MatchResult = class {
+ constructor(target) {
+ this.failuresHere = /* @__PURE__ */ new Map();
+ this.captures = /* @__PURE__ */ new Map();
+ this.finalized = false;
+ this.innerMatchFailures = /* @__PURE__ */ new Map();
+ this._hasFailed = false;
+ this._failCount = 0;
+ this._cost = 0;
+ this.target = target;
+ }
+ /**
+ * DEPRECATED
+ * @deprecated use recordFailure()
+ */
+ push(matcher, path, message) {
+ return this.recordFailure({ matcher, path, message });
+ }
+ /**
+ * Record a new failure into this result at a specific path.
+ */
+ recordFailure(failure) {
+ const failKey = failure.path.join(".");
+ let list = this.failuresHere.get(failKey);
+ if (!list) {
+ list = [];
+ this.failuresHere.set(failKey, list);
+ }
+ this._failCount += 1;
+ this._cost += failure.cost ?? 1;
+ list.push(failure);
+ this._hasFailed = true;
+ return this;
+ }
+ /** Whether the match is a success */
+ get isSuccess() {
+ return !this._hasFailed;
+ }
+ /** Does the result contain any failures. If not, the result is a success */
+ hasFailed() {
+ return this._hasFailed;
+ }
+ /** The number of failures */
+ get failCount() {
+ return this._failCount;
+ }
+ /** The cost of the failures so far */
+ get failCost() {
+ return this._cost;
+ }
+ /**
+ * Compose the results of a previous match as a subtree.
+ * @param id the id of the parent tree.
+ */
+ compose(id, inner) {
+ if (inner.hasFailed()) {
+ this._hasFailed = true;
+ this._failCount += inner.failCount;
+ this._cost += inner._cost;
+ this.innerMatchFailures.set(id, inner);
+ }
+ inner.captures.forEach((vals, capture) => {
+ vals.forEach((value) => this.recordCapture({ capture, value }));
+ });
+ return this;
+ }
+ /**
+ * Prepare the result to be analyzed.
+ * This API *must* be called prior to analyzing these results.
+ */
+ finished() {
+ if (this.finalized) {
+ return this;
+ }
+ if (this.failCount === 0) {
+ this.captures.forEach((vals, cap) => cap._captured.push(...vals));
+ }
+ this.finalized = true;
+ return this;
+ }
+ /**
+ * Render the failed match in a presentable way
+ *
+ * Prefer using `renderMismatch` over this method. It is left for backwards
+ * compatibility for test suites that expect it, but `renderMismatch()` will
+ * produce better output.
+ */
+ toHumanStrings() {
+ const failures = new Array();
+ debugger;
+ recurse(this, []);
+ return failures.map((r) => {
+ const loc = r.path.length === 0 ? "" : ` at /${r.path.join("/")}`;
+ return "" + r.message + loc + ` (using ${r.matcher.name} matcher)`;
+ });
+ function recurse(x, prefix) {
+ for (const fail of Array.from(x.failuresHere.values()).flat()) {
+ failures.push({
+ matcher: fail.matcher,
+ message: fail.message,
+ path: [...prefix, ...fail.path]
+ });
+ }
+ for (const [key, inner] of x.innerMatchFailures.entries()) {
+ recurse(inner, [...prefix, key]);
+ }
+ }
+ }
+ /**
+ * Do a deep render of the match result, showing the structure mismatches in context
+ */
+ renderMismatch() {
+ if (!this.hasFailed()) {
+ return "";
+ }
+ const parts = new Array();
+ const indents = new Array();
+ emitFailures(this, "");
+ recurse(this);
+ return moveMarkersToFront(parts.join("").trimEnd());
+ function emit(x) {
+ if (x === void 0) {
+ debugger;
+ }
+ parts.push(x.replace(/\n/g, `
+${indents.join("")}`));
+ }
+ function emitFailures(r, path, scrapSet) {
+ for (const fail of r.failuresHere.get(path) ?? []) {
+ emit(`!! ${fail.message}
+`);
+ }
+ scrapSet == null ? void 0 : scrapSet.delete(path);
+ }
+ function recurse(r) {
+ const remainingFailures = new Set(Array.from(r.failuresHere.keys()).filter((x) => x !== ""));
+ if (Array.isArray(r.target)) {
+ indents.push(" ");
+ emit("[\n");
+ for (const [first, i] of enumFirst(range(r.target.length))) {
+ if (!first) {
+ emit(",\n");
+ }
+ emitFailures(r, `${i}`, remainingFailures);
+ const innerMatcher = r.innerMatchFailures.get(`${i}`);
+ if (innerMatcher) {
+ emitFailures(innerMatcher, "");
+ recurseComparingValues(innerMatcher, r.target[i]);
+ } else {
+ emit(renderAbridged(r.target[i]));
+ }
+ }
+ emitRemaining();
+ indents.pop();
+ emit("\n]");
+ return;
+ }
+ if (r.target && typeof r.target === "object") {
+ indents.push(" ");
+ emit("{\n");
+ const keys = Array.from(/* @__PURE__ */ new Set([
+ ...Object.keys(r.target),
+ ...Array.from(remainingFailures)
+ ])).sort();
+ for (const [first, key] of enumFirst(keys)) {
+ if (!first) {
+ emit(",\n");
+ }
+ emitFailures(r, key, remainingFailures);
+ const innerMatcher = r.innerMatchFailures.get(key);
+ if (innerMatcher) {
+ emitFailures(innerMatcher, "");
+ emit(`${jsonify(key)}: `);
+ recurseComparingValues(innerMatcher, r.target[key]);
+ } else {
+ emit(`${jsonify(key)}: `);
+ emit(renderAbridged(r.target[key]));
+ }
+ }
+ emitRemaining();
+ indents.pop();
+ emit("\n}");
+ return;
+ }
+ emitRemaining();
+ emit(jsonify(r.target));
+ function emitRemaining() {
+ if (remainingFailures.size > 0) {
+ emit("\n");
+ }
+ for (const key of remainingFailures) {
+ emitFailures(r, key);
+ }
+ }
+ }
+ function recurseComparingValues(inner, actualValue) {
+ if (inner.target === actualValue) {
+ return recurse(inner);
+ }
+ emit(renderAbridged(actualValue));
+ emit(" <*> ");
+ recurse(inner);
+ }
+ function renderAbridged(x) {
+ if (Array.isArray(x)) {
+ switch (x.length) {
+ case 0:
+ return "[]";
+ case 1:
+ return `[ ${renderAbridged(x[0])} ]`;
+ case 2:
+ if (x.every((e) => ["number", "boolean", "string"].includes(typeof e))) {
+ return `[ ${x.map(renderAbridged).join(", ")} ]`;
+ }
+ return "[ ... ]";
+ default:
+ return "[ ... ]";
+ }
+ }
+ if (x && typeof x === "object") {
+ const keys = Object.keys(x);
+ switch (keys.length) {
+ case 0:
+ return "{}";
+ case 1:
+ return `{ ${JSON.stringify(keys[0])}: ${renderAbridged(x[keys[0]])} }`;
+ default:
+ return "{ ... }";
+ }
+ }
+ return jsonify(x);
+ }
+ function jsonify(x) {
+ return JSON.stringify(x) ?? "undefined";
+ }
+ function moveMarkersToFront(x) {
+ const re = /^(\s+)!!/gm;
+ return x.replace(re, (_, spaces) => `!!${spaces.substring(0, spaces.length - 2)}`);
+ }
+ }
+ /**
+ * Record a capture against in this match result.
+ */
+ recordCapture(options) {
+ let values = this.captures.get(options.capture);
+ if (values === void 0) {
+ values = [];
+ }
+ values.push(options.value);
+ this.captures.set(options.capture, values);
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/matchers/absent.ts
+var AbsentMatch;
+var init_absent = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/matchers/absent.ts"() {
+ "use strict";
+ init_matcher();
+ AbsentMatch = class extends Matcher {
+ constructor(name) {
+ super();
+ this.name = name;
+ }
+ test(actual) {
+ const result = new MatchResult(actual);
+ if (actual !== void 0) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Received ${actual}, but key should be absent`
+ });
+ }
+ return result;
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/sorting.ts
+function sortKeyComparator(keyFn) {
+ return (a, b) => {
+ const ak = keyFn(a);
+ const bk = keyFn(b);
+ for (let i = 0; i < ak.length && i < bk.length; i++) {
+ const av = ak[i];
+ const bv = bk[i];
+ let diff = 0;
+ if (typeof av === "number" && typeof bv === "number") {
+ diff = av - bv;
+ } else if (typeof av === "string" && typeof bv === "string") {
+ diff = av.localeCompare(bv);
+ }
+ if (diff !== 0) {
+ return diff;
+ }
+ }
+ return bk.length - ak.length;
+ };
+}
+var init_sorting = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/sorting.ts"() {
+ "use strict";
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/sparse-matrix.ts
+var SparseMatrix;
+var init_sparse_matrix = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/sparse-matrix.ts"() {
+ "use strict";
+ SparseMatrix = class {
+ constructor() {
+ this.matrix = /* @__PURE__ */ new Map();
+ }
+ get(row, col) {
+ var _a;
+ return (_a = this.matrix.get(row)) == null ? void 0 : _a.get(col);
+ }
+ row(row) {
+ var _a;
+ return Array.from(((_a = this.matrix.get(row)) == null ? void 0 : _a.entries()) ?? []);
+ }
+ set(row, col, value) {
+ let r = this.matrix.get(row);
+ if (!r) {
+ r = /* @__PURE__ */ new Map();
+ this.matrix.set(row, r);
+ }
+ r.set(col, value);
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/private/type.ts
+function getType(obj) {
+ return Array.isArray(obj) ? "array" : typeof obj;
+}
+var init_type = __esm({
+ "../../aws-cdk-lib/assertions/lib/private/type.ts"() {
+ "use strict";
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/match.ts
+var match_exports = {};
+__export(match_exports, {
+ Match: () => Match
+});
+var Match, LiteralMatch, ArrayMatch, ObjectMatch, SerializedJson, NotMatch, AnyMatch, StringLikeRegexpMatch;
+var init_match = __esm({
+ "../../aws-cdk-lib/assertions/lib/match.ts"() {
+ "use strict";
+ init_matcher();
+ init_absent();
+ init_sorting();
+ init_sparse_matrix();
+ init_type();
+ Match = class {
+ /**
+ * Use this matcher in the place of a field's value, if the field must not be present.
+ */
+ static absent() {
+ return new AbsentMatch("absent");
+ }
+ /**
+ * Matches the specified pattern with the array found in the same relative path of the target.
+ * The set of elements (or matchers) must be in the same order as would be found.
+ * @param pattern the pattern to match
+ */
+ static arrayWith(pattern) {
+ return new ArrayMatch("arrayWith", pattern);
+ }
+ /**
+ * Matches the specified pattern with the array found in the same relative path of the target.
+ * The set of elements (or matchers) must match exactly and in order.
+ * @param pattern the pattern to match
+ */
+ static arrayEquals(pattern) {
+ return new ArrayMatch("arrayEquals", pattern, { subsequence: false });
+ }
+ /**
+ * Deep exact matching of the specified pattern to the target.
+ * @param pattern the pattern to match
+ */
+ static exact(pattern) {
+ return new LiteralMatch("exact", pattern, { partialObjects: false });
+ }
+ /**
+ * Matches the specified pattern to an object found in the same relative path of the target.
+ * The keys and their values (or matchers) must be present in the target but the target can be a superset.
+ * @param pattern the pattern to match
+ */
+ static objectLike(pattern) {
+ return new ObjectMatch("objectLike", pattern);
+ }
+ /**
+ * Matches the specified pattern to an object found in the same relative path of the target.
+ * The keys and their values (or matchers) must match exactly with the target.
+ * @param pattern the pattern to match
+ */
+ static objectEquals(pattern) {
+ return new ObjectMatch("objectEquals", pattern, { partial: false });
+ }
+ /**
+ * Matches any target which does NOT follow the specified pattern.
+ * @param pattern the pattern to NOT match
+ */
+ static not(pattern) {
+ return new NotMatch("not", pattern);
+ }
+ /**
+ * Matches any string-encoded JSON and applies the specified pattern after parsing it.
+ * @param pattern the pattern to match after parsing the encoded JSON.
+ */
+ static serializedJson(pattern) {
+ return new SerializedJson("serializedJson", pattern);
+ }
+ /**
+ * Matches any non-null value at the target.
+ */
+ static anyValue() {
+ return new AnyMatch("anyValue");
+ }
+ /**
+ * Matches targets according to a regular expression
+ */
+ static stringLikeRegexp(pattern) {
+ return new StringLikeRegexpMatch("stringLikeRegexp", pattern);
+ }
+ };
+ LiteralMatch = class extends Matcher {
+ constructor(name, pattern, options = {}) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ this.partialObjects = options.partialObjects ?? false;
+ if (Matcher.isMatcher(this.pattern)) {
+ throw new Error("LiteralMatch cannot directly contain another matcher. Remove the top-level matcher or nest it more deeply.");
+ }
+ }
+ test(actual) {
+ if (Array.isArray(this.pattern)) {
+ return new ArrayMatch(this.name, this.pattern, { subsequence: false, partialObjects: this.partialObjects }).test(actual);
+ }
+ if (typeof this.pattern === "object") {
+ return new ObjectMatch(this.name, this.pattern, { partial: this.partialObjects }).test(actual);
+ }
+ const result = new MatchResult(actual);
+ if (typeof this.pattern !== typeof actual) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected type ${typeof this.pattern} but received ${getType(actual)}`
+ });
+ return result;
+ }
+ if (actual !== this.pattern) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected ${this.pattern} but received ${actual}`
+ });
+ }
+ return result;
+ }
+ };
+ ArrayMatch = class extends Matcher {
+ constructor(name, pattern, options = {}) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ this.subsequence = options.subsequence ?? true;
+ this.partialObjects = options.partialObjects ?? false;
+ }
+ test(actual) {
+ if (!Array.isArray(actual)) {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected type array but received ${getType(actual)}`
+ });
+ }
+ return this.subsequence ? this.testSubsequence(actual) : this.testFullArray(actual);
+ }
+ testFullArray(actual) {
+ const result = new MatchResult(actual);
+ let i = 0;
+ for (; i < this.pattern.length && i < actual.length; i++) {
+ const patternElement = this.pattern[i];
+ const matcher = Matcher.isMatcher(patternElement) ? patternElement : new LiteralMatch(this.name, patternElement, { partialObjects: this.partialObjects });
+ const innerResult = matcher.test(actual[i]);
+ result.compose(`${i}`, innerResult);
+ }
+ if (i < this.pattern.length) {
+ result.recordFailure({
+ matcher: this,
+ message: `Not enough elements in array (expecting ${this.pattern.length}, got ${actual.length})`,
+ path: [`${i}`]
+ });
+ }
+ if (i < actual.length) {
+ result.recordFailure({
+ matcher: this,
+ message: `Too many elements in array (expecting ${this.pattern.length}, got ${actual.length})`,
+ path: [`${i}`]
+ });
+ }
+ return result;
+ }
+ testSubsequence(actual) {
+ const result = new MatchResult(actual);
+ let patternIdx = 0;
+ let actualIdx = 0;
+ const matches = new SparseMatrix();
+ while (patternIdx < this.pattern.length && actualIdx < actual.length) {
+ const patternElement = this.pattern[patternIdx];
+ const matcher = Matcher.isMatcher(patternElement) ? patternElement : new LiteralMatch(this.name, patternElement, { partialObjects: this.partialObjects });
+ const matcherName = matcher.name;
+ if (matcherName == "absent" || matcherName == "anyValue") {
+ throw new Error(`The Matcher ${matcherName}() cannot be nested within arrayWith()`);
+ }
+ const innerResult = matcher.test(actual[actualIdx]);
+ matches.set(patternIdx, actualIdx, innerResult);
+ actualIdx++;
+ if (innerResult.isSuccess) {
+ result.compose(`${actualIdx}`, innerResult);
+ patternIdx++;
+ }
+ }
+ if (patternIdx < this.pattern.length) {
+ for (let spi = 0; spi < patternIdx; spi++) {
+ const foundMatch = matches.row(spi).find(([, r]) => r.isSuccess);
+ if (!foundMatch) {
+ continue;
+ }
+ const [index] = foundMatch;
+ result.compose(`${index}`, new MatchResult(actual[index]).recordFailure({
+ matcher: this,
+ message: `arrayWith pattern ${spi} matched here`,
+ path: [],
+ cost: 0
+ // This is an informational message so it would be unfair to assign it cost
+ }));
+ }
+ const failedMatches = matches.row(patternIdx);
+ failedMatches.sort(sortKeyComparator(([i, r]) => [r.failCost, i]));
+ if (failedMatches.length > 0) {
+ const [index, innerResult] = failedMatches[0];
+ result.recordFailure({
+ matcher: this,
+ message: `Could not match arrayWith pattern ${patternIdx}. This is the closest match`,
+ path: [`${index}`],
+ cost: 0
+ // Informational message
+ });
+ result.compose(`${index}`, innerResult);
+ } else {
+ result.recordFailure({
+ matcher: this,
+ message: `Could not match arrayWith pattern ${patternIdx}. No more elements to try`,
+ path: [`${actual.length}`]
+ });
+ }
+ }
+ return result;
+ }
+ };
+ ObjectMatch = class extends Matcher {
+ constructor(name, pattern, options = {}) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ this.partial = options.partial ?? true;
+ }
+ test(actual) {
+ if (typeof actual !== "object" || Array.isArray(actual)) {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected type object but received ${getType(actual)}`
+ });
+ }
+ const result = new MatchResult(actual);
+ if (!this.partial) {
+ for (const a of Object.keys(actual)) {
+ if (!(a in this.pattern)) {
+ result.recordFailure({
+ matcher: this,
+ path: [a],
+ message: `Unexpected key ${a}`
+ });
+ }
+ }
+ }
+ for (const [patternKey, patternVal] of Object.entries(this.pattern)) {
+ if (!(patternKey in actual) && !(patternVal instanceof AbsentMatch)) {
+ result.recordFailure({
+ matcher: this,
+ path: [patternKey],
+ message: `Missing key '${patternKey}'`
+ });
+ continue;
+ }
+ const matcher = Matcher.isMatcher(patternVal) ? patternVal : new LiteralMatch(this.name, patternVal, { partialObjects: this.partial });
+ const inner = matcher.test(actual[patternKey]);
+ result.compose(patternKey, inner);
+ }
+ return result;
+ }
+ };
+ SerializedJson = class extends Matcher {
+ constructor(name, pattern) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ }
+ test(actual) {
+ if (getType(actual) !== "string") {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected JSON as a string but found ${getType(actual)}`
+ });
+ }
+ let parsed;
+ try {
+ parsed = JSON.parse(actual);
+ } catch (err) {
+ if (err instanceof SyntaxError) {
+ return new MatchResult(actual).recordFailure({
+ matcher: this,
+ path: [],
+ message: `Invalid JSON string: ${actual}`
+ });
+ } else {
+ throw err;
+ }
+ }
+ const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern);
+ const innerResult = matcher.test(parsed);
+ if (innerResult.hasFailed()) {
+ innerResult.recordFailure({
+ matcher: this,
+ path: [],
+ message: "Encoded JSON value does not match"
+ });
+ }
+ return innerResult;
+ }
+ };
+ NotMatch = class extends Matcher {
+ constructor(name, pattern) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ }
+ test(actual) {
+ const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern);
+ const innerResult = matcher.test(actual);
+ const result = new MatchResult(actual);
+ if (innerResult.failCount === 0) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Found unexpected match: ${JSON.stringify(actual, void 0, 2)}`
+ });
+ }
+ return result;
+ }
+ };
+ AnyMatch = class extends Matcher {
+ constructor(name) {
+ super();
+ this.name = name;
+ }
+ test(actual) {
+ const result = new MatchResult(actual);
+ if (actual == null) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: "Expected a value but found none"
+ });
+ }
+ return result;
+ }
+ };
+ StringLikeRegexpMatch = class extends Matcher {
+ constructor(name, pattern) {
+ super();
+ this.name = name;
+ this.pattern = pattern;
+ }
+ test(actual) {
+ const result = new MatchResult(actual);
+ const regex = new RegExp(this.pattern, "gm");
+ if (typeof actual !== "string") {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `Expected a string, but got '${typeof actual}'`
+ });
+ }
+ if (!regex.test(actual)) {
+ result.recordFailure({
+ matcher: this,
+ path: [],
+ message: `String '${actual}' did not match pattern '${this.pattern}'`
+ });
+ }
+ return result;
+ }
+ };
+ }
+});
+
+// ../../aws-cdk-lib/assertions/lib/helpers-internal/index.js
+var require_helpers_internal = __commonJS({
+ "../../aws-cdk-lib/assertions/lib/helpers-internal/index.js"(exports) {
+ "use strict";
+ var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
+ if (k2 === void 0)
+ k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() {
+ return m[k];
+ } };
+ }
+ Object.defineProperty(o, k2, desc);
+ } : function(o, m, k, k2) {
+ if (k2 === void 0)
+ k2 = k;
+ o[k2] = m[k];
+ });
+ var __exportStar = exports && exports.__exportStar || function(m, exports2) {
+ for (var p in m)
+ if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
+ __createBinding(exports2, m, p);
+ };
+ Object.defineProperty(exports, "__esModule", { value: true });
+ __exportStar((init_match(), __toCommonJS(match_exports)), exports);
+ __exportStar((init_matcher(), __toCommonJS(matcher_exports)), exports);
+ }
+});
+
+// lib/assertions/providers/lambda-handler/index.ts
+var lambda_handler_exports = {};
+__export(lambda_handler_exports, {
+ handler: () => handler,
+ isComplete: () => isComplete,
+ onTimeout: () => onTimeout
+});
+module.exports = __toCommonJS(lambda_handler_exports);
+
+// lib/assertions/providers/lambda-handler/assertion.ts
+var import_helpers_internal = __toESM(require_helpers_internal());
+
+// lib/assertions/providers/lambda-handler/base.ts
+var https = __toESM(require("https"));
+var url = __toESM(require("url"));
+var AWS = __toESM(require("aws-sdk"));
+var CustomResourceHandler = class {
+ constructor(event, context) {
+ this.event = event;
+ this.context = context;
+ this.timedOut = false;
+ this.timeout = setTimeout(async () => {
+ await this.respond({
+ status: "FAILED",
+ reason: "Lambda Function Timeout",
+ data: this.context.logStreamName
+ });
+ this.timedOut = true;
+ }, context.getRemainingTimeInMillis() - 1200);
+ this.event = event;
+ this.physicalResourceId = extractPhysicalResourceId(event);
+ }
+ /**
+ * Handles executing the custom resource event. If `stateMachineArn` is present
+ * in the props then trigger the waiter statemachine
+ */
+ async handle() {
+ try {
+ if ("stateMachineArn" in this.event.ResourceProperties) {
+ const req = {
+ stateMachineArn: this.event.ResourceProperties.stateMachineArn,
+ name: this.event.RequestId,
+ input: JSON.stringify(this.event)
+ };
+ await this.startExecution(req);
+ return;
+ } else {
+ const response = await this.processEvent(this.event.ResourceProperties);
+ return response;
+ }
+ } catch (e) {
+ console.log(e);
+ throw e;
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ }
+ /**
+ * Handle async requests from the waiter state machine
+ */
+ async handleIsComplete() {
+ try {
+ const result = await this.processEvent(this.event.ResourceProperties);
+ return result;
+ } catch (e) {
+ console.log(e);
+ return;
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ }
+ /**
+ * Start a step function state machine which will wait for the request
+ * to be successful.
+ */
+ async startExecution(req) {
+ try {
+ const sfn = new AWS.StepFunctions();
+ await sfn.startExecution(req).promise();
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ }
+ respond(response) {
+ if (this.timedOut) {
+ return;
+ }
+ const cfResponse = {
+ Status: response.status,
+ Reason: response.reason,
+ PhysicalResourceId: this.physicalResourceId,
+ StackId: this.event.StackId,
+ RequestId: this.event.RequestId,
+ LogicalResourceId: this.event.LogicalResourceId,
+ NoEcho: false,
+ Data: response.data
+ };
+ const responseBody = JSON.stringify(cfResponse);
+ console.log("Responding to CloudFormation", responseBody);
+ const parsedUrl = url.parse(this.event.ResponseURL);
+ const requestOptions = {
+ hostname: parsedUrl.hostname,
+ path: parsedUrl.path,
+ method: "PUT",
+ headers: {
+ "content-type": "",
+ "content-length": Buffer.byteLength(responseBody, "utf8")
+ }
+ };
+ return new Promise((resolve, reject) => {
+ try {
+ const request2 = https.request(requestOptions, resolve);
+ request2.on("error", reject);
+ request2.write(responseBody);
+ request2.end();
+ } catch (e) {
+ reject(e);
+ } finally {
+ clearTimeout(this.timeout);
+ }
+ });
+ }
+};
+function extractPhysicalResourceId(event) {
+ switch (event.RequestType) {
+ case "Create":
+ return event.LogicalResourceId;
+ case "Update":
+ case "Delete":
+ return event.PhysicalResourceId;
+ }
+}
+
+// lib/assertions/providers/lambda-handler/assertion.ts
+var AssertionHandler = class extends CustomResourceHandler {
+ async processEvent(request2) {
+ let actual = decodeCall(request2.actual);
+ const expected = decodeCall(request2.expected);
+ let result;
+ const matcher = new MatchCreator(expected).getMatcher();
+ console.log(`Testing equality between ${JSON.stringify(request2.actual)} and ${JSON.stringify(request2.expected)}`);
+ const matchResult = matcher.test(actual);
+ matchResult.finished();
+ if (matchResult.hasFailed()) {
+ result = {
+ failed: true,
+ assertion: JSON.stringify({
+ status: "fail",
+ message: matchResult.renderMismatch()
+ })
+ };
+ if (request2.failDeployment) {
+ throw new Error(result.assertion);
+ }
+ } else {
+ result = {
+ assertion: JSON.stringify({
+ status: "success"
+ })
+ };
+ }
+ return result;
+ }
+};
+var MatchCreator = class {
+ constructor(obj) {
+ this.parsedObj = {
+ matcher: obj
+ };
+ }
+ /**
+ * Return a Matcher that can be tested against the actual results.
+ * This will convert the encoded matchers into their corresponding
+ * assertions matcher.
+ *
+ * For example:
+ *
+ * ExpectedResult.objectLike({
+ * Messages: [{
+ * Body: Match.objectLike({
+ * Elements: Match.arrayWith([{ Asdf: 3 }]),
+ * Payload: Match.serializedJson({ key: 'value' }),
+ * }),
+ * }],
+ * });
+ *
+ * Will be encoded as:
+ * {
+ * $ObjectLike: {
+ * Messages: [{
+ * Body: {
+ * $ObjectLike: {
+ * Elements: {
+ * $ArrayWith: [{ Asdf: 3 }],
+ * },
+ * Payload: {
+ * $SerializedJson: { key: 'value' }
+ * }
+ * },
+ * },
+ * }],
+ * },
+ * }
+ *
+ * Which can then be parsed by this function. For each key (recursively)
+ * the parser will check if the value has one of the encoded matchers as a key
+ * and if so, it will set the value as the Matcher. So,
+ *
+ * {
+ * Body: {
+ * $ObjectLike: {
+ * Elements: {
+ * $ArrayWith: [{ Asdf: 3 }],
+ * },
+ * Payload: {
+ * $SerializedJson: { key: 'value' }
+ * }
+ * },
+ * },
+ * }
+ *
+ * Will be converted to
+ * {
+ * Body: Match.objectLike({
+ * Elements: Match.arrayWith([{ Asdf: 3 }]),
+ * Payload: Match.serializedJson({ key: 'value' }),
+ * }),
+ * }
+ */
+ getMatcher() {
+ try {
+ const final = JSON.parse(JSON.stringify(this.parsedObj), function(_k, v) {
+ const nested = Object.keys(v)[0];
+ switch (nested) {
+ case "$ArrayWith":
+ return import_helpers_internal.Match.arrayWith(v[nested]);
+ case "$ObjectLike":
+ return import_helpers_internal.Match.objectLike(v[nested]);
+ case "$StringLike":
+ return import_helpers_internal.Match.stringLikeRegexp(v[nested]);
+ case "$SerializedJson":
+ return import_helpers_internal.Match.serializedJson(v[nested]);
+ default:
+ return v;
+ }
+ });
+ if (import_helpers_internal.Matcher.isMatcher(final.matcher)) {
+ return final.matcher;
+ }
+ return import_helpers_internal.Match.exact(final.matcher);
+ } catch {
+ return import_helpers_internal.Match.exact(this.parsedObj.matcher);
+ }
+ }
+};
+function decodeCall(call) {
+ if (!call) {
+ return void 0;
+ }
+ try {
+ const parsed = JSON.parse(call);
+ return parsed;
+ } catch {
+ return call;
+ }
+}
+
+// lib/assertions/providers/lambda-handler/utils.ts
+function decode(object) {
+ return JSON.parse(JSON.stringify(object), (_k, v) => {
+ switch (v) {
+ case "TRUE:BOOLEAN":
+ return true;
+ case "FALSE:BOOLEAN":
+ return false;
+ default:
+ return v;
+ }
+ });
+}
+
+// lib/assertions/providers/lambda-handler/sdk.ts
+function flatten(object) {
+ return Object.assign(
+ {},
+ ...function _flatten(child, path = []) {
+ return [].concat(...Object.keys(child).map((key) => {
+ let childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key];
+ if (typeof childKey === "string") {
+ childKey = isJsonString(childKey);
+ }
+ return typeof childKey === "object" && childKey !== null ? _flatten(childKey, path.concat([key])) : { [path.concat([key]).join(".")]: childKey };
+ }));
+ }(object)
+ );
+}
+var AwsApiCallHandler = class extends CustomResourceHandler {
+ async processEvent(request2) {
+ const AWS2 = require("aws-sdk");
+ console.log(`AWS SDK VERSION: ${AWS2.VERSION}`);
+ if (!Object.prototype.hasOwnProperty.call(AWS2, request2.service)) {
+ throw Error(`Service ${request2.service} does not exist in AWS SDK version ${AWS2.VERSION}.`);
+ }
+ const service = new AWS2[request2.service]();
+ const response = await service[request2.api](request2.parameters && decode(request2.parameters)).promise();
+ console.log(`SDK response received ${JSON.stringify(response)}`);
+ delete response.ResponseMetadata;
+ const respond = {
+ apiCallResponse: response
+ };
+ const flatData = {
+ ...flatten(respond)
+ };
+ let resp = respond;
+ if (request2.outputPaths) {
+ resp = filterKeys(flatData, request2.outputPaths);
+ } else if (request2.flattenResponse === "true") {
+ resp = flatData;
+ }
+ console.log(`Returning result ${JSON.stringify(resp)}`);
+ return resp;
+ }
+};
+function filterKeys(object, searchStrings) {
+ return Object.entries(object).reduce((filteredObject, [key, value]) => {
+ for (const searchString of searchStrings) {
+ if (key.startsWith(`apiCallResponse.${searchString}`)) {
+ filteredObject[key] = value;
+ }
+ }
+ return filteredObject;
+ }, {});
+}
+function isJsonString(value) {
+ try {
+ return JSON.parse(value);
+ } catch {
+ return value;
+ }
+}
+
+// lib/assertions/providers/lambda-handler/types.ts
+var ASSERT_RESOURCE_TYPE = "Custom::DeployAssert@AssertEquals";
+var SDK_RESOURCE_TYPE_PREFIX = "Custom::DeployAssert@SdkCall";
+
+// lib/assertions/providers/lambda-handler/index.ts
+async function handler(event, context) {
+ console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`);
+ const provider = createResourceHandler(event, context);
+ try {
+ if (event.RequestType === "Delete") {
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK"
+ });
+ return;
+ }
+ const result = await provider.handle();
+ if ("stateMachineArn" in event.ResourceProperties) {
+ console.info('Found "stateMachineArn", waiter statemachine started');
+ return;
+ } else if ("expected" in event.ResourceProperties) {
+ console.info('Found "expected", testing assertions');
+ const actualPath = event.ResourceProperties.actualPath;
+ const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse;
+ const assertion = new AssertionHandler({
+ ...event,
+ ResourceProperties: {
+ ServiceToken: event.ServiceToken,
+ actual,
+ expected: event.ResourceProperties.expected
+ }
+ }, context);
+ try {
+ const assertionResult = await assertion.handle();
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ // return both the result of the API call _and_ the assertion results
+ data: {
+ ...assertionResult,
+ ...result
+ }
+ });
+ return;
+ } catch (e) {
+ await provider.respond({
+ status: "FAILED",
+ reason: e.message ?? "Internal Error"
+ });
+ return;
+ }
+ }
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ data: result
+ });
+ } catch (e) {
+ await provider.respond({
+ status: "FAILED",
+ reason: e.message ?? "Internal Error"
+ });
+ return;
+ }
+ return;
+}
+async function onTimeout(timeoutEvent) {
+ const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage);
+ const provider = createResourceHandler(isCompleteRequest, standardContext);
+ await provider.respond({
+ status: "FAILED",
+ reason: "Operation timed out: " + JSON.stringify(isCompleteRequest)
+ });
+}
+async function isComplete(event, context) {
+ console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`);
+ const provider = createResourceHandler(event, context);
+ try {
+ const result = await provider.handleIsComplete();
+ const actualPath = event.ResourceProperties.actualPath;
+ if (result) {
+ const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse;
+ if ("expected" in event.ResourceProperties) {
+ const assertion = new AssertionHandler({
+ ...event,
+ ResourceProperties: {
+ ServiceToken: event.ServiceToken,
+ actual,
+ expected: event.ResourceProperties.expected
+ }
+ }, context);
+ const assertionResult = await assertion.handleIsComplete();
+ if (!(assertionResult == null ? void 0 : assertionResult.failed)) {
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ data: {
+ ...assertionResult,
+ ...result
+ }
+ });
+ return;
+ } else {
+ console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`);
+ throw new Error(JSON.stringify(event));
+ }
+ }
+ await provider.respond({
+ status: "SUCCESS",
+ reason: "OK",
+ data: result
+ });
+ } else {
+ console.log("No result");
+ throw new Error(JSON.stringify(event));
+ }
+ return;
+ } catch (e) {
+ console.log(e);
+ throw new Error(JSON.stringify(event));
+ }
+}
+function createResourceHandler(event, context) {
+ if (event.ResourceType.startsWith(SDK_RESOURCE_TYPE_PREFIX)) {
+ return new AwsApiCallHandler(event, context);
+ } else if (event.ResourceType.startsWith(ASSERT_RESOURCE_TYPE)) {
+ return new AssertionHandler(event, context);
+ } else {
+ throw new Error(`Unsupported resource type "${event.ResourceType}`);
+ }
+}
+var standardContext = {
+ getRemainingTimeInMillis: () => 9e4
+};
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+ handler,
+ isComplete,
+ onTimeout
+});
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js
new file mode 100644
index 0000000000000..8237c98f2cc96
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce/index.js
@@ -0,0 +1,256 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.handler = exports.forceSdkInstallation = exports.flatten = exports.PHYSICAL_RESOURCE_ID_REFERENCE = void 0;
+/* eslint-disable no-console */
+const child_process_1 = require("child_process");
+const fs = require("fs");
+const path_1 = require("path");
+/**
+ * Serialized form of the physical resource id for use in the operation parameters
+ */
+exports.PHYSICAL_RESOURCE_ID_REFERENCE = 'PHYSICAL:RESOURCEID:';
+/**
+ * Flattens a nested object
+ *
+ * @param object the object to be flattened
+ * @returns a flat object with path as keys
+ */
+function flatten(object) {
+ return Object.assign({}, ...function _flatten(child, path = []) {
+ return [].concat(...Object.keys(child)
+ .map(key => {
+ const childKey = Buffer.isBuffer(child[key]) ? child[key].toString('utf8') : child[key];
+ return typeof childKey === 'object' && childKey !== null
+ ? _flatten(childKey, path.concat([key]))
+ : ({ [path.concat([key]).join('.')]: childKey });
+ }));
+ }(object));
+}
+exports.flatten = flatten;
+/**
+ * Decodes encoded special values (physicalResourceId)
+ */
+function decodeSpecialValues(object, physicalResourceId) {
+ return JSON.parse(JSON.stringify(object), (_k, v) => {
+ switch (v) {
+ case exports.PHYSICAL_RESOURCE_ID_REFERENCE:
+ return physicalResourceId;
+ default:
+ return v;
+ }
+ });
+}
+/**
+ * Filters the keys of an object.
+ */
+function filterKeys(object, pred) {
+ return Object.entries(object)
+ .reduce((acc, [k, v]) => pred(k)
+ ? { ...acc, [k]: v }
+ : acc, {});
+}
+let latestSdkInstalled = false;
+function forceSdkInstallation() {
+ latestSdkInstalled = false;
+}
+exports.forceSdkInstallation = forceSdkInstallation;
+/**
+ * Installs latest AWS SDK v2
+ */
+function installLatestSdk() {
+ console.log('Installing latest AWS SDK v2');
+ // Both HOME and --prefix are needed here because /tmp is the only writable location
+ (0, child_process_1.execSync)('HOME=/tmp npm install aws-sdk@2 --production --no-package-lock --no-save --prefix /tmp');
+ latestSdkInstalled = true;
+}
+// no currently patched services
+const patchedServices = [];
+/**
+ * Patches the AWS SDK by loading service models in the same manner as the actual SDK
+ */
+function patchSdk(awsSdk) {
+ const apiLoader = awsSdk.apiLoader;
+ patchedServices.forEach(({ serviceName, apiVersions }) => {
+ const lowerServiceName = serviceName.toLowerCase();
+ if (!awsSdk.Service.hasService(lowerServiceName)) {
+ apiLoader.services[lowerServiceName] = {};
+ awsSdk[serviceName] = awsSdk.Service.defineService(lowerServiceName, apiVersions);
+ }
+ else {
+ awsSdk.Service.addVersions(awsSdk[serviceName], apiVersions);
+ }
+ apiVersions.forEach(apiVersion => {
+ Object.defineProperty(apiLoader.services[lowerServiceName], apiVersion, {
+ get: function get() {
+ const modelFilePrefix = `aws-sdk-patch/${lowerServiceName}-${apiVersion}`;
+ const model = JSON.parse(fs.readFileSync((0, path_1.join)(__dirname, `${modelFilePrefix}.service.json`), 'utf-8'));
+ model.paginators = JSON.parse(fs.readFileSync((0, path_1.join)(__dirname, `${modelFilePrefix}.paginators.json`), 'utf-8')).pagination;
+ return model;
+ },
+ enumerable: true,
+ configurable: true,
+ });
+ });
+ });
+ return awsSdk;
+}
+/* eslint-disable @typescript-eslint/no-require-imports, import/no-extraneous-dependencies */
+async function handler(event, context) {
+ try {
+ let AWS;
+ if (!latestSdkInstalled && event.ResourceProperties.InstallLatestAwsSdk === 'true') {
+ try {
+ installLatestSdk();
+ AWS = require('/tmp/node_modules/aws-sdk');
+ }
+ catch (e) {
+ console.log(`Failed to install latest AWS SDK v2: ${e}`);
+ AWS = require('aws-sdk'); // Fallback to pre-installed version
+ }
+ }
+ else if (latestSdkInstalled) {
+ AWS = require('/tmp/node_modules/aws-sdk');
+ }
+ else {
+ AWS = require('aws-sdk');
+ }
+ try {
+ AWS = patchSdk(AWS);
+ }
+ catch (e) {
+ console.log(`Failed to patch AWS SDK: ${e}. Proceeding with the installed copy.`);
+ }
+ console.log(JSON.stringify({ ...event, ResponseURL: '...' }));
+ console.log('AWS SDK VERSION: ' + AWS.VERSION);
+ event.ResourceProperties.Create = decodeCall(event.ResourceProperties.Create);
+ event.ResourceProperties.Update = decodeCall(event.ResourceProperties.Update);
+ event.ResourceProperties.Delete = decodeCall(event.ResourceProperties.Delete);
+ // Default physical resource id
+ let physicalResourceId;
+ switch (event.RequestType) {
+ case 'Create':
+ physicalResourceId = event.ResourceProperties.Create?.physicalResourceId?.id ??
+ event.ResourceProperties.Update?.physicalResourceId?.id ??
+ event.ResourceProperties.Delete?.physicalResourceId?.id ??
+ event.LogicalResourceId;
+ break;
+ case 'Update':
+ case 'Delete':
+ physicalResourceId = event.ResourceProperties[event.RequestType]?.physicalResourceId?.id ?? event.PhysicalResourceId;
+ break;
+ }
+ let flatData = {};
+ let data = {};
+ const call = event.ResourceProperties[event.RequestType];
+ if (call) {
+ let credentials;
+ if (call.assumedRoleArn) {
+ const timestamp = (new Date()).getTime();
+ const params = {
+ RoleArn: call.assumedRoleArn,
+ RoleSessionName: `${timestamp}-${physicalResourceId}`.substring(0, 64),
+ };
+ credentials = new AWS.ChainableTemporaryCredentials({
+ params: params,
+ stsConfig: { stsRegionalEndpoints: 'regional' },
+ });
+ }
+ if (!Object.prototype.hasOwnProperty.call(AWS, call.service)) {
+ throw Error(`Service ${call.service} does not exist in AWS SDK version ${AWS.VERSION}.`);
+ }
+ const awsService = new AWS[call.service]({
+ apiVersion: call.apiVersion,
+ credentials: credentials,
+ region: call.region,
+ });
+ try {
+ const response = await awsService[call.action](call.parameters && decodeSpecialValues(call.parameters, physicalResourceId)).promise();
+ flatData = {
+ apiVersion: awsService.config.apiVersion,
+ region: awsService.config.region,
+ ...flatten(response),
+ };
+ let outputPaths;
+ if (call.outputPath) {
+ outputPaths = [call.outputPath];
+ }
+ else if (call.outputPaths) {
+ outputPaths = call.outputPaths;
+ }
+ if (outputPaths) {
+ data = filterKeys(flatData, startsWithOneOf(outputPaths));
+ }
+ else {
+ data = flatData;
+ }
+ }
+ catch (e) {
+ if (!call.ignoreErrorCodesMatching || !new RegExp(call.ignoreErrorCodesMatching).test(e.code)) {
+ throw e;
+ }
+ }
+ if (call.physicalResourceId?.responsePath) {
+ physicalResourceId = flatData[call.physicalResourceId.responsePath];
+ }
+ }
+ await respond('SUCCESS', 'OK', physicalResourceId, data);
+ }
+ catch (e) {
+ console.log(e);
+ await respond('FAILED', e.message || 'Internal Error', context.logStreamName, {});
+ }
+ function respond(responseStatus, reason, physicalResourceId, data) {
+ const responseBody = JSON.stringify({
+ Status: responseStatus,
+ Reason: reason,
+ PhysicalResourceId: physicalResourceId,
+ StackId: event.StackId,
+ RequestId: event.RequestId,
+ LogicalResourceId: event.LogicalResourceId,
+ NoEcho: false,
+ Data: data,
+ });
+ console.log('Responding', responseBody);
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const parsedUrl = require('url').parse(event.ResponseURL);
+ const requestOptions = {
+ hostname: parsedUrl.hostname,
+ path: parsedUrl.path,
+ method: 'PUT',
+ headers: {
+ 'content-type': '',
+ 'content-length': Buffer.byteLength(responseBody, 'utf8'),
+ },
+ };
+ return new Promise((resolve, reject) => {
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const request = require('https').request(requestOptions, resolve);
+ request.on('error', reject);
+ request.write(responseBody);
+ request.end();
+ }
+ catch (e) {
+ reject(e);
+ }
+ });
+ }
+}
+exports.handler = handler;
+function decodeCall(call) {
+ if (!call) {
+ return undefined;
+ }
+ return JSON.parse(call);
+}
+function startsWithOneOf(searchStrings) {
+ return function (string) {
+ for (const searchString of searchStrings) {
+ if (string.startsWith(searchString)) {
+ return true;
+ }
+ }
+ return false;
+ };
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsaURBQXlDO0FBQ3pDLHlCQUF5QjtBQUN6QiwrQkFBNEI7QUFTNUI7O0dBRUc7QUFDVSxRQUFBLDhCQUE4QixHQUFHLHNCQUFzQixDQUFDO0FBRXJFOzs7OztHQUtHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLE1BQWM7SUFDcEMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQixFQUFFLEVBQ0YsR0FBRyxTQUFTLFFBQVEsQ0FBQyxLQUFVLEVBQUUsT0FBaUIsRUFBRTtRQUNsRCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEYsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksUUFBUSxLQUFLLElBQUk7Z0JBQ3RELENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUNWLENBQUM7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QUUsRUFBRTtZQUNyQyxJQUFJO2dCQUNGLGlFQUFpRTtnQkFDakUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2xFLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM1QixPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7YUFDZjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNYO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQztBQXJKRCwwQkFxSkM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxJQUF3QjtJQUMxQyxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQUUsT0FBTyxTQUFTLENBQUM7S0FBRTtJQUNoQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLGFBQXVCO0lBQzlDLE9BQU8sVUFBUyxNQUFjO1FBQzVCLEtBQUssTUFBTSxZQUFZLElBQUksYUFBYSxFQUFFO1lBQ3hDLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFDbkMsT0FBTyxJQUFJLENBQUM7YUFDYjtTQUNGO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbi8vIGltcG9ydCB0aGUgQVdTTGFtYmRhIHBhY2thZ2UgZXhwbGljaXRseSxcbi8vIHdoaWNoIGlzIGdsb2JhbGx5IGF2YWlsYWJsZSBpbiB0aGUgTGFtYmRhIHJ1bnRpbWUsXG4vLyBhcyBvdGhlcndpc2UgbGlua2luZyB0aGlzIHJlcG9zaXRvcnkgd2l0aCBsaW5rLWFsbC5zaFxuLy8gZmFpbHMgaW4gdGhlIENESyBhcHAgZXhlY3V0ZWQgd2l0aCB0cy1ub2RlXG4vKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzLGltcG9ydC9uby11bnJlc29sdmVkICovXG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBBd3NTZGtDYWxsIH0gZnJvbSAnLi4vYXdzLWN1c3RvbS1yZXNvdXJjZSc7XG5cbi8qKlxuICogU2VyaWFsaXplZCBmb3JtIG9mIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBpZCBmb3IgdXNlIGluIHRoZSBvcGVyYXRpb24gcGFyYW1ldGVyc1xuICovXG5leHBvcnQgY29uc3QgUEhZU0lDQUxfUkVTT1VSQ0VfSURfUkVGRVJFTkNFID0gJ1BIWVNJQ0FMOlJFU09VUkNFSUQ6JztcblxuLyoqXG4gKiBGbGF0dGVucyBhIG5lc3RlZCBvYmplY3RcbiAqXG4gKiBAcGFyYW0gb2JqZWN0IHRoZSBvYmplY3QgdG8gYmUgZmxhdHRlbmVkXG4gKiBAcmV0dXJucyBhIGZsYXQgb2JqZWN0IHdpdGggcGF0aCBhcyBrZXlzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuKG9iamVjdDogb2JqZWN0KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKFxuICAgIHt9LFxuICAgIC4uLmZ1bmN0aW9uIF9mbGF0dGVuKGNoaWxkOiBhbnksIHBhdGg6IHN0cmluZ1tdID0gW10pOiBhbnkge1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdCguLi5PYmplY3Qua2V5cyhjaGlsZClcbiAgICAgICAgLm1hcChrZXkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkS2V5ID0gQnVmZmVyLmlzQnVmZmVyKGNoaWxkW2tleV0pID8gY2hpbGRba2V5XS50b1N0cmluZygndXRmOCcpIDogY2hpbGRba2V5XTtcbiAgICAgICAgICByZXR1cm4gdHlwZW9mIGNoaWxkS2V5ID09PSAnb2JqZWN0JyAmJiBjaGlsZEtleSAhPT0gbnVsbFxuICAgICAgICAgICAgPyBfZmxhdHRlbihjaGlsZEtleSwgcGF0aC5jb25jYXQoW2tleV0pKVxuICAgICAgICAgICAgOiAoeyBbcGF0aC5jb25jYXQoW2tleV0pLmpvaW4oJy4nKV06IGNoaWxkS2V5IH0pO1xuICAgICAgICB9KSk7XG4gICAgfShvYmplY3QpLFxuICApO1xufVxuXG4vKipcbiAqIERlY29kZXMgZW5jb2RlZCBzcGVjaWFsIHZhbHVlcyAocGh5c2ljYWxSZXNvdXJjZUlkKVxuICovXG5mdW5jdGlvbiBkZWNvZGVTcGVjaWFsVmFsdWVzKG9iamVjdDogb2JqZWN0LCBwaHlzaWNhbFJlc291cmNlSWQ6IHN0cmluZykge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmplY3QpLCAoX2ssIHYpID0+IHtcbiAgICBzd2l0Y2ggKHYpIHtcbiAgICAgIGNhc2UgUEhZU0lDQUxfUkVTT1VSQ0VfSURfUkVGRVJFTkNFOlxuICAgICAgICByZXR1cm4gcGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHY7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBGaWx0ZXJzIHRoZSBrZXlzIG9mIGFuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZmlsdGVyS2V5cyhvYmplY3Q6IG9iamVjdCwgcHJlZDogKGtleTogc3RyaW5nKSA9PiBib29sZWFuKSB7XG4gIHJldHVybiBPYmplY3QuZW50cmllcyhvYmplY3QpXG4gICAgLnJlZHVjZShcbiAgICAgIChhY2MsIFtrLCB2XSkgPT4gcHJlZChrKVxuICAgICAgICA/IHsgLi4uYWNjLCBba106IHYgfVxuICAgICAgICA6IGFjYyxcbiAgICAgIHt9LFxuICAgICk7XG59XG5cbmxldCBsYXRlc3RTZGtJbnN0YWxsZWQgPSBmYWxzZTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZvcmNlU2RrSW5zdGFsbGF0aW9uKCkge1xuICBsYXRlc3RTZGtJbnN0YWxsZWQgPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBJbnN0YWxscyBsYXRlc3QgQVdTIFNESyB2MlxuICovXG5mdW5jdGlvbiBpbnN0YWxsTGF0ZXN0U2RrKCk6IHZvaWQge1xuICBjb25zb2xlLmxvZygnSW5zdGFsbGluZyBsYXRlc3QgQVdTIFNESyB2MicpO1xuICAvLyBCb3RoIEhPTUUgYW5kIC0tcHJlZml4IGFyZSBuZWVkZWQgaGVyZSBiZWNhdXNlIC90bXAgaXMgdGhlIG9ubHkgd3JpdGFibGUgbG9jYXRpb25cbiAgZXhlY1N5bmMoJ0hPTUU9L3RtcCBucG0gaW5zdGFsbCBhd3Mtc2RrQDIgLS1wcm9kdWN0aW9uIC0tbm8tcGFja2FnZS1sb2NrIC0tbm8tc2F2ZSAtLXByZWZpeCAvdG1wJyk7XG4gIGxhdGVzdFNka0luc3RhbGxlZCA9IHRydWU7XG59XG5cbi8vIG5vIGN1cnJlbnRseSBwYXRjaGVkIHNlcnZpY2VzXG5jb25zdCBwYXRjaGVkU2VydmljZXM6IHsgc2VydmljZU5hbWU6IHN0cmluZzsgYXBpVmVyc2lvbnM6IHN0cmluZ1tdIH1bXSA9IFtdO1xuLyoqXG4gKiBQYXRjaGVzIHRoZSBBV1MgU0RLIGJ5IGxvYWRpbmcgc2VydmljZSBtb2RlbHMgaW4gdGhlIHNhbWUgbWFubmVyIGFzIHRoZSBhY3R1YWwgU0RLXG4gKi9cbmZ1bmN0aW9uIHBhdGNoU2RrKGF3c1NkazogYW55KTogYW55IHtcbiAgY29uc3QgYXBpTG9hZGVyID0gYXdzU2RrLmFwaUxvYWRlcjtcbiAgcGF0Y2hlZFNlcnZpY2VzLmZvckVhY2goKHsgc2VydmljZU5hbWUsIGFwaVZlcnNpb25zIH0pID0+IHtcbiAgICBjb25zdCBsb3dlclNlcnZpY2VOYW1lID0gc2VydmljZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoIWF3c1Nkay5TZXJ2aWNlLmhhc1NlcnZpY2UobG93ZXJTZXJ2aWNlTmFtZSkpIHtcbiAgICAgIGFwaUxvYWRlci5zZXJ2aWNlc1tsb3dlclNlcnZpY2VOYW1lXSA9IHt9O1xuICAgICAgYXdzU2RrW3NlcnZpY2VOYW1lXSA9IGF3c1Nkay5TZXJ2aWNlLmRlZmluZVNlcnZpY2UobG93ZXJTZXJ2aWNlTmFtZSwgYXBpVmVyc2lvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd3NTZGsuU2VydmljZS5hZGRWZXJzaW9ucyhhd3NTZGtbc2VydmljZU5hbWVdLCBhcGlWZXJzaW9ucyk7XG4gICAgfVxuICAgIGFwaVZlcnNpb25zLmZvckVhY2goYXBpVmVyc2lvbiA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXBpTG9hZGVyLnNlcnZpY2VzW2xvd2VyU2VydmljZU5hbWVdLCBhcGlWZXJzaW9uLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgIGNvbnN0IG1vZGVsRmlsZVByZWZpeCA9IGBhd3Mtc2RrLXBhdGNoLyR7bG93ZXJTZXJ2aWNlTmFtZX0tJHthcGlWZXJzaW9ufWA7XG4gICAgICAgICAgY29uc3QgbW9kZWwgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgYCR7bW9kZWxGaWxlUHJlZml4fS5zZXJ2aWNlLmpzb25gKSwgJ3V0Zi04JykpO1xuICAgICAgICAgIG1vZGVsLnBhZ2luYXRvcnMgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgYCR7bW9kZWxGaWxlUHJlZml4fS5wYWdpbmF0b3JzLmpzb25gKSwgJ3V0Zi04JykpLnBhZ2luYXRpb247XG4gICAgICAgICAgcmV0dXJuIG1vZGVsO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBhd3NTZGs7XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMsIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIHRyeSB7XG4gICAgbGV0IEFXUzogYW55O1xuICAgIGlmICghbGF0ZXN0U2RrSW5zdGFsbGVkICYmIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5JbnN0YWxsTGF0ZXN0QXdzU2RrID09PSAndHJ1ZScpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGluc3RhbGxMYXRlc3RTZGsoKTtcbiAgICAgICAgQVdTID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvYXdzLXNkaycpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgRmFpbGVkIHRvIGluc3RhbGwgbGF0ZXN0IEFXUyBTREsgdjI6ICR7ZX1gKTtcbiAgICAgICAgQVdTID0gcmVxdWlyZSgnYXdzLXNkaycpOyAvLyBGYWxsYmFjayB0byBwcmUtaW5zdGFsbGVkIHZlcnNpb25cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxhdGVzdFNka0luc3RhbGxlZCkge1xuICAgICAgQVdTID0gcmVxdWlyZSgnL3RtcC9ub2RlX21vZHVsZXMvYXdzLXNkaycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBBV1MgPSByZXF1aXJlKCdhd3Mtc2RrJyk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBBV1MgPSBwYXRjaFNkayhBV1MpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUubG9nKGBGYWlsZWQgdG8gcGF0Y2ggQVdTIFNESzogJHtlfS4gUHJvY2VlZGluZyB3aXRoIHRoZSBpbnN0YWxsZWQgY29weS5gKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh7IC4uLmV2ZW50LCBSZXNwb25zZVVSTDogJy4uLicgfSkpO1xuICAgIGNvbnNvbGUubG9nKCdBV1MgU0RLIFZFUlNJT046ICcgKyBBV1MuVkVSU0lPTik7XG5cbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ3JlYXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ3JlYXRlKTtcbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuVXBkYXRlKTtcbiAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlID0gZGVjb2RlQ2FsbChldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlKTtcbiAgICAvLyBEZWZhdWx0IHBoeXNpY2FsIHJlc291cmNlIGlkXG4gICAgbGV0IHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nO1xuICAgIHN3aXRjaCAoZXZlbnQuUmVxdWVzdFR5cGUpIHtcbiAgICAgIGNhc2UgJ0NyZWF0ZSc6XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DcmVhdGU/LnBoeXNpY2FsUmVzb3VyY2VJZD8uaWQgPz9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLlVwZGF0ZT8ucGh5c2ljYWxSZXNvdXJjZUlkPy5pZCA/P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1VwZGF0ZSc6XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXNbZXZlbnQuUmVxdWVzdFR5cGVdPy5waHlzaWNhbFJlc291cmNlSWQ/LmlkID8/IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgbGV0IGZsYXREYXRhOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgbGV0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBjYWxsOiBBd3NTZGtDYWxsIHwgdW5kZWZpbmVkID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzW2V2ZW50LlJlcXVlc3RUeXBlXTtcblxuICAgIGlmIChjYWxsKSB7XG5cbiAgICAgIGxldCBjcmVkZW50aWFscztcbiAgICAgIGlmIChjYWxsLmFzc3VtZWRSb2xlQXJuKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIFJvbGVBcm46IGNhbGwuYXNzdW1lZFJvbGVBcm4sXG4gICAgICAgICAgUm9sZVNlc3Npb25OYW1lOiBgJHt0aW1lc3RhbXB9LSR7cGh5c2ljYWxSZXNvdXJjZUlkfWAuc3Vic3RyaW5nKDAsIDY0KSxcbiAgICAgICAgfTtcblxuICAgICAgICBjcmVkZW50aWFscyA9IG5ldyBBV1MuQ2hhaW5hYmxlVGVtcG9yYXJ5Q3JlZGVudGlhbHMoe1xuICAgICAgICAgIHBhcmFtczogcGFyYW1zLFxuICAgICAgICAgIHN0c0NvbmZpZzogeyBzdHNSZWdpb25hbEVuZHBvaW50czogJ3JlZ2lvbmFsJyB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoQVdTLCBjYWxsLnNlcnZpY2UpKSB7XG4gICAgICAgIHRocm93IEVycm9yKGBTZXJ2aWNlICR7Y2FsbC5zZXJ2aWNlfSBkb2VzIG5vdCBleGlzdCBpbiBBV1MgU0RLIHZlcnNpb24gJHtBV1MuVkVSU0lPTn0uYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBhd3NTZXJ2aWNlID0gbmV3IChBV1MgYXMgYW55KVtjYWxsLnNlcnZpY2VdKHtcbiAgICAgICAgYXBpVmVyc2lvbjogY2FsbC5hcGlWZXJzaW9uLFxuICAgICAgICBjcmVkZW50aWFsczogY3JlZGVudGlhbHMsXG4gICAgICAgIHJlZ2lvbjogY2FsbC5yZWdpb24sXG4gICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBhd3NTZXJ2aWNlW2NhbGwuYWN0aW9uXShcbiAgICAgICAgICBjYWxsLnBhcmFtZXRlcnMgJiYgZGVjb2RlU3BlY2lhbFZhbHVlcyhjYWxsLnBhcmFtZXRlcnMsIHBoeXNpY2FsUmVzb3VyY2VJZCkpLnByb21pc2UoKTtcbiAgICAgICAgZmxhdERhdGEgPSB7XG4gICAgICAgICAgYXBpVmVyc2lvbjogYXdzU2VydmljZS5jb25maWcuYXBpVmVyc2lvbiwgLy8gRm9yIHRlc3QgcHVycG9zZXM6IGNoZWNrIGlmIGFwaVZlcnNpb24gd2FzIGNvcnJlY3RseSBwYXNzZWQuXG4gICAgICAgICAgcmVnaW9uOiBhd3NTZXJ2aWNlLmNvbmZpZy5yZWdpb24sIC8vIEZvciB0ZXN0IHB1cnBvc2VzOiBjaGVjayBpZiByZWdpb24gd2FzIGNvcnJlY3RseSBwYXNzZWQuXG4gICAgICAgICAgLi4uZmxhdHRlbihyZXNwb25zZSksXG4gICAgICAgIH07XG5cbiAgICAgICAgbGV0IG91dHB1dFBhdGhzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGNhbGwub3V0cHV0UGF0aCkge1xuICAgICAgICAgIG91dHB1dFBhdGhzID0gW2NhbGwub3V0cHV0UGF0aF07XG4gICAgICAgIH0gZWxzZSBpZiAoY2FsbC5vdXRwdXRQYXRocykge1xuICAgICAgICAgIG91dHB1dFBhdGhzID0gY2FsbC5vdXRwdXRQYXRocztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvdXRwdXRQYXRocykge1xuICAgICAgICAgIGRhdGEgPSBmaWx0ZXJLZXlzKGZsYXREYXRhLCBzdGFydHNXaXRoT25lT2Yob3V0cHV0UGF0aHMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhID0gZmxhdERhdGE7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBpZiAoIWNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nIHx8ICFuZXcgUmVnRXhwKGNhbGwuaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nKS50ZXN0KGUuY29kZSkpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjYWxsLnBoeXNpY2FsUmVzb3VyY2VJZD8ucmVzcG9uc2VQYXRoKSB7XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCA9IGZsYXREYXRhW2NhbGwucGh5c2ljYWxSZXNvdXJjZUlkLnJlc3BvbnNlUGF0aF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgcmVzcG9uZCgnU1VDQ0VTUycsICdPSycsIHBoeXNpY2FsUmVzb3VyY2VJZCwgZGF0YSk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNvbnNvbGUubG9nKGUpO1xuICAgIGF3YWl0IHJlc3BvbmQoJ0ZBSUxFRCcsIGUubWVzc2FnZSB8fCAnSW50ZXJuYWwgRXJyb3InLCBjb250ZXh0LmxvZ1N0cmVhbU5hbWUsIHt9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3BvbmQocmVzcG9uc2VTdGF0dXM6IHN0cmluZywgcmVhc29uOiBzdHJpbmcsIHBoeXNpY2FsUmVzb3VyY2VJZDogc3RyaW5nLCBkYXRhOiBhbnkpIHtcbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBTdGF0dXM6IHJlc3BvbnNlU3RhdHVzLFxuICAgICAgUmVhc29uOiByZWFzb24sXG4gICAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCxcbiAgICAgIE5vRWNobzogZmFsc2UsXG4gICAgICBEYXRhOiBkYXRhLFxuICAgIH0pO1xuXG4gICAgY29uc29sZS5sb2coJ1Jlc3BvbmRpbmcnLCByZXNwb25zZUJvZHkpO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCBwYXJzZWRVcmwgPSByZXF1aXJlKCd1cmwnKS5wYXJzZShldmVudC5SZXNwb25zZVVSTCk7XG4gICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgICAgcGF0aDogcGFyc2VkVXJsLnBhdGgsXG4gICAgICBtZXRob2Q6ICdQVVQnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnY29udGVudC10eXBlJzogJycsXG4gICAgICAgICdjb250ZW50LWxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHJlc3BvbnNlQm9keSwgJ3V0ZjgnKSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnaHR0cHMnKS5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCByZXNvbHZlKTtcbiAgICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWNvZGVDYWxsKGNhbGw6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICBpZiAoIWNhbGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICByZXR1cm4gSlNPTi5wYXJzZShjYWxsKTtcbn1cblxuZnVuY3Rpb24gc3RhcnRzV2l0aE9uZU9mKHNlYXJjaFN0cmluZ3M6IHN0cmluZ1tdKTogKHN0cmluZzogc3RyaW5nKSA9PiBib29sZWFuIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBzZWFyY2hTdHJpbmcgb2Ygc2VhcmNoU3RyaW5ncykge1xuICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKHNlYXJjaFN0cmluZykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbn1cbiJdfQ==
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/__entrypoint__.js
new file mode 100644
index 0000000000000..c83ecebaaadac
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/__entrypoint__.js
@@ -0,0 +1,147 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.withRetries = exports.handler = exports.external = void 0;
+const https = require("https");
+const url = require("url");
+// for unit tests
+exports.external = {
+ sendHttpRequest: defaultSendHttpRequest,
+ log: defaultLog,
+ includeStackTraces: true,
+ userHandlerIndex: './index',
+};
+const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED';
+const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID';
+async function handler(event, context) {
+ const sanitizedEvent = { ...event, ResponseURL: '...' };
+ exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2));
+ // ignore DELETE event when the physical resource ID is the marker that
+ // indicates that this DELETE is a subsequent DELETE to a failed CREATE
+ // operation.
+ if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) {
+ exports.external.log('ignoring DELETE event caused by a failed CREATE event');
+ await submitResponse('SUCCESS', event);
+ return;
+ }
+ try {
+ // invoke the user handler. this is intentionally inside the try-catch to
+ // ensure that if there is an error it's reported as a failure to
+ // cloudformation (otherwise cfn waits).
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const userHandler = require(exports.external.userHandlerIndex).handler;
+ const result = await userHandler(sanitizedEvent, context);
+ // validate user response and create the combined event
+ const responseEvent = renderResponse(event, result);
+ // submit to cfn as success
+ await submitResponse('SUCCESS', responseEvent);
+ }
+ catch (e) {
+ const resp = {
+ ...event,
+ Reason: exports.external.includeStackTraces ? e.stack : e.message,
+ };
+ if (!resp.PhysicalResourceId) {
+ // special case: if CREATE fails, which usually implies, we usually don't
+ // have a physical resource id. in this case, the subsequent DELETE
+ // operation does not have any meaning, and will likely fail as well. to
+ // address this, we use a marker so the provider framework can simply
+ // ignore the subsequent DELETE.
+ if (event.RequestType === 'Create') {
+ exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored');
+ resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER;
+ }
+ else {
+ // otherwise, if PhysicalResourceId is not specified, something is
+ // terribly wrong because all other events should have an ID.
+ exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`);
+ }
+ }
+ // this is an actual error, fail the activity altogether and exist.
+ await submitResponse('FAILED', resp);
+ }
+}
+exports.handler = handler;
+function renderResponse(cfnRequest, handlerResponse = {}) {
+ // if physical ID is not returned, we have some defaults for you based
+ // on the request type.
+ const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId;
+ // if we are in DELETE and physical ID was changed, it's an error.
+ if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) {
+ throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`);
+ }
+ // merge request event and result event (result prevails).
+ return {
+ ...cfnRequest,
+ ...handlerResponse,
+ PhysicalResourceId: physicalResourceId,
+ };
+}
+async function submitResponse(status, event) {
+ const json = {
+ Status: status,
+ Reason: event.Reason ?? status,
+ StackId: event.StackId,
+ RequestId: event.RequestId,
+ PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER,
+ LogicalResourceId: event.LogicalResourceId,
+ NoEcho: event.NoEcho,
+ Data: event.Data,
+ };
+ exports.external.log('submit response to cloudformation', json);
+ const responseBody = JSON.stringify(json);
+ const parsedUrl = url.parse(event.ResponseURL);
+ const req = {
+ hostname: parsedUrl.hostname,
+ path: parsedUrl.path,
+ method: 'PUT',
+ headers: {
+ 'content-type': '',
+ 'content-length': Buffer.byteLength(responseBody, 'utf8'),
+ },
+ };
+ const retryOptions = {
+ attempts: 5,
+ sleep: 1000,
+ };
+ await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody);
+}
+async function defaultSendHttpRequest(options, responseBody) {
+ return new Promise((resolve, reject) => {
+ try {
+ const request = https.request(options, _ => resolve());
+ request.on('error', reject);
+ request.write(responseBody);
+ request.end();
+ }
+ catch (e) {
+ reject(e);
+ }
+ });
+}
+function defaultLog(fmt, ...params) {
+ // eslint-disable-next-line no-console
+ console.log(fmt, ...params);
+}
+function withRetries(options, fn) {
+ return async (...xs) => {
+ let attempts = options.attempts;
+ let ms = options.sleep;
+ while (true) {
+ try {
+ return await fn(...xs);
+ }
+ catch (e) {
+ if (attempts-- <= 0) {
+ throw e;
+ }
+ await sleep(Math.floor(Math.random() * ms));
+ ms *= 2;
+ }
+ }
+ };
+}
+exports.withRetries = withRetries;
+async function sleep(ms) {
+ return new Promise((ok) => setTimeout(ok, ms));
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFN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LE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBSyxFQUFFLEVBQUU7UUFDeEIsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUNoQyxJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQ3ZCLE9BQU8sSUFBSSxFQUFFO1lBQ1gsSUFBSTtnQkFDRixPQUFPLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7YUFDeEI7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixJQUFJLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRTtvQkFDbkIsTUFBTSxDQUFDLENBQUM7aUJBQ1Q7Z0JBQ0QsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDNUMsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUNUO1NBQ0Y7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDO0FBaEJELGtDQWdCQztBQUVELEtBQUssVUFBVSxLQUFLLENBQUMsRUFBVTtJQUM3QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDakQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCAqIGFzIHVybCBmcm9tICd1cmwnO1xuXG4vLyBmb3IgdW5pdCB0ZXN0c1xuZXhwb3J0IGNvbnN0IGV4dGVybmFsID0ge1xuICBzZW5kSHR0cFJlcXVlc3Q6IGRlZmF1bHRTZW5kSHR0cFJlcXVlc3QsXG4gIGxvZzogZGVmYXVsdExvZyxcbiAgaW5jbHVkZVN0YWNrVHJhY2VzOiB0cnVlLFxuICB1c2VySGFuZGxlckluZGV4OiAnLi9pbmRleCcsXG59O1xuXG5jb25zdCBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUiA9ICdBV1NDREs6OkN1c3RvbVJlc291cmNlUHJvdmlkZXJGcmFtZXdvcms6OkNSRUFURV9GQUlMRUQnO1xuY29uc3QgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpNSVNTSU5HX1BIWVNJQ0FMX0lEJztcblxuZXhwb3J0IHR5cGUgUmVzcG9uc2UgPSBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50ICYgSGFuZGxlclJlc3BvbnNlO1xuZXhwb3J0IHR5cGUgSGFuZGxlciA9IChldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpID0+IFByb21pc2U8SGFuZGxlclJlc3BvbnNlIHwgdm9pZD47XG5leHBvcnQgdHlwZSBIYW5kbGVyUmVzcG9uc2UgPSB1bmRlZmluZWQgfCB7XG4gIERhdGE/OiBhbnk7XG4gIFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZztcbiAgUmVhc29uPzogc3RyaW5nO1xuICBOb0VjaG8/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGNvbnN0IHNhbml0aXplZEV2ZW50ID0geyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH07XG4gIGV4dGVybmFsLmxvZyhKU09OLnN0cmluZ2lmeShzYW5pdGl6ZWRFdmVudCwgdW5kZWZpbmVkLCAyKSk7XG5cbiAgLy8gaWdub3JlIERFTEVURSBldmVudCB3aGVuIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBpcyB0aGUgbWFya2VyIHRoYXRcbiAgLy8gaW5kaWNhdGVzIHRoYXQgdGhpcyBERUxFVEUgaXMgYSBzdWJzZXF1ZW50IERFTEVURSB0byBhIGZhaWxlZCBDUkVBVEVcbiAgLy8gb3BlcmF0aW9uLlxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnICYmIGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCA9PT0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIpIHtcbiAgICBleHRlcm5hbC5sb2coJ2lnbm9yaW5nIERFTEVURSBldmVudCBjYXVzZWQgYnkgYSBmYWlsZWQgQ1JFQVRFIGV2ZW50Jyk7XG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCBldmVudCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBpbnZva2UgdGhlIHVzZXIgaGFuZGxlci4gdGhpcyBpcyBpbnRlbnRpb25hbGx5IGluc2lkZSB0aGUgdHJ5LWNhdGNoIHRvXG4gICAgLy8gZW5zdXJlIHRoYXQgaWYgdGhlcmUgaXMgYW4gZXJyb3IgaXQncyByZXBvcnRlZCBhcyBhIGZhaWx1cmUgdG9cbiAgICAvLyBjbG91ZGZvcm1hdGlvbiAob3RoZXJ3aXNlIGNmbiB3YWl0cykuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCB1c2VySGFuZGxlcjogSGFuZGxlciA9IHJlcXVpcmUoZXh0ZXJuYWwudXNlckhhbmRsZXJJbmRleCkuaGFuZGxlcjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB1c2VySGFuZGxlcihzYW5pdGl6ZWRFdmVudCwgY29udGV4dCk7XG5cbiAgICAvLyB2YWxpZGF0ZSB1c2VyIHJlc3BvbnNlIGFuZCBjcmVhdGUgdGhlIGNvbWJpbmVkIGV2ZW50XG4gICAgY29uc3QgcmVzcG9uc2VFdmVudCA9IHJlbmRlclJlc3BvbnNlKGV2ZW50LCByZXN1bHQpO1xuXG4gICAgLy8gc3VibWl0IHRvIGNmbiBhcyBzdWNjZXNzXG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ1NVQ0NFU1MnLCByZXNwb25zZUV2ZW50KTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgY29uc3QgcmVzcDogUmVzcG9uc2UgPSB7XG4gICAgICAuLi5ldmVudCxcbiAgICAgIFJlYXNvbjogZXh0ZXJuYWwuaW5jbHVkZVN0YWNrVHJhY2VzID8gZS5zdGFjayA6IGUubWVzc2FnZSxcbiAgICB9O1xuXG4gICAgaWYgKCFyZXNwLlBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgICAgLy8gc3BlY2lhbCBjYXNlOiBpZiBDUkVBVEUgZmFpbHMsIHdoaWNoIHVzdWFsbHkgaW1wbGllcywgd2UgdXN1YWxseSBkb24ndFxuICAgICAgLy8gaGF2ZSBhIHBoeXNpY2FsIHJlc291cmNlIGlkLiBpbiB0aGlzIGNhc2UsIHRoZSBzdWJzZXF1ZW50IERFTEVURVxuICAgICAgLy8gb3BlcmF0aW9uIGRvZXMgbm90IGhhdmUgYW55IG1lYW5pbmcsIGFuZCB3aWxsIGxpa2VseSBmYWlsIGFzIHdlbGwuIHRvXG4gICAgICAvLyBhZGRyZXNzIHRoaXMsIHdlIHVzZSBhIG1hcmtlciBzbyB0aGUgcHJvdmlkZXIgZnJhbWV3b3JrIGNhbiBzaW1wbHlcbiAgICAgIC8vIGlnbm9yZSB0aGUgc3Vic2VxdWVudCBERUxFVEUuXG4gICAgICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdDcmVhdGUnKSB7XG4gICAgICAgIGV4dGVybmFsLmxvZygnQ1JFQVRFIGZhaWxlZCwgcmVzcG9uZGluZyB3aXRoIGEgbWFya2VyIHBoeXNpY2FsIHJlc291cmNlIGlkIHNvIHRoYXQgdGhlIHN1YnNlcXVlbnQgREVMRVRFIHdpbGwgYmUgaWdub3JlZCcpO1xuICAgICAgICByZXNwLlBoeXNpY2FsUmVzb3VyY2VJZCA9IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb3RoZXJ3aXNlLCBpZiBQaHlzaWNhbFJlc291cmNlSWQgaXMgbm90IHNwZWNpZmllZCwgc29tZXRoaW5nIGlzXG4gICAgICAgIC8vIHRlcnJpYmx5IHdyb25nIGJlY2F1c2UgYWxsIG90aGVyIGV2ZW50cyBzaG91bGQgaGF2ZSBhbiBJRC5cbiAgICAgICAgZXh0ZXJuYWwubG9nKGBFUlJPUjogTWFsZm9ybWVkIGV2ZW50LiBcIlBoeXNpY2FsUmVzb3VyY2VJZFwiIGlzIHJlcXVpcmVkOiAke0pTT04uc3RyaW5naWZ5KGV2ZW50KX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0aGlzIGlzIGFuIGFjdHVhbCBlcnJvciwgZmFpbCB0aGUgYWN0aXZpdHkgYWx0b2dldGhlciBhbmQgZXhpc3QuXG4gICAgYXdhaXQgc3VibWl0UmVzcG9uc2UoJ0ZBSUxFRCcsIHJlc3ApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbmRlclJlc3BvbnNlKFxuICBjZm5SZXF1ZXN0OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50ICYgeyBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmcgfSxcbiAgaGFuZGxlclJlc3BvbnNlOiB2b2lkIHwgSGFuZGxlclJlc3BvbnNlID0geyB9KTogUmVzcG9uc2Uge1xuXG4gIC8vIGlmIHBoeXNpY2FsIElEIGlzIG5vdCByZXR1cm5lZCwgd2UgaGF2ZSBzb21lIGRlZmF1bHRzIGZvciB5b3UgYmFzZWRcbiAgLy8gb24gdGhlIHJlcXVlc3QgdHlwZS5cbiAgY29uc3QgcGh5c2ljYWxSZXNvdXJjZUlkID0gaGFuZGxlclJlc3BvbnNlLlBoeXNpY2FsUmVzb3VyY2VJZCA/PyBjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZCA/PyBjZm5SZXF1ZXN0LlJlcXVlc3RJZDtcblxuICAvLyBpZiB3ZSBhcmUgaW4gREVMRVRFIGFuZCBwaHlzaWNhbCBJRCB3YXMgY2hhbmdlZCwgaXQncyBhbiBlcnJvci5cbiAgaWYgKGNmblJlcXVlc3QuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnICYmIHBoeXNpY2FsUmVzb3VyY2VJZCAhPT0gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYERFTEVURTogY2Fubm90IGNoYW5nZSB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgZnJvbSBcIiR7Y2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWR9XCIgdG8gXCIke2hhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWR9XCIgZHVyaW5nIGRlbGV0aW9uYCk7XG4gIH1cblxuICAvLyBtZXJnZSByZXF1ZXN0IGV2ZW50IGFuZCByZXN1bHQgZXZlbnQgKHJlc3VsdCBwcmV2YWlscykuXG4gIHJldHVybiB7XG4gICAgLi4uY2ZuUmVxdWVzdCxcbiAgICAuLi5oYW5kbGVyUmVzcG9uc2UsXG4gICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBwaHlzaWNhbFJlc291cmNlSWQsXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHN1Ym1pdFJlc3BvbnNlKHN0YXR1czogJ1NVQ0NFU1MnIHwgJ0ZBSUxFRCcsIGV2ZW50OiBSZXNwb25zZSkge1xuICBjb25zdCBqc29uOiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZVJlc3BvbnNlID0ge1xuICAgIFN0YXR1czogc3RhdHVzLFxuICAgIFJlYXNvbjogZXZlbnQuUmVhc29uID8/IHN0YXR1cyxcbiAgICBTdGFja0lkOiBldmVudC5TdGFja0lkLFxuICAgIFJlcXVlc3RJZDogZXZlbnQuUmVxdWVzdElkLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkIHx8IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSLFxuICAgIExvZ2ljYWxSZXNvdXJjZUlkOiBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCxcbiAgICBOb0VjaG86IGV2ZW50Lk5vRWNobyxcbiAgICBEYXRhOiBldmVudC5EYXRhLFxuICB9O1xuXG4gIGV4dGVybmFsLmxvZygnc3VibWl0IHJlc3BvbnNlIHRvIGNsb3VkZm9ybWF0aW9uJywganNvbik7XG5cbiAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoanNvbik7XG4gIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShldmVudC5SZXNwb25zZVVSTCk7XG4gIGNvbnN0IHJlcSA9IHtcbiAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ2NvbnRlbnQtdHlwZSc6ICcnLFxuICAgICAgJ2NvbnRlbnQtbGVuZ3RoJzogQnVmZmVyLmJ5dGVMZW5ndGgocmVzcG9uc2VCb2R5LCAndXRmOCcpLFxuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgcmV0cnlPcHRpb25zID0ge1xuICAgIGF0dGVtcHRzOiA1LFxuICAgIHNsZWVwOiAxMDAwLFxuICB9O1xuICBhd2FpdCB3aXRoUmV0cmllcyhyZXRyeU9wdGlvbnMsIGV4dGVybmFsLnNlbmRIdHRwUmVxdWVzdCkocmVxLCByZXNwb25zZUJvZHkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0KG9wdGlvbnM6IGh0dHBzLlJlcXVlc3RPcHRpb25zLCByZXNwb25zZUJvZHk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gaHR0cHMucmVxdWVzdChvcHRpb25zLCBfID0+IHJlc29sdmUoKSk7XG4gICAgICByZXF1ZXN0Lm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgICByZXF1ZXN0LndyaXRlKHJlc3BvbnNlQm9keSk7XG4gICAgICByZXF1ZXN0LmVuZCgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlamVjdChlKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0TG9nKGZtdDogc3RyaW5nLCAuLi5wYXJhbXM6IGFueVtdKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUubG9nKGZtdCwgLi4ucGFyYW1zKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXRyeU9wdGlvbnMge1xuICAvKiogSG93IG1hbnkgcmV0cmllcyAod2lsbCBhdCBsZWFzdCB0cnkgb25jZSkgKi9cbiAgcmVhZG9ubHkgYXR0ZW1wdHM6IG51bWJlcjtcbiAgLyoqIFNsZWVwIGJhc2UsIGluIG1zICovXG4gIHJlYWRvbmx5IHNsZWVwOiBudW1iZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUmV0cmllczxBIGV4dGVuZHMgQXJyYXk8YW55PiwgQj4ob3B0aW9uczogUmV0cnlPcHRpb25zLCBmbjogKC4uLnhzOiBBKSA9PiBQcm9taXNlPEI+KTogKC4uLnhzOiBBKSA9PiBQcm9taXNlPEI+IHtcbiAgcmV0dXJuIGFzeW5jICguLi54czogQSkgPT4ge1xuICAgIGxldCBhdHRlbXB0cyA9IG9wdGlvbnMuYXR0ZW1wdHM7XG4gICAgbGV0IG1zID0gb3B0aW9ucy5zbGVlcDtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZuKC4uLnhzKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGF0dGVtcHRzLS0gPD0gMCkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgc2xlZXAoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogbXMpKTtcbiAgICAgICAgbXMgKj0gMjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNsZWVwKG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChvaykgPT4gc2V0VGltZW91dChvaywgbXMpKTtcbn1cbiJdfQ==
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/index.js
new file mode 100644
index 0000000000000..cf597f535efd3
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd/index.js
@@ -0,0 +1,81 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.handler = void 0;
+// eslint-disable-next-line import/no-extraneous-dependencies
+const aws_sdk_1 = require("aws-sdk");
+const ec2 = new aws_sdk_1.EC2();
+/**
+ * The default security group ingress rule. This can be used to both revoke and authorize the rules
+ */
+function ingressRuleParams(groupId, account) {
+ return {
+ GroupId: groupId,
+ IpPermissions: [{
+ UserIdGroupPairs: [{
+ GroupId: groupId,
+ UserId: account,
+ }],
+ IpProtocol: '-1',
+ }],
+ };
+}
+/**
+ * The default security group egress rule. This can be used to both revoke and authorize the rules
+ */
+function egressRuleParams(groupId) {
+ return {
+ GroupId: groupId,
+ IpPermissions: [{
+ IpRanges: [{
+ CidrIp: '0.0.0.0/0',
+ }],
+ IpProtocol: '-1',
+ }],
+ };
+}
+/**
+ * Process a custom resource request to restrict the default security group
+ * ingress & egress rules.
+ *
+ * When someone turns off the property then this custom resource will be deleted in which
+ * case we should add back the rules that were removed.
+ */
+async function handler(event) {
+ const securityGroupId = event.ResourceProperties.DefaultSecurityGroupId;
+ const account = event.ResourceProperties.Account;
+ switch (event.RequestType) {
+ case 'Create':
+ return revokeRules(securityGroupId, account);
+ case 'Update':
+ return onUpdate(event);
+ case 'Delete':
+ return authorizeRules(securityGroupId, account);
+ }
+}
+exports.handler = handler;
+async function onUpdate(event) {
+ const oldSg = event.OldResourceProperties.DefaultSecurityGroupId;
+ const newSg = event.ResourceProperties.DefaultSecurityGroupId;
+ if (oldSg !== newSg) {
+ await authorizeRules(oldSg, event.ResourceProperties.Account);
+ await revokeRules(newSg, event.ResourceProperties.Account);
+ }
+ return;
+}
+/**
+ * Revoke both ingress and egress rules
+ */
+async function revokeRules(groupId, account) {
+ await ec2.revokeSecurityGroupEgress(egressRuleParams(groupId)).promise();
+ await ec2.revokeSecurityGroupIngress(ingressRuleParams(groupId, account)).promise();
+ return;
+}
+/**
+ * Authorize both ingress and egress rules
+ */
+async function authorizeRules(groupId, account) {
+ await ec2.authorizeSecurityGroupIngress(ingressRuleParams(groupId, account)).promise();
+ await ec2.authorizeSecurityGroupEgress(egressRuleParams(groupId)).promise();
+ return;
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2REFBNkQ7QUFDN0QscUNBQThCO0FBRTlCLE1BQU0sR0FBRyxHQUFHLElBQUksYUFBRyxFQUFFLENBQUM7QUFFdEI7O0dBRUc7QUFDSCxTQUFTLGlCQUFpQixDQUFDLE9BQWUsRUFBRSxPQUFlO0lBQ3pELE9BQU87UUFDTCxPQUFPLEVBQUUsT0FBTztRQUNoQixhQUFhLEVBQUUsQ0FBQztnQkFDZCxnQkFBZ0IsRUFBRSxDQUFDO3dCQUNqQixPQUFPLEVBQUUsT0FBTzt3QkFDaEIsTUFBTSxFQUFFLE9BQU87cUJBQ2hCLENBQUM7Z0JBQ0YsVUFBVSxFQUFFLElBQUk7YUFDakIsQ0FBQztLQUNILENBQUM7QUFDSixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGdCQUFnQixDQUFDLE9BQWU7SUFDdkMsT0FBTztRQUNMLE9BQU8sRUFBRSxPQUFPO1FBQ2hCLGFBQWEsRUFBRSxDQUFDO2dCQUNkLFFBQVEsRUFBRSxDQUFDO3dCQUNULE1BQU0sRUFBRSxXQUFXO3FCQUNwQixDQUFDO2dCQUNGLFVBQVUsRUFBRSxJQUFJO2FBQ2pCLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNJLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBa0Q7SUFDOUUsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixDQUFDO0lBQ3hFLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUM7SUFDakQsUUFBUSxLQUFLLENBQUMsV0FBVyxFQUFFO1FBQ3pCLEtBQUssUUFBUTtZQUNYLE9BQU8sV0FBVyxDQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMvQyxLQUFLLFFBQVE7WUFDWCxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixLQUFLLFFBQVE7WUFDWCxPQUFPLGNBQWMsQ0FBQyxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDbkQ7QUFDSCxDQUFDO0FBWEQsMEJBV0M7QUFDRCxLQUFLLFVBQVUsUUFBUSxDQUFDLEtBQXdEO0lBQzlFLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxzQkFBc0IsQ0FBQztJQUNqRSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUMsc0JBQXNCLENBQUM7SUFDOUQsSUFBSSxLQUFLLEtBQUssS0FBSyxFQUFFO1FBQ25CLE1BQU0sY0FBYyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUQsTUFBTSxXQUFXLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztLQUM1RDtJQUNELE9BQU87QUFDVCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsV0FBVyxDQUFDLE9BQWUsRUFBRSxPQUFlO0lBQ3pELE1BQU0sR0FBRyxDQUFDLHlCQUF5QixDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDekUsTUFBTSxHQUFHLENBQUMsMEJBQTBCLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDcEYsT0FBTztBQUNULENBQUM7QUFFRDs7R0FFRztBQUNILEtBQUssVUFBVSxjQUFjLENBQUMsT0FBZSxFQUFFLE9BQWU7SUFDNUQsTUFBTSxHQUFHLENBQUMsNkJBQTZCLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDdkYsTUFBTSxHQUFHLENBQUMsNEJBQTRCLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1RSxPQUFPO0FBQ1QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcbmltcG9ydCB7IEVDMiB9IGZyb20gJ2F3cy1zZGsnO1xuXG5jb25zdCBlYzIgPSBuZXcgRUMyKCk7XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgc2VjdXJpdHkgZ3JvdXAgaW5ncmVzcyBydWxlLiBUaGlzIGNhbiBiZSB1c2VkIHRvIGJvdGggcmV2b2tlIGFuZCBhdXRob3JpemUgdGhlIHJ1bGVzXG4gKi9cbmZ1bmN0aW9uIGluZ3Jlc3NSdWxlUGFyYW1zKGdyb3VwSWQ6IHN0cmluZywgYWNjb3VudDogc3RyaW5nKTogRUMyLlJldm9rZVNlY3VyaXR5R3JvdXBJbmdyZXNzUmVxdWVzdCB8IEVDMi5BdXRob3JpemVTZWN1cml0eUdyb3VwSW5ncmVzc1JlcXVlc3Qge1xuICByZXR1cm4ge1xuICAgIEdyb3VwSWQ6IGdyb3VwSWQsXG4gICAgSXBQZXJtaXNzaW9uczogW3tcbiAgICAgIFVzZXJJZEdyb3VwUGFpcnM6IFt7XG4gICAgICAgIEdyb3VwSWQ6IGdyb3VwSWQsXG4gICAgICAgIFVzZXJJZDogYWNjb3VudCxcbiAgICAgIH1dLFxuICAgICAgSXBQcm90b2NvbDogJy0xJyxcbiAgICB9XSxcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBzZWN1cml0eSBncm91cCBlZ3Jlc3MgcnVsZS4gVGhpcyBjYW4gYmUgdXNlZCB0byBib3RoIHJldm9rZSBhbmQgYXV0aG9yaXplIHRoZSBydWxlc1xuICovXG5mdW5jdGlvbiBlZ3Jlc3NSdWxlUGFyYW1zKGdyb3VwSWQ6IHN0cmluZyk6IEVDMi5SZXZva2VTZWN1cml0eUdyb3VwRWdyZXNzUmVxdWVzdCB8IEVDMi5BdXRob3JpemVTZWN1cml0eUdyb3VwRWdyZXNzUmVxdWVzdCB7XG4gIHJldHVybiB7XG4gICAgR3JvdXBJZDogZ3JvdXBJZCxcbiAgICBJcFBlcm1pc3Npb25zOiBbe1xuICAgICAgSXBSYW5nZXM6IFt7XG4gICAgICAgIENpZHJJcDogJzAuMC4wLjAvMCcsXG4gICAgICB9XSxcbiAgICAgIElwUHJvdG9jb2w6ICctMScsXG4gICAgfV0sXG4gIH07XG59XG5cbi8qKlxuICogUHJvY2VzcyBhIGN1c3RvbSByZXNvdXJjZSByZXF1ZXN0IHRvIHJlc3RyaWN0IHRoZSBkZWZhdWx0IHNlY3VyaXR5IGdyb3VwXG4gKiBpbmdyZXNzICYgZWdyZXNzIHJ1bGVzLlxuICpcbiAqIFdoZW4gc29tZW9uZSB0dXJucyBvZmYgdGhlIHByb3BlcnR5IHRoZW4gdGhpcyBjdXN0b20gcmVzb3VyY2Ugd2lsbCBiZSBkZWxldGVkIGluIHdoaWNoXG4gKiBjYXNlIHdlIHNob3VsZCBhZGQgYmFjayB0aGUgcnVsZXMgdGhhdCB3ZXJlIHJlbW92ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHNlY3VyaXR5R3JvdXBJZCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWZhdWx0U2VjdXJpdHlHcm91cElkO1xuICBjb25zdCBhY2NvdW50ID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkFjY291bnQ7XG4gIHN3aXRjaCAoZXZlbnQuUmVxdWVzdFR5cGUpIHtcbiAgICBjYXNlICdDcmVhdGUnOlxuICAgICAgcmV0dXJuIHJldm9rZVJ1bGVzKHNlY3VyaXR5R3JvdXBJZCwgYWNjb3VudCk7XG4gICAgY2FzZSAnVXBkYXRlJzpcbiAgICAgIHJldHVybiBvblVwZGF0ZShldmVudCk7XG4gICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgIHJldHVybiBhdXRob3JpemVSdWxlcyhzZWN1cml0eUdyb3VwSWQsIGFjY291bnQpO1xuICB9XG59XG5hc3luYyBmdW5jdGlvbiBvblVwZGF0ZShldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VVcGRhdGVFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBvbGRTZyA9IGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcy5EZWZhdWx0U2VjdXJpdHlHcm91cElkO1xuICBjb25zdCBuZXdTZyA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5EZWZhdWx0U2VjdXJpdHlHcm91cElkO1xuICBpZiAob2xkU2cgIT09IG5ld1NnKSB7XG4gICAgYXdhaXQgYXV0aG9yaXplUnVsZXMob2xkU2csIGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5BY2NvdW50KTtcbiAgICBhd2FpdCByZXZva2VSdWxlcyhuZXdTZywgZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkFjY291bnQpO1xuICB9XG4gIHJldHVybjtcbn1cblxuLyoqXG4gKiBSZXZva2UgYm90aCBpbmdyZXNzIGFuZCBlZ3Jlc3MgcnVsZXNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmV2b2tlUnVsZXMoZ3JvdXBJZDogc3RyaW5nLCBhY2NvdW50OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgZWMyLnJldm9rZVNlY3VyaXR5R3JvdXBFZ3Jlc3MoZWdyZXNzUnVsZVBhcmFtcyhncm91cElkKSkucHJvbWlzZSgpO1xuICBhd2FpdCBlYzIucmV2b2tlU2VjdXJpdHlHcm91cEluZ3Jlc3MoaW5ncmVzc1J1bGVQYXJhbXMoZ3JvdXBJZCwgYWNjb3VudCkpLnByb21pc2UoKTtcbiAgcmV0dXJuO1xufVxuXG4vKipcbiAqIEF1dGhvcml6ZSBib3RoIGluZ3Jlc3MgYW5kIGVncmVzcyBydWxlc1xuICovXG5hc3luYyBmdW5jdGlvbiBhdXRob3JpemVSdWxlcyhncm91cElkOiBzdHJpbmcsIGFjY291bnQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBlYzIuYXV0aG9yaXplU2VjdXJpdHlHcm91cEluZ3Jlc3MoaW5ncmVzc1J1bGVQYXJhbXMoZ3JvdXBJZCwgYWNjb3VudCkpLnByb21pc2UoKTtcbiAgYXdhaXQgZWMyLmF1dGhvcml6ZVNlY3VyaXR5R3JvdXBFZ3Jlc3MoZWdyZXNzUnVsZVBhcmFtcyhncm91cElkKSkucHJvbWlzZSgpO1xuICByZXR1cm47XG59XG4iXX0=
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/cdk.out
new file mode 100644
index 0000000000000..7925065efbcc4
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/cdk.out
@@ -0,0 +1 @@
+{"version":"31.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/integ.json
new file mode 100644
index 0000000000000..e90960d38b74b
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/integ.json
@@ -0,0 +1,12 @@
+{
+ "version": "31.0.0",
+ "testCases": {
+ "IntegTestAlbOidc/DefaultTest": {
+ "stacks": [
+ "IntegAlbOidc"
+ ],
+ "assertionStack": "IntegTestAlbOidc/DefaultTest/DeployAssert",
+ "assertionStackName": "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/manifest.json
new file mode 100644
index 0000000000000..53ed2223c83b5
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/manifest.json
@@ -0,0 +1,412 @@
+{
+ "version": "31.0.0",
+ "artifacts": {
+ "IntegAlbOidc.assets": {
+ "type": "cdk:asset-manifest",
+ "properties": {
+ "file": "IntegAlbOidc.assets.json",
+ "requiresBootstrapStackVersion": 6,
+ "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+ }
+ },
+ "IntegAlbOidc": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "IntegAlbOidc.template.json",
+ "validateOnSynth": false,
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
+ "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
+ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/3533112c00a18f9eedd48cded520f3b4577ba46223123b31d79cf6b23b508640.json",
+ "requiresBootstrapStackVersion": 6,
+ "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
+ "additionalDependencies": [
+ "IntegAlbOidc.assets"
+ ],
+ "lookupRole": {
+ "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}",
+ "requiresBootstrapStackVersion": 8,
+ "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+ }
+ },
+ "dependencies": [
+ "IntegAlbOidc.assets"
+ ],
+ "metadata": {
+ "/IntegAlbOidc/Vpc/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Vpc8378EB38"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet1/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet1Subnet5C2D37C4"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet1/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet1RouteTable6C95E38E"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet1/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet1RouteTableAssociation97140677"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet1/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet1DefaultRoute3DA9E72A"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet1/EIP": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet1EIPD7E02669"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet1/NATGateway": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet1NATGateway4D7517AA"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet2/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet2Subnet691E08A3"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet2/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet2RouteTable94F7E489"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet2/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet2RouteTableAssociationDD5762D8"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet2/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet2DefaultRoute97F91067"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet2/EIP": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet2EIP3C605A87"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PublicSubnet2/NATGateway": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPublicSubnet2NATGateway9182C01D"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet1/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet1Subnet536B997A"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet1/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet1RouteTableB2C5B500"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet1/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet1RouteTableAssociation70C59FA6"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet1/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet1DefaultRouteBE02A9ED"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet2/Subnet": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet2Subnet3788AAA1"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet2/RouteTable": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet2RouteTableA678073B"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet2/RouteTableAssociation": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet2RouteTableAssociationA89CAD56"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/PrivateSubnet2/DefaultRoute": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcPrivateSubnet2DefaultRoute060D2087"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/IGW": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcIGWD7BA715C"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/VPCGW": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcVPCGWBF912B6E"
+ }
+ ],
+ "/IntegAlbOidc/Vpc/RestrictDefaultSecurityGroupCustomResource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "VpcRestrictDefaultSecurityGroupCustomResourceC73DA2BE"
+ }
+ ],
+ "/IntegAlbOidc/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0"
+ }
+ ],
+ "/IntegAlbOidc/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E"
+ }
+ ],
+ "/IntegAlbOidc/Certificate/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Certificate4E7ABB08"
+ }
+ ],
+ "/IntegAlbOidc/UserPool/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserPool6BA7E5F2"
+ }
+ ],
+ "/IntegAlbOidc/UserPool/Domain/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserPoolDomainD0EA232A"
+ }
+ ],
+ "/IntegAlbOidc/UserPool/UserPoolClient/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserPoolUserPoolClient40176907"
+ }
+ ],
+ "/IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient/Resource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserPoolUserPoolClientDescribeCognitoUserPoolClientA6EA22D2"
+ }
+ ],
+ "/IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient/CustomResourcePolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserPoolUserPoolClientDescribeCognitoUserPoolClientCustomResourcePolicyFFF2174F"
+ }
+ ],
+ "/IntegAlbOidc/LoadBalancer/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "LoadBalancerBE9EEC3A"
+ }
+ ],
+ "/IntegAlbOidc/LoadBalancer/SecurityGroup/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "LoadBalancerSecurityGroupA28D6DD7"
+ }
+ ],
+ "/IntegAlbOidc/LoadBalancer/Listener/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "LoadBalancerListenerE1A099B9"
+ }
+ ],
+ "/IntegAlbOidc/DefaultCrNodeVersionMap": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "DefaultCrNodeVersionMap"
+ }
+ ],
+ "/IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ],
+ "/IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AWS679f53fac002430cb0da5b7982bd22872D164C4C"
+ }
+ ],
+ "/IntegAlbOidc/ARecord/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ARecordE7B57761"
+ }
+ ],
+ "/IntegAlbOidc/User/Resource/Resource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserFDDCDD17"
+ }
+ ],
+ "/IntegAlbOidc/User/Resource/CustomResourcePolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserCustomResourcePolicyC2EB5139"
+ }
+ ],
+ "/IntegAlbOidc/User/SetUserPassword/Resource/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserSetUserPasswordAD2F2A64"
+ }
+ ],
+ "/IntegAlbOidc/User/SetUserPassword/CustomResourcePolicy/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "UserSetUserPasswordCustomResourcePolicy7B250C76"
+ }
+ ],
+ "/IntegAlbOidc/Signin/ServiceRole/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "SigninServiceRole24B8BB32"
+ }
+ ],
+ "/IntegAlbOidc/Signin/Resource": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "Signin352C80E6"
+ }
+ ],
+ "/IntegAlbOidc/Exports/Output{\"Ref\":\"Signin352C80E6\"}": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ExportsOutputRefSignin352C80E64BA58F71"
+ }
+ ],
+ "/IntegAlbOidc/BootstrapVersion": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BootstrapVersion"
+ }
+ ],
+ "/IntegAlbOidc/CheckBootstrapVersion": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CheckBootstrapVersion"
+ }
+ ]
+ },
+ "displayName": "IntegAlbOidc"
+ },
+ "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets": {
+ "type": "cdk:asset-manifest",
+ "properties": {
+ "file": "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets.json",
+ "requiresBootstrapStackVersion": 6,
+ "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+ }
+ },
+ "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6": {
+ "type": "aws:cloudformation:stack",
+ "environment": "aws://unknown-account/unknown-region",
+ "properties": {
+ "templateFile": "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.template.json",
+ "validateOnSynth": false,
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
+ "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
+ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/8e06e2daf38e95962b941bf8be88c2adb10e55aafddcbd59930a4ef29bc8c79e.json",
+ "requiresBootstrapStackVersion": 6,
+ "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
+ "additionalDependencies": [
+ "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets"
+ ],
+ "lookupRole": {
+ "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}",
+ "requiresBootstrapStackVersion": 8,
+ "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+ }
+ },
+ "dependencies": [
+ "IntegAlbOidc",
+ "IntegTestAlbOidcDefaultTestDeployAssert2476ECB6.assets"
+ ],
+ "metadata": {
+ "/IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Default/Default": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd"
+ }
+ ],
+ "/IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Invoke": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bdInvoke5A72F915"
+ }
+ ],
+ "/IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/AssertionResults": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "AssertionResultsLambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd"
+ }
+ ],
+ "/IntegTestAlbOidc/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73"
+ }
+ ],
+ "/IntegTestAlbOidc/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F"
+ }
+ ],
+ "/IntegTestAlbOidc/DefaultTest/DeployAssert/BootstrapVersion": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "BootstrapVersion"
+ }
+ ],
+ "/IntegTestAlbOidc/DefaultTest/DeployAssert/CheckBootstrapVersion": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "CheckBootstrapVersion"
+ }
+ ]
+ },
+ "displayName": "IntegTestAlbOidc/DefaultTest/DeployAssert"
+ },
+ "Tree": {
+ "type": "cdk:tree",
+ "properties": {
+ "file": "tree.json"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/tree.json
new file mode 100644
index 0000000000000..d723a06ec5fad
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.js.snapshot/tree.json
@@ -0,0 +1,1860 @@
+{
+ "version": "tree-0.1",
+ "tree": {
+ "id": "App",
+ "path": "",
+ "children": {
+ "IntegAlbOidc": {
+ "id": "IntegAlbOidc",
+ "path": "IntegAlbOidc",
+ "children": {
+ "Vpc": {
+ "id": "Vpc",
+ "path": "IntegAlbOidc/Vpc",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/Vpc/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::VPC",
+ "aws:cdk:cloudformation:props": {
+ "cidrBlock": "10.0.0.0/16",
+ "enableDnsHostnames": true,
+ "enableDnsSupport": true,
+ "instanceTenancy": "default",
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnVPC",
+ "version": "0.0.0"
+ }
+ },
+ "PublicSubnet1": {
+ "id": "PublicSubnet1",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.0.0/18",
+ "mapPublicIpOnLaunch": true,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Public"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Public"
+ },
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1/Acl",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+ },
+ "subnetId": {
+ "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "gatewayId": {
+ "Ref": "VpcIGWD7BA715C"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ },
+ "EIP": {
+ "id": "EIP",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1/EIP",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+ "aws:cdk:cloudformation:props": {
+ "domain": "vpc",
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnEIP",
+ "version": "0.0.0"
+ }
+ },
+ "NATGateway": {
+ "id": "NATGateway",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet1/NATGateway",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+ "aws:cdk:cloudformation:props": {
+ "subnetId": {
+ "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+ },
+ "allocationId": {
+ "Fn::GetAtt": [
+ "VpcPublicSubnet1EIPD7E02669",
+ "AllocationId"
+ ]
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "PublicSubnet2": {
+ "id": "PublicSubnet2",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.64.0/18",
+ "mapPublicIpOnLaunch": true,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Public"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Public"
+ },
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2/Acl",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+ },
+ "subnetId": {
+ "Ref": "VpcPublicSubnet2Subnet691E08A3"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "gatewayId": {
+ "Ref": "VpcIGWD7BA715C"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ },
+ "EIP": {
+ "id": "EIP",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2/EIP",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+ "aws:cdk:cloudformation:props": {
+ "domain": "vpc",
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnEIP",
+ "version": "0.0.0"
+ }
+ },
+ "NATGateway": {
+ "id": "NATGateway",
+ "path": "IntegAlbOidc/Vpc/PublicSubnet2/NATGateway",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+ "aws:cdk:cloudformation:props": {
+ "subnetId": {
+ "Ref": "VpcPublicSubnet2Subnet691E08A3"
+ },
+ "allocationId": {
+ "Fn::GetAtt": [
+ "VpcPublicSubnet2EIP3C605A87",
+ "AllocationId"
+ ]
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PublicSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "PrivateSubnet1": {
+ "id": "PrivateSubnet1",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet1",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet1/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 0,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.128.0/18",
+ "mapPublicIpOnLaunch": false,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Private"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Private"
+ },
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet1/Acl",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet1/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PrivateSubnet1"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet1/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+ },
+ "subnetId": {
+ "Ref": "VpcPrivateSubnet1Subnet536B997A"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet1/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "natGatewayId": {
+ "Ref": "VpcPublicSubnet1NATGateway4D7517AA"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "PrivateSubnet2": {
+ "id": "PrivateSubnet2",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet2",
+ "children": {
+ "Subnet": {
+ "id": "Subnet",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet2/Subnet",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Subnet",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "availabilityZone": {
+ "Fn::Select": [
+ 1,
+ {
+ "Fn::GetAZs": ""
+ }
+ ]
+ },
+ "cidrBlock": "10.0.192.0/18",
+ "mapPublicIpOnLaunch": false,
+ "tags": [
+ {
+ "key": "aws-cdk:subnet-name",
+ "value": "Private"
+ },
+ {
+ "key": "aws-cdk:subnet-type",
+ "value": "Private"
+ },
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "Acl": {
+ "id": "Acl",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet2/Acl",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTable": {
+ "id": "RouteTable",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet2/RouteTable",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc/PrivateSubnet2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+ "version": "0.0.0"
+ }
+ },
+ "RouteTableAssociation": {
+ "id": "RouteTableAssociation",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet2/RouteTableAssociation",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+ },
+ "subnetId": {
+ "Ref": "VpcPrivateSubnet2Subnet3788AAA1"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultRoute": {
+ "id": "DefaultRoute",
+ "path": "IntegAlbOidc/Vpc/PrivateSubnet2/DefaultRoute",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+ "aws:cdk:cloudformation:props": {
+ "routeTableId": {
+ "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+ },
+ "destinationCidrBlock": "0.0.0.0/0",
+ "natGatewayId": {
+ "Ref": "VpcPublicSubnet2NATGateway9182C01D"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet",
+ "version": "0.0.0"
+ }
+ },
+ "IGW": {
+ "id": "IGW",
+ "path": "IntegAlbOidc/Vpc/IGW",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway",
+ "aws:cdk:cloudformation:props": {
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Vpc"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway",
+ "version": "0.0.0"
+ }
+ },
+ "VPCGW": {
+ "id": "VPCGW",
+ "path": "IntegAlbOidc/Vpc/VPCGW",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment",
+ "aws:cdk:cloudformation:props": {
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ },
+ "internetGatewayId": {
+ "Ref": "VpcIGWD7BA715C"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment",
+ "version": "0.0.0"
+ }
+ },
+ "RestrictDefaultSecurityGroupCustomResource": {
+ "id": "RestrictDefaultSecurityGroupCustomResource",
+ "path": "IntegAlbOidc/Vpc/RestrictDefaultSecurityGroupCustomResource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "IntegAlbOidc/Vpc/RestrictDefaultSecurityGroupCustomResource/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.Vpc",
+ "version": "0.0.0"
+ }
+ },
+ "Custom::VpcRestrictDefaultSGCustomResourceProvider": {
+ "id": "Custom::VpcRestrictDefaultSGCustomResourceProvider",
+ "path": "IntegAlbOidc/Custom::VpcRestrictDefaultSGCustomResourceProvider",
+ "children": {
+ "Staging": {
+ "id": "Staging",
+ "path": "IntegAlbOidc/Custom::VpcRestrictDefaultSGCustomResourceProvider/Staging",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "Role": {
+ "id": "Role",
+ "path": "IntegAlbOidc/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ },
+ "Handler": {
+ "id": "Handler",
+ "path": "IntegAlbOidc/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResourceProvider",
+ "version": "0.0.0"
+ }
+ },
+ "HostedZone": {
+ "id": "HostedZone",
+ "path": "IntegAlbOidc/HostedZone",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "Certificate": {
+ "id": "Certificate",
+ "path": "IntegAlbOidc/Certificate",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/Certificate/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::CertificateManager::Certificate",
+ "aws:cdk:cloudformation:props": {
+ "domainName": "*.example.com",
+ "domainValidationOptions": [
+ {
+ "domainName": "*.example.com",
+ "hostedZoneId": "Z23ABC4XYZL05B"
+ }
+ ],
+ "tags": [
+ {
+ "key": "Name",
+ "value": "IntegAlbOidc/Certificate"
+ }
+ ],
+ "validationMethod": "DNS"
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_certificatemanager.CfnCertificate",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_certificatemanager.Certificate",
+ "version": "0.0.0"
+ }
+ },
+ "UserPool": {
+ "id": "UserPool",
+ "path": "IntegAlbOidc/UserPool",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/UserPool/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Cognito::UserPool",
+ "aws:cdk:cloudformation:props": {
+ "accountRecoverySetting": {
+ "recoveryMechanisms": [
+ {
+ "name": "verified_phone_number",
+ "priority": 1
+ },
+ {
+ "name": "verified_email",
+ "priority": 2
+ }
+ ]
+ },
+ "adminCreateUserConfig": {
+ "allowAdminCreateUserOnly": true
+ },
+ "autoVerifiedAttributes": [
+ "email"
+ ],
+ "emailVerificationMessage": "The verification code to your new account is {####}",
+ "emailVerificationSubject": "Verify your new account",
+ "smsVerificationMessage": "The verification code to your new account is {####}",
+ "usernameAttributes": [
+ "email"
+ ],
+ "verificationMessageTemplate": {
+ "defaultEmailOption": "CONFIRM_WITH_CODE",
+ "emailMessage": "The verification code to your new account is {####}",
+ "emailSubject": "Verify your new account",
+ "smsMessage": "The verification code to your new account is {####}"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool",
+ "version": "0.0.0"
+ }
+ },
+ "Domain": {
+ "id": "Domain",
+ "path": "IntegAlbOidc/UserPool/Domain",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/UserPool/Domain/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Cognito::UserPoolDomain",
+ "aws:cdk:cloudformation:props": {
+ "domain": "z23abc4xyzl05b",
+ "userPoolId": {
+ "Ref": "UserPool6BA7E5F2"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_cognito.CfnUserPoolDomain",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_cognito.UserPoolDomain",
+ "version": "0.0.0"
+ }
+ },
+ "UserPoolClient": {
+ "id": "UserPoolClient",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Cognito::UserPoolClient",
+ "aws:cdk:cloudformation:props": {
+ "userPoolId": {
+ "Ref": "UserPool6BA7E5F2"
+ },
+ "allowedOAuthFlows": [
+ "code"
+ ],
+ "allowedOAuthFlowsUserPoolClient": true,
+ "allowedOAuthScopes": [
+ "profile",
+ "phone",
+ "email",
+ "openid",
+ "aws.cognito.signin.user.admin"
+ ],
+ "callbackUrLs": [
+ "https://*.example.com/oauth2/idpresponse"
+ ],
+ "generateSecret": true,
+ "supportedIdentityProviders": [
+ "COGNITO"
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_cognito.CfnUserPoolClient",
+ "version": "0.0.0"
+ }
+ },
+ "DescribeCognitoUserPoolClient": {
+ "id": "DescribeCognitoUserPoolClient",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient",
+ "children": {
+ "Provider": {
+ "id": "Provider",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient/Provider",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient/Resource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient/Resource/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourcePolicy": {
+ "id": "CustomResourcePolicy",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient/CustomResourcePolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/UserPool/UserPoolClient/DescribeCognitoUserPoolClient/CustomResourcePolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:DescribeUserPoolClient",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "UserPoolUserPoolClientDescribeCognitoUserPoolClientCustomResourcePolicyFFF2174F",
+ "roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.custom_resources.AwsCustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_cognito.UserPoolClient",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_cognito.UserPool",
+ "version": "0.0.0"
+ }
+ },
+ "LoadBalancer": {
+ "id": "LoadBalancer",
+ "path": "IntegAlbOidc/LoadBalancer",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/LoadBalancer/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
+ "aws:cdk:cloudformation:props": {
+ "loadBalancerAttributes": [
+ {
+ "key": "deletion_protection.enabled",
+ "value": "false"
+ }
+ ],
+ "scheme": "internet-facing",
+ "securityGroups": [
+ {
+ "Fn::GetAtt": [
+ "LoadBalancerSecurityGroupA28D6DD7",
+ "GroupId"
+ ]
+ }
+ ],
+ "subnets": [
+ {
+ "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+ },
+ {
+ "Ref": "VpcPublicSubnet2Subnet691E08A3"
+ }
+ ],
+ "type": "application"
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer",
+ "version": "0.0.0"
+ }
+ },
+ "SecurityGroup": {
+ "id": "SecurityGroup",
+ "path": "IntegAlbOidc/LoadBalancer/SecurityGroup",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/LoadBalancer/SecurityGroup/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup",
+ "aws:cdk:cloudformation:props": {
+ "groupDescription": "Automatically created Security Group for ELB IntegAlbOidcLoadBalancer3609D530",
+ "securityGroupEgress": [
+ {
+ "cidrIp": "0.0.0.0/0",
+ "ipProtocol": "tcp",
+ "fromPort": 443,
+ "toPort": 443,
+ "description": "Allow to IdP endpoint"
+ }
+ ],
+ "securityGroupIngress": [
+ {
+ "cidrIp": "0.0.0.0/0",
+ "ipProtocol": "tcp",
+ "fromPort": 443,
+ "toPort": 443,
+ "description": "Allow from anyone on port 443"
+ }
+ ],
+ "vpcId": {
+ "Ref": "Vpc8378EB38"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup",
+ "version": "0.0.0"
+ }
+ },
+ "Listener": {
+ "id": "Listener",
+ "path": "IntegAlbOidc/LoadBalancer/Listener",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/LoadBalancer/Listener/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener",
+ "aws:cdk:cloudformation:props": {
+ "defaultActions": [
+ {
+ "type": "authenticate-oidc",
+ "authenticateOidcConfig": {
+ "authorizationEndpoint": {
+ "Fn::Join": [
+ "",
+ [
+ "https://",
+ {
+ "Ref": "UserPoolDomainD0EA232A"
+ },
+ ".auth.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazoncognito.com/oauth2/authorize"
+ ]
+ ]
+ },
+ "clientId": {
+ "Ref": "UserPoolUserPoolClient40176907"
+ },
+ "clientSecret": {
+ "Fn::GetAtt": [
+ "UserPoolUserPoolClientDescribeCognitoUserPoolClientA6EA22D2",
+ "UserPoolClient.ClientSecret"
+ ]
+ },
+ "issuer": {
+ "Fn::Join": [
+ "",
+ [
+ "https://cognito-idp.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazonaws.com/",
+ {
+ "Ref": "UserPool6BA7E5F2"
+ }
+ ]
+ ]
+ },
+ "tokenEndpoint": {
+ "Fn::Join": [
+ "",
+ [
+ "https://",
+ {
+ "Ref": "UserPoolDomainD0EA232A"
+ },
+ ".auth.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazoncognito.com/oauth2/token"
+ ]
+ ]
+ },
+ "userInfoEndpoint": {
+ "Fn::Join": [
+ "",
+ [
+ "https://",
+ {
+ "Ref": "UserPoolDomainD0EA232A"
+ },
+ ".auth.",
+ {
+ "Ref": "AWS::Region"
+ },
+ ".amazoncognito.com/oauth2/userInfo"
+ ]
+ ]
+ }
+ },
+ "order": 1
+ },
+ {
+ "type": "fixed-response",
+ "fixedResponseConfig": {
+ "statusCode": "200",
+ "contentType": "text/plain",
+ "messageBody": "Authenticated"
+ },
+ "order": 2
+ }
+ ],
+ "loadBalancerArn": {
+ "Ref": "LoadBalancerBE9EEC3A"
+ },
+ "certificates": [
+ {
+ "certificateArn": {
+ "Ref": "Certificate4E7ABB08"
+ }
+ }
+ ],
+ "port": 443,
+ "protocol": "HTTPS"
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnListener",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationListener",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer",
+ "version": "0.0.0"
+ }
+ },
+ "DefaultCrNodeVersionMap": {
+ "id": "DefaultCrNodeVersionMap",
+ "path": "IntegAlbOidc/DefaultCrNodeVersionMap",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnMapping",
+ "version": "0.0.0"
+ }
+ },
+ "AWS679f53fac002430cb0da5b7982bd2287": {
+ "id": "AWS679f53fac002430cb0da5b7982bd2287",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole",
+ "children": {
+ "ImportServiceRole": {
+ "id": "ImportServiceRole",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/ImportServiceRole",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnRole",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Code": {
+ "id": "Code",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/Code/Stage",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3_assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/AWS679f53fac002430cb0da5b7982bd2287/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "s3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "s3Key": "a9d3d4d1afa000946b9863b3e7578a5a5ad86d88274b3639938aa2baebf822ce.zip"
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
+ "Arn"
+ ]
+ },
+ "handler": "index.handler",
+ "runtime": {
+ "Fn::FindInMap": [
+ "DefaultCrNodeVersionMap",
+ {
+ "Ref": "AWS::Region"
+ },
+ "value"
+ ]
+ },
+ "timeout": 120
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.Function",
+ "version": "0.0.0"
+ }
+ },
+ "ARecord": {
+ "id": "ARecord",
+ "path": "IntegAlbOidc/ARecord",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/ARecord/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet",
+ "aws:cdk:cloudformation:props": {
+ "name": "example.com.",
+ "type": "A",
+ "aliasTarget": {
+ "hostedZoneId": {
+ "Fn::GetAtt": [
+ "LoadBalancerBE9EEC3A",
+ "CanonicalHostedZoneID"
+ ]
+ },
+ "dnsName": {
+ "Fn::Join": [
+ "",
+ [
+ "dualstack.",
+ {
+ "Fn::GetAtt": [
+ "LoadBalancerBE9EEC3A",
+ "DNSName"
+ ]
+ }
+ ]
+ ]
+ }
+ },
+ "hostedZoneId": "Z23ABC4XYZL05B"
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_route53.CfnRecordSet",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_route53.ARecord",
+ "version": "0.0.0"
+ }
+ },
+ "User": {
+ "id": "User",
+ "path": "IntegAlbOidc/User",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/User/Resource",
+ "children": {
+ "Provider": {
+ "id": "Provider",
+ "path": "IntegAlbOidc/User/Resource/Provider",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/User/Resource/Resource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "IntegAlbOidc/User/Resource/Resource/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourcePolicy": {
+ "id": "CustomResourcePolicy",
+ "path": "IntegAlbOidc/User/Resource/CustomResourcePolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/User/Resource/CustomResourcePolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminCreateUser",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "UserCustomResourcePolicyC2EB5139",
+ "roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.custom_resources.AwsCustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "SetUserPassword": {
+ "id": "SetUserPassword",
+ "path": "IntegAlbOidc/User/SetUserPassword",
+ "children": {
+ "Provider": {
+ "id": "Provider",
+ "path": "IntegAlbOidc/User/SetUserPassword/Provider",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/User/SetUserPassword/Resource",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "IntegAlbOidc/User/SetUserPassword/Resource/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "CustomResourcePolicy": {
+ "id": "CustomResourcePolicy",
+ "path": "IntegAlbOidc/User/SetUserPassword/CustomResourcePolicy",
+ "children": {
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/User/SetUserPassword/CustomResourcePolicy/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+ "aws:cdk:cloudformation:props": {
+ "policyDocument": {
+ "Statement": [
+ {
+ "Action": "cognito-idp:AdminSetUserPassword",
+ "Effect": "Allow",
+ "Resource": {
+ "Fn::GetAtt": [
+ "UserPool6BA7E5F2",
+ "Arn"
+ ]
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "policyName": "UserSetUserPasswordCustomResourcePolicy7B250C76",
+ "roles": [
+ {
+ "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2"
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Policy",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.custom_resources.AwsCustomResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.2.9"
+ }
+ },
+ "Signin": {
+ "id": "Signin",
+ "path": "IntegAlbOidc/Signin",
+ "children": {
+ "ServiceRole": {
+ "id": "ServiceRole",
+ "path": "IntegAlbOidc/Signin/ServiceRole",
+ "children": {
+ "ImportServiceRole": {
+ "id": "ImportServiceRole",
+ "path": "IntegAlbOidc/Signin/ServiceRole/ImportServiceRole",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Resource",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/Signin/ServiceRole/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+ "aws:cdk:cloudformation:props": {
+ "assumeRolePolicyDocument": {
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "lambda.amazonaws.com"
+ }
+ }
+ ],
+ "Version": "2012-10-17"
+ },
+ "managedPolicyArns": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ {
+ "Ref": "AWS::Partition"
+ },
+ ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+ ]
+ ]
+ }
+ ]
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.CfnRole",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_iam.Role",
+ "version": "0.0.0"
+ }
+ },
+ "Code": {
+ "id": "Code",
+ "path": "IntegAlbOidc/Signin/Code",
+ "children": {
+ "Stage": {
+ "id": "Stage",
+ "path": "IntegAlbOidc/Signin/Code/Stage",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "AssetBucket": {
+ "id": "AssetBucket",
+ "path": "IntegAlbOidc/Signin/Code/AssetBucket",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3.BucketBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_s3_assets.Asset",
+ "version": "0.0.0"
+ }
+ },
+ "Resource": {
+ "id": "Resource",
+ "path": "IntegAlbOidc/Signin/Resource",
+ "attributes": {
+ "aws:cdk:cloudformation:type": "AWS::Lambda::Function",
+ "aws:cdk:cloudformation:props": {
+ "code": {
+ "s3Bucket": {
+ "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
+ },
+ "s3Key": "1832f4c7bb54fe8f4eb5677dc53ae4204e4b27b12077ddd397a6755206864302.zip"
+ },
+ "role": {
+ "Fn::GetAtt": [
+ "SigninServiceRole24B8BB32",
+ "Arn"
+ ]
+ },
+ "environment": {
+ "variables": {
+ "TEST_USERNAME": "test-user@example.com",
+ "TEST_PASSWORD": "TestUser@123",
+ "TEST_URL": "https://*.example.com"
+ }
+ },
+ "functionName": "cdk-integ-alb-oidc-signin-handler",
+ "handler": "index.handler",
+ "memorySize": 1024,
+ "runtime": "nodejs18.x",
+ "timeout": 300
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.CfnFunction",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_lambda.Function",
+ "version": "0.0.0"
+ }
+ },
+ "Exports": {
+ "id": "Exports",
+ "path": "IntegAlbOidc/Exports",
+ "children": {
+ "Output{\"Ref\":\"Signin352C80E6\"}": {
+ "id": "Output{\"Ref\":\"Signin352C80E6\"}",
+ "path": "IntegAlbOidc/Exports/Output{\"Ref\":\"Signin352C80E6\"}",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnOutput",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.2.9"
+ }
+ },
+ "BootstrapVersion": {
+ "id": "BootstrapVersion",
+ "path": "IntegAlbOidc/BootstrapVersion",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "CheckBootstrapVersion": {
+ "id": "CheckBootstrapVersion",
+ "path": "IntegAlbOidc/CheckBootstrapVersion",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnRule",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Stack",
+ "version": "0.0.0"
+ }
+ },
+ "IntegTestAlbOidc": {
+ "id": "IntegTestAlbOidc",
+ "path": "IntegTestAlbOidc",
+ "children": {
+ "DefaultTest": {
+ "id": "DefaultTest",
+ "path": "IntegTestAlbOidc/DefaultTest",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "IntegTestAlbOidc/DefaultTest/Default",
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.2.9"
+ }
+ },
+ "DeployAssert": {
+ "id": "DeployAssert",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert",
+ "children": {
+ "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd": {
+ "id": "LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd",
+ "children": {
+ "SdkProvider": {
+ "id": "SdkProvider",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/SdkProvider",
+ "children": {
+ "AssertionsProvider": {
+ "id": "AssertionsProvider",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/SdkProvider/AssertionsProvider",
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.2.9"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/integ-tests-alpha.AssertionsProvider",
+ "version": "0.0.0"
+ }
+ },
+ "Default": {
+ "id": "Default",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Default",
+ "children": {
+ "Default": {
+ "id": "Default",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Default/Default",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CustomResource",
+ "version": "0.0.0"
+ }
+ },
+ "Invoke": {
+ "id": "Invoke",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/Invoke",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ },
+ "AssertionResults": {
+ "id": "AssertionResults",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/LambdaInvoke018ab0799f88e5aed4847cc0bb1ff6bd/AssertionResults",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnOutput",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/integ-tests-alpha.LambdaInvokeFunction",
+ "version": "0.0.0"
+ }
+ },
+ "SingletonFunction1488541a7b23466481b69b4408076b81": {
+ "id": "SingletonFunction1488541a7b23466481b69b4408076b81",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81",
+ "children": {
+ "Staging": {
+ "id": "Staging",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Staging",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "Role": {
+ "id": "Role",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ },
+ "Handler": {
+ "id": "Handler",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnResource",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.2.9"
+ }
+ },
+ "BootstrapVersion": {
+ "id": "BootstrapVersion",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/BootstrapVersion",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnParameter",
+ "version": "0.0.0"
+ }
+ },
+ "CheckBootstrapVersion": {
+ "id": "CheckBootstrapVersion",
+ "path": "IntegTestAlbOidc/DefaultTest/DeployAssert/CheckBootstrapVersion",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnRule",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.Stack",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "@aws-cdk/integ-tests-alpha.IntegTest",
+ "version": "0.0.0"
+ }
+ },
+ "Tree": {
+ "id": "Tree",
+ "path": "Tree",
+ "constructInfo": {
+ "fqn": "constructs.Construct",
+ "version": "10.2.9"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.App",
+ "version": "0.0.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.ts
new file mode 100644
index 0000000000000..b22cb28c98fc2
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.oidc.ts
@@ -0,0 +1,198 @@
+import * as integ from '@aws-cdk/integ-tests-alpha';
+import * as acm from 'aws-cdk-lib/aws-certificatemanager';
+import * as cognito from 'aws-cdk-lib/aws-cognito';
+import * as ec2 from 'aws-cdk-lib/aws-ec2';
+import { ApplicationLoadBalancer, ApplicationProtocol, ListenerAction } from 'aws-cdk-lib/aws-elasticloadbalancingv2';
+import * as iam from 'aws-cdk-lib/aws-iam';
+import * as lambda from 'aws-cdk-lib/aws-lambda';
+import * as route53 from 'aws-cdk-lib/aws-route53';
+import * as route53targets from 'aws-cdk-lib/aws-route53-targets';
+import { App, Duration, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib/core';
+import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from 'aws-cdk-lib/custom-resources';
+import { Construct } from 'constructs';
+
+interface CognitoUserProps {
+ userPool: cognito.UserPool
+ username: string
+ password: string
+}
+/**
+ * Cognito User for testing
+ */
+class CognitoUser extends Construct {
+ readonly username: string;
+ readonly password: string;
+ constructor(scope: Construct, id: string, props: CognitoUserProps) {
+ super(scope, id);
+ const user = new AwsCustomResource(this, 'Resource', {
+ resourceType: 'Custom::CognitoUser',
+ onCreate: {
+ service: 'CognitoIdentityServiceProvider',
+ action: 'adminCreateUser',
+ parameters: {
+ UserPoolId: props.userPool.userPoolId,
+ Username: props.username,
+ UserAttributes: [
+ {
+ Name: 'email',
+ Value: props.username,
+ },
+ {
+ Name: 'email_verified',
+ Value: 'true',
+ },
+ ],
+ MessageAction: 'SUPPRESS',
+ },
+ physicalResourceId: PhysicalResourceId.of('User'),
+ },
+ policy: AwsCustomResourcePolicy.fromStatements([new iam.PolicyStatement({
+ actions: ['cognito-idp:AdminCreateUser'],
+ resources: [props.userPool.userPoolArn],
+ })]),
+ });
+
+ new AwsCustomResource(this, 'SetUserPassword', {
+ resourceType: 'Custom::CognitoUserPassword',
+ onCreate: {
+ service: 'CognitoIdentityServiceProvider',
+ action: 'adminSetUserPassword',
+ parameters: {
+ UserPoolId: props.userPool.userPoolId,
+ Username: user.getResponseField('User.Username'),
+ Password: props.password,
+ Permanent: true,
+ },
+ physicalResourceId: PhysicalResourceId.of('SetUserPassword'),
+ },
+ policy: AwsCustomResourcePolicy.fromStatements([new iam.PolicyStatement({
+ actions: ['cognito-idp:AdminSetUserPassword'],
+ resources: [props.userPool.userPoolArn],
+ })]),
+ }).node.addDependency(user);
+ this.password = props.password;
+ this.username = props.username;
+ }
+}
+
+interface AlbOidcStackProps extends StackProps {
+ hostedZoneId: string
+ hostedZoneName: string
+ domainName: string
+}
+
+class AlbOidcStack extends Stack {
+ public readonly userPool: cognito.UserPool;
+ constructor(scope: Construct, id: string, props: AlbOidcStackProps) {
+ super(scope, id, props);
+
+ const vpc = new ec2.Vpc(this, 'Vpc', {
+ maxAzs: 2,
+ });
+
+ const hostedZone = route53.PublicHostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
+ hostedZoneId: props.hostedZoneId,
+ zoneName: props.hostedZoneName,
+ });
+ const certificate = new acm.Certificate(this, 'Certificate', {
+ domainName: props.domainName,
+ validation: acm.CertificateValidation.fromDns(hostedZone),
+ });
+
+ // Create Cognito UserPool as IdP
+ this.userPool = new cognito.UserPool(this, 'UserPool', {
+ signInAliases: {
+ email: true,
+ },
+ removalPolicy: RemovalPolicy.DESTROY,
+ });
+ const userPoolDomain = this.userPool.addDomain('Domain', {
+ cognitoDomain: {
+ domainPrefix: props.hostedZoneId.toLowerCase(),
+ },
+ });
+ const userPoolClient = this.userPool.addClient('UserPoolClient', {
+ generateSecret: true,
+ oAuth: {
+ callbackUrls: [`https://${props.domainName}/oauth2/idpresponse`],
+ flows: {
+ authorizationCodeGrant: true,
+ },
+ },
+ });
+
+ const lb = new ApplicationLoadBalancer(this, 'LoadBalancer', {
+ vpc,
+ internetFacing: true,
+ });
+ const userPoolDomainName = `${userPoolDomain.domainName}.auth.${this.region}.amazoncognito.com`;
+ lb.addListener('Listener', {
+ protocol: ApplicationProtocol.HTTPS,
+ certificates: [certificate],
+ defaultAction: ListenerAction.authenticateOidc({
+ authorizationEndpoint: `https://${userPoolDomainName}/oauth2/authorize`,
+ clientId: userPoolClient.userPoolClientId,
+ clientSecret: userPoolClient.userPoolClientSecret,
+ issuer: `https://cognito-idp.${this.region}.amazonaws.com/${this.userPool.userPoolId}`,
+ tokenEndpoint: `https://${userPoolDomainName}/oauth2/token`,
+ userInfoEndpoint: `https://${userPoolDomainName}/oauth2/userInfo`,
+ next: ListenerAction.fixedResponse(200, {
+ contentType: 'text/plain',
+ messageBody: 'Authenticated',
+ }),
+ }),
+ });
+ new route53.ARecord(this, 'ARecord', {
+ target: route53.RecordTarget.fromAlias(new route53targets.LoadBalancerTarget(lb)),
+ zone: hostedZone,
+ });
+ }
+}
+
+/**
+ * In order to test this you need to have a valid public hosted zone that you can use
+ * to request certificates for.
+ *
+*/
+const hostedZoneId = process.env.CDK_INTEG_HOSTED_ZONE_ID ?? process.env.HOSTED_ZONE_ID;
+if (!hostedZoneId) throw new Error('For this test you must provide your own HostedZoneId as an env var "HOSTED_ZONE_ID"');
+const hostedZoneName = process.env.CDK_INTEG_HOSTED_ZONE_NAME ?? process.env.HOSTED_ZONE_NAME;
+if (!hostedZoneName) throw new Error('For this test you must provide your own HostedZoneName as an env var "HOSTED_ZONE_NAME"');
+const domainName = process.env.CDK_INTEG_DOMAIN_NAME ?? process.env.DOMAIN_NAME;
+if (!domainName) throw new Error('For this test you must provide your own Domain Name as an env var "DOMAIN_NAME"');
+
+const app = new App();
+const testCase = new AlbOidcStack(app, 'IntegAlbOidc', {
+ hostedZoneId,
+ hostedZoneName,
+ domainName,
+});
+const test = new integ.IntegTest(app, 'IntegTestAlbOidc', {
+ testCases: [testCase],
+});
+const testUser = new CognitoUser(testCase, 'User', {
+ userPool: testCase.userPool,
+ username: 'test-user@example.com',
+ password: 'TestUser@123',
+});
+// this function signs in to the website and returns text content of the authenticated page body
+const signinFunction = new lambda.Function(testCase, 'Signin', {
+ functionName: 'cdk-integ-alb-oidc-signin-handler',
+ code: lambda.Code.fromAsset('alb-oidc-signin-handler'),
+ handler: 'index.handler',
+ runtime: lambda.Runtime.NODEJS_18_X,
+ environment: {
+ TEST_USERNAME: testUser.username,
+ TEST_PASSWORD: testUser.password,
+ TEST_URL: `https://${domainName}`,
+ },
+ memorySize: 1024,
+ timeout: Duration.minutes(5),
+});
+const invoke = test.assertions.invokeFunction({
+ functionName: signinFunction.functionName,
+});
+invoke.expect(integ.ExpectedResult.objectLike({
+ Payload: '"Authenticated"',
+}));
+app.synth();
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb2.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb2.js.snapshot/cdk.out
index 588d7b269d34f..b72fef144f05c 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb2.js.snapshot/cdk.out
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb2.js.snapshot/cdk.out
@@ -1 +1 @@
-{"version":"20.0.0"}
\ No newline at end of file
+{"version":"30.1.0"}
\ No newline at end of file
diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/lib/cognito-action.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/lib/cognito-action.ts
index 454d7cddd9e95..f0727ee79eba8 100644
--- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/lib/cognito-action.ts
+++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/lib/cognito-action.ts
@@ -1,4 +1,6 @@
+import { Construct, IConstruct } from 'constructs';
import * as cognito from '../../aws-cognito';
+import { Port } from '../../aws-ec2';
import * as elbv2 from '../../aws-elasticloadbalancingv2';
import { Duration } from '../../core';
@@ -65,6 +67,18 @@ export interface AuthenticateCognitoActionProps {
* @default Duration.days(7)
*/
readonly sessionTimeout?: Duration;
+
+ /**
+ * Allow HTTPS outbound traffic to communicate with the IdP.
+ *
+ * Set this property to false if the IP address used for the IdP endpoint is identifiable
+ * and you want to control outbound traffic.
+ * Then allow HTTPS outbound traffic to the IdP's IP address using the listener's `connections` property.
+ *
+ * @default true
+ * @see https://repost.aws/knowledge-center/elb-configure-authentication-alb
+ */
+ readonly allowHttpsOutbound?: boolean;
}
/**
@@ -85,6 +99,8 @@ export class AuthenticateCognitoAction extends elbv2.ListenerAction {
};
}
+ private readonly allowHttpsOutbound: boolean;
+
/**
* Authenticate using an identity provide (IdP) that is compliant with OpenID Connect (OIDC)
*/
@@ -93,6 +109,8 @@ export class AuthenticateCognitoAction extends elbv2.ListenerAction {
type: 'authenticate-cognito',
authenticateCognitoConfig: AuthenticateCognitoAction.config(options),
}, options.next);
+
+ this.allowHttpsOutbound = options.allowHttpsOutbound ?? true;
this.addRuleAction({
type: 'authenticate-cognito',
authenticateCognitoConfig: {
@@ -101,4 +119,10 @@ export class AuthenticateCognitoAction extends elbv2.ListenerAction {
},
});
}
+ public bind(scope: Construct, listener: elbv2.IApplicationListener, associatingConstruct?: IConstruct | undefined): void {
+ super.bind(scope, listener, associatingConstruct);
+
+ if (!this.allowHttpsOutbound) return;
+ listener.connections.allowToAnyIpv4(Port.tcp(443), 'Allow to IdP endpoint');
+ }
}
diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/test/cognito.test.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/test/cognito.test.ts
index e98a96ab1f74f..a738e52c35178 100644
--- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/test/cognito.test.ts
+++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-actions/test/cognito.test.ts
@@ -59,7 +59,61 @@ test('Cognito Action', () => {
});
});
-test('Can set sessionTimeout for actions and defaultActions', () => {
+test('Cognito authentication action allows HTTPS outbound', () => {
+ // GIVEN
+ const stack = new Stack();
+ const vpc = new ec2.Vpc(stack, 'Stack');
+ const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc });
+
+ const userPool = new cognito.UserPool(stack, 'UserPool');
+ const userPoolClient = new cognito.UserPoolClient(stack, 'Client', { userPool });
+ const userPoolDomain = new cognito.UserPoolDomain(stack, 'Domain', {
+ userPool,
+ cognitoDomain: {
+ domainPrefix: 'prefix',
+ },
+ });
+
+ // WHEN
+ lb.addListener('Listener', {
+ port: 80,
+ defaultAction: new actions.AuthenticateCognitoAction({
+ userPool,
+ userPoolClient,
+ userPoolDomain,
+ next: elbv2.ListenerAction.fixedResponse(200, {
+ contentType: 'text/plain',
+ messageBody: 'Authenticated',
+ }),
+ }),
+ });
+
+ // THEN
+ Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', {
+ GroupDescription: 'Automatically created Security Group for ELB LB',
+ SecurityGroupEgress: [
+ {
+ CidrIp: '0.0.0.0/0',
+ Description: 'Allow to IdP endpoint',
+ FromPort: 443,
+ IpProtocol: 'tcp',
+ ToPort: 443,
+ },
+ ],
+ SecurityGroupIngress: [
+ {
+ CidrIp: '0.0.0.0/0',
+ Description: 'Allow from anyone on port 80',
+ FromPort: 80,
+ IpProtocol: 'tcp',
+ ToPort: 80,
+ },
+ ],
+ VpcId: { Ref: 'Stack8A423254' },
+ });
+});
+
+test('Cognito authentication action not allows HTTPS outbound when allowHttpsOutbound is false', () => {
// GIVEN
const stack = new Stack();
const vpc = new ec2.Vpc(stack, 'Stack');
@@ -74,6 +128,60 @@ test('Can set sessionTimeout for actions and defaultActions', () => {
},
});
+ // WHEN
+ lb.addListener('Listener', {
+ port: 80,
+ defaultAction: new actions.AuthenticateCognitoAction({
+ allowHttpsOutbound: false,
+ userPool,
+ userPoolClient,
+ userPoolDomain,
+ next: elbv2.ListenerAction.fixedResponse(200, {
+ contentType: 'text/plain',
+ messageBody: 'Authenticated',
+ }),
+ }),
+ });
+
+ // THEN
+ Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', {
+ GroupDescription: 'Automatically created Security Group for ELB LB',
+ SecurityGroupEgress: [
+ {
+ CidrIp: '255.255.255.255/32',
+ Description: 'Disallow all traffic',
+ FromPort: 252,
+ IpProtocol: 'icmp',
+ ToPort: 86,
+ },
+ ],
+ SecurityGroupIngress: [
+ {
+ CidrIp: '0.0.0.0/0',
+ Description: 'Allow from anyone on port 80',
+ FromPort: 80,
+ IpProtocol: 'tcp',
+ ToPort: 80,
+ },
+ ],
+ VpcId: { Ref: 'Stack8A423254' },
+ });
+});
+
+test('Can set sessionTimeout for actions and defaultActions', () => {
+ // GIVEN
+ const stack = new Stack();
+ const vpc = new ec2.Vpc(stack, 'Stack');
+ const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc });
+
+ const userPool = new cognito.UserPool(stack, 'UserPool');
+ const userPoolClient = new cognito.UserPoolClient(stack, 'Client', { userPool });
+ const userPoolDomain = new cognito.UserPoolDomain(stack, 'Domain', {
+ userPool,
+ cognitoDomain: {
+ domainPrefix: 'prefix',
+ },
+ });
const action = new actions.AuthenticateCognitoAction({
userPool,
userPoolClient,
diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts
index 68625f631d78a..f3135ecd94ca9 100644
--- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts
+++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts
@@ -1,6 +1,7 @@
import { Construct, IConstruct } from 'constructs';
import { IApplicationListener } from './application-listener';
import { IApplicationTargetGroup } from './application-target-group';
+import { Port } from '../../../aws-ec2';
import { Duration, SecretValue, Tokenization } from '../../../core';
import { CfnListener, CfnListenerRule } from '../elasticloadbalancingv2.generated';
import { IListenerAction } from '../shared/listener-action';
@@ -28,31 +29,7 @@ export class ListenerAction implements IListenerAction {
* @see https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#oidc-requirements
*/
public static authenticateOidc(options: AuthenticateOidcOptions): ListenerAction {
- const config: CfnListener.AuthenticateOidcConfigProperty = {
- authorizationEndpoint: options.authorizationEndpoint,
- clientId: options.clientId,
- clientSecret: options.clientSecret.unsafeUnwrap(), // Safe usage
- issuer: options.issuer,
- tokenEndpoint: options.tokenEndpoint,
- userInfoEndpoint: options.userInfoEndpoint,
- authenticationRequestExtraParams: options.authenticationRequestExtraParams,
- onUnauthenticatedRequest: options.onUnauthenticatedRequest,
- scope: options.scope,
- sessionCookieName: options.sessionCookieName,
- sessionTimeout: options.sessionTimeout?.toSeconds().toString(),
- };
- const listenerAction = new ListenerAction({
- type: 'authenticate-oidc',
- authenticateOidcConfig: config,
- }, options.next);
- listenerAction.addRuleAction({
- type: 'authenticate-oidc',
- authenticateOidcConfig: {
- ...config,
- sessionTimeout: options.sessionTimeout?.toSeconds(),
- },
- });
- return listenerAction;
+ return new AuthenticateOidcAction(options);
}
/**
@@ -438,6 +415,18 @@ export interface AuthenticateOidcOptions {
* This must be a full URL, including the HTTPS protocol, the domain, and the path.
*/
readonly userInfoEndpoint: string;
+
+ /**
+ * Allow HTTPS outbound traffic to communicate with the IdP.
+ *
+ * Set this property to false if the IP address used for the IdP endpoint is identifiable
+ * and you want to control outbound traffic.
+ * Then allow HTTPS outbound traffic to the IdP's IP address using the listener's `connections` property.
+ *
+ * @default true
+ * @see https://repost.aws/knowledge-center/elb-configure-authentication-alb
+ */
+ readonly allowHttpsOutbound?: boolean;
}
/**
@@ -474,3 +463,45 @@ class TargetGroupListenerAction extends ListenerAction {
}
}
}
+
+/**
+ * A Listener Action to authenticate with OIDC
+ */
+class AuthenticateOidcAction extends ListenerAction {
+ private readonly allowHttpsOutbound: boolean;
+
+ constructor(options: AuthenticateOidcOptions) {
+ const defaultActionConfig: CfnListener.AuthenticateOidcConfigProperty = {
+ authorizationEndpoint: options.authorizationEndpoint,
+ clientId: options.clientId,
+ clientSecret: options.clientSecret.unsafeUnwrap(), // Safe usage
+ issuer: options.issuer,
+ tokenEndpoint: options.tokenEndpoint,
+ userInfoEndpoint: options.userInfoEndpoint,
+ authenticationRequestExtraParams: options.authenticationRequestExtraParams,
+ onUnauthenticatedRequest: options.onUnauthenticatedRequest,
+ scope: options.scope,
+ sessionCookieName: options.sessionCookieName,
+ sessionTimeout: options.sessionTimeout?.toSeconds().toString(),
+ };
+ super({
+ type: 'authenticate-oidc',
+ authenticateOidcConfig: defaultActionConfig,
+ }, options.next);
+
+ this.allowHttpsOutbound = options.allowHttpsOutbound ?? true;
+ this.addRuleAction({
+ type: 'authenticate-oidc',
+ authenticateOidcConfig: {
+ ...defaultActionConfig,
+ sessionTimeout: options.sessionTimeout?.toSeconds(),
+ },
+ });
+ }
+ public bind(scope: Construct, listener: IApplicationListener, associatingConstruct?: IConstruct | undefined): void {
+ super.bind(scope, listener, associatingConstruct);
+
+ if (!this.allowHttpsOutbound) return;
+ listener.connections.allowToAnyIpv4(Port.tcp(443), 'Allow to IdP endpoint');
+ }
+}
\ No newline at end of file
diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts
index ad636135138c5..c3b1d090ceb98 100644
--- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts
+++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts
@@ -185,6 +185,87 @@ describe('tests', () => {
});
});
+ test('OIDC authentication action allows HTTPS outbound', () => {
+ // WHEN
+ lb.addListener('Listener', {
+ port: 80,
+ defaultAction: elbv2.ListenerAction.authenticateOidc({
+ authorizationEndpoint: 'A',
+ clientId: 'B',
+ clientSecret: cdk.SecretValue.unsafePlainText('C'),
+ issuer: 'D',
+ tokenEndpoint: 'E',
+ userInfoEndpoint: 'F',
+ next: elbv2.ListenerAction.forward([group1]),
+ }),
+ });
+
+ // THEN
+ Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', {
+ GroupDescription: 'Automatically created Security Group for ELB LB',
+ SecurityGroupEgress: [
+ {
+ CidrIp: '0.0.0.0/0',
+ Description: 'Allow to IdP endpoint',
+ FromPort: 443,
+ IpProtocol: 'tcp',
+ ToPort: 443,
+ },
+ ],
+ SecurityGroupIngress: [
+ {
+ CidrIp: '0.0.0.0/0',
+ Description: 'Allow from anyone on port 80',
+ FromPort: 80,
+ IpProtocol: 'tcp',
+ ToPort: 80,
+ },
+ ],
+ VpcId: { Ref: 'Stack8A423254' },
+ });
+ });
+
+ test('OIDC authentication action not allows HTTPS outbound when allowHttpsOutbound is false', () => {
+ // WHEN
+ lb.addListener('Listener', {
+ port: 80,
+ defaultAction: elbv2.ListenerAction.authenticateOidc({
+ allowHttpsOutbound: false,
+ authorizationEndpoint: 'A',
+ clientId: 'B',
+ clientSecret: cdk.SecretValue.unsafePlainText('C'),
+ issuer: 'D',
+ tokenEndpoint: 'E',
+ userInfoEndpoint: 'F',
+ next: elbv2.ListenerAction.forward([group1]),
+ }),
+ });
+
+ // THEN
+ Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', {
+ GroupDescription: 'Automatically created Security Group for ELB LB',
+ SecurityGroupEgress: [
+ {
+ CidrIp: '255.255.255.255/32',
+ Description: 'Disallow all traffic',
+ FromPort: 252,
+ IpProtocol: 'icmp',
+ ToPort: 86,
+ },
+ ],
+ SecurityGroupIngress: [
+ {
+ CidrIp: '0.0.0.0/0',
+ Description: 'Allow from anyone on port 80',
+ FromPort: 80,
+ IpProtocol: 'tcp',
+ ToPort: 80,
+ },
+ ],
+ VpcId: { Ref: 'Stack8A423254' },
+ });
+ });
+
test('Add default Action and add Action with conditions', () => {
// GIVEN
const listener = lb.addListener('Listener', { port: 80 });