@aws/nx-plugin 1.0.0-rc.27 → 1.0.0-rc.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/preset/generator.js +1 -1
- package/src/preset/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +12 -2
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +112 -0
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +115 -1
- package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +1 -0
- package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +1 -0
package/package.json
CHANGED
package/src/preset/generator.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/ import { addDependenciesToPackageJson, detectPackageManager, generateFiles, joinPathFragments, OverwriteStrategy, readNxJson, updateJson, updateNxJson } from "@nx/devkit";
|
|
5
5
|
import { initGenerator } from "@nx/js";
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
|
-
import
|
|
7
|
+
import enquirer from "enquirer";
|
|
8
8
|
import { readFileSync } from "fs";
|
|
9
9
|
import yaml from "js-yaml";
|
|
10
10
|
import { readModulePackageJson } from "nx/src/utils/package-json";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/preset/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addDependenciesToPackageJson,\n detectPackageManager,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n readNxJson,\n type Tree,\n updateJson,\n updateNxJson,\n} from '@nx/devkit';\nimport { initGenerator } from '@nx/js';\nimport { execSync } from 'child_process';\nimport * as enquirer from 'enquirer';\nimport { readFileSync } from 'fs';\nimport yaml from 'js-yaml';\nimport { readModulePackageJson } from 'nx/src/utils/package-json';\nimport GeneratorsJson from '../../generators.json' with { type: 'json' };\nimport { SYNC_GENERATOR_NAME as TS_SYNC_GENERATOR_NAME } from '../ts/sync/generator';\nimport {\n ensureAwsNxPluginConfig,\n updateAwsNxPluginConfig,\n} from '../utils/config/utils';\nimport { inferContainers } from '../utils/containers';\nimport { DEFAULT_BIOME_CONFIG, formatFilesInSubtree } from '../utils/format';\nimport { installDependencies } from '../utils/install';\nimport { configureMcpServers } from '../utils/mcp';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics';\nimport { getNpmScope } from '../utils/npm-scope';\nimport { getGeneratorInfo, type NxGeneratorInfo } from '../utils/nx';\nimport { getPackageManagerDisplayCommands } from '../utils/pkg-manager';\nimport { withVersions } from '../utils/versions';\nimport type { PresetGeneratorSchema } from './schema';\n\nconst WORKSPACES = ['packages/*'];\nconst NX_TYPESCRIPT_SYNC_GENERATOR = '@nx/js:typescript-sync';\n\n// Built dependencies whose install scripts the generated workspace trusts.\n// `onlyBuiltDependencies` is the pnpm 10 key (silently ignored by pnpm 11);\n// pnpm 11 reads `allowBuilds` instead. Any dep NOT in this allowlist will\n// have its install scripts skipped with a warning — matching pnpm 10's\n// default behaviour. The user can opt-in later via `pnpm approve-builds`.\nconst PNPM_BUILT_DEPENDENCIES = ['@swc/core', 'esbuild', 'nx', 'sharp'];\n\nexport const PRESET_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nconst setUpWorkspaces = (tree: Tree) => {\n if (detectPackageManager() === 'pnpm') {\n tree.write(\n 'pnpm-workspace.yaml',\n yaml.dump(\n {\n packages: WORKSPACES,\n allowBuilds: Object.fromEntries(\n PNPM_BUILT_DEPENDENCIES.map((dep) => [dep, true]),\n ),\n onlyBuiltDependencies: PNPM_BUILT_DEPENDENCIES,\n },\n { quotingType: \"'\" },\n ),\n );\n } else {\n updateJson(tree, 'package.json', (json) => {\n json.workspaces = WORKSPACES;\n return json;\n });\n }\n};\n\n/**\n * Determines if the current user is an Amazon employee based on their git configuration.\n *\n * This function checks the git user email configuration to identify Amazon employees\n * by looking for email addresses with Amazon domains (e.g., @amazon.com, @amazon.co.uk).\n *\n * @returns {boolean} True if the user's git email has an Amazon domain, false otherwise\n *\n * @example\n * // Returns true for Amazon employee emails\n * // git config user.email = \"john.doe@amazon.com\"\n * isAmazonian(); // true\n *\n * @example\n * // Returns false for non-Amazon emails\n * // git config user.email = \"user@example.com\"\n * isAmazonian(); // false\n *\n * @example\n * // Returns false when git config is not available or throws an error\n * isAmazonian(); // false\n */\nexport function isAmazonian(): boolean {\n try {\n // Execute git command to retrieve the user's configured email address\n const gitEmail = execSync('git config user.email', {\n encoding: 'utf8',\n }).trim();\n\n // Return false if no email is configured\n if (!gitEmail) {\n return false;\n }\n\n // Split email address to extract domain part\n const emailParts = gitEmail.split('@');\n if (emailParts.length < 2) {\n return false;\n }\n\n // Extract domain and normalize to lowercase for comparison\n const domain = emailParts[1].toLowerCase();\n\n // Check if domain starts with 'amazon.' (covers amazon.com, amazon.co.uk, etc.)\n return domain.startsWith('amazon.');\n } catch (error) {\n // Return false if git command fails or any other error occurs\n // This handles cases where git is not installed or configured\n return false;\n }\n}\n\nconst setUpGitSecrets = (tree: Tree) => {\n const gitSecretsDir = joinPathFragments(\n import.meta.dirname,\n 'git-secrets-files',\n 'git-secrets-dir',\n );\n const huskyDir = joinPathFragments(\n import.meta.dirname,\n 'git-secrets-files',\n 'husky-dir',\n );\n\n tree.write(\n '.git-secrets/git-secrets',\n readFileSync(joinPathFragments(gitSecretsDir, 'git-secrets'), 'utf-8'),\n );\n tree.write(\n '.husky/pre-commit',\n readFileSync(joinPathFragments(huskyDir, 'pre-commit'), 'utf-8'),\n );\n tree.write('.gitallowed', '\\\\.git-secrets/git-secrets:\\n');\n\n updateJson(tree, 'package.json', (json) => ({\n ...json,\n scripts: {\n ...json.scripts,\n prepare: 'husky',\n },\n }));\n\n addDependenciesToPackageJson(tree, {}, withVersions(['husky']));\n};\n\nexport const presetGenerator = async (\n tree: Tree,\n {\n iac,\n gitSecrets,\n mcp,\n containers,\n preferInstallDependencies,\n }: PresetGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const resolvedContainers =\n !containers || containers === 'infer' ? inferContainers() : containers;\n if (\n isAmazonian() &&\n !process.env.VITEST &&\n !process.env.CI &&\n process.env.NX_DRY_RUN !== 'true' &&\n process.env.NX_INTERACTIVE !== 'false'\n ) {\n const { engagementId } = await enquirer.prompt<{ engagementId?: string }>([\n {\n name: 'engagementId',\n message: 'Please enter your engagementId (if known)',\n type: 'input',\n initial: 'None',\n },\n ]);\n\n if (engagementId != 'None') {\n await ensureAwsNxPluginConfig(tree);\n await updateAwsNxPluginConfig(tree, { tags: [engagementId] });\n }\n }\n\n // Write IaC provider and container engine to plugin config\n await ensureAwsNxPluginConfig(tree);\n await updateAwsNxPluginConfig(tree, {\n iac: { provider: iac },\n containers: { engine: resolvedContainers },\n });\n\n await initGenerator(tree, {\n formatter: 'none',\n addTsPlugin: true,\n });\n\n tree.delete('apps/.gitkeep');\n tree.delete('libs/.gitkeep');\n tree.write('packages/.gitkeep', '');\n\n setUpWorkspaces(tree);\n\n const nxJson = readNxJson(tree);\n updateNxJson(tree, {\n ...nxJson,\n analytics: false,\n targetDefaults: {\n ...nxJson.targetDefaults,\n compile: {\n ...nxJson.targetDefaults?.compile,\n syncGenerators: [\n ...(nxJson.targetDefaults?.compile?.syncGenerators ?? []).filter(\n (g) =>\n ![TS_SYNC_GENERATOR_NAME, NX_TYPESCRIPT_SYNC_GENERATOR].includes(\n g,\n ),\n ),\n NX_TYPESCRIPT_SYNC_GENERATOR,\n TS_SYNC_GENERATOR_NAME,\n ],\n },\n },\n });\n\n updateJson(tree, 'package.json', (packageJson) => ({\n ...packageJson,\n type: 'module',\n scripts: {\n ...packageJson.scripts,\n dev: 'nx run-many --target dev',\n build: 'nx run-many --target build',\n lint: 'nx run-many --target lint --configuration=fix',\n test: 'nx run-many --target test --all',\n 'build:skip-lint': 'nx run-many --target build --configuration=skip-lint',\n 'build:all': 'nx run-many --target build --all',\n 'affected:all': 'nx affected --target build',\n },\n }));\n\n addDependenciesToPackageJson(\n tree,\n {},\n {\n '@nx/workspace': readModulePackageJson('@nx/js').packageJson.version,\n ...withVersions(['typescript', '@biomejs/biome']),\n },\n );\n\n // Write biome.json for formatting and linting\n if (!tree.exists('biome.json')) {\n tree.write('biome.json', JSON.stringify(DEFAULT_BIOME_CONFIG, null, 2));\n }\n\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, 'files'),\n '.',\n {\n projectName: getNpmScope(tree),\n generators: Object.entries(GeneratorsJson.generators)\n .filter(([_, v]) => !v['hidden'])\n .map(([k, v]) => ({ name: k, description: v.description })),\n ...(() => {\n const cmds = getPackageManagerDisplayCommands();\n return {\n pkgMgrCmd: cmds.exec,\n buildCmd: `${cmds.run} build`,\n lintCmd: `${cmds.run} lint`,\n };\n })(),\n },\n {\n overwriteStrategy: OverwriteStrategy.Overwrite,\n },\n );\n\n if (gitSecrets !== false) {\n setUpGitSecrets(tree);\n }\n\n if (mcp !== false) {\n configureMcpServers(tree);\n }\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\nexport default presetGenerator;\n"],"names":["addDependenciesToPackageJson","detectPackageManager","generateFiles","joinPathFragments","OverwriteStrategy","readNxJson","updateJson","updateNxJson","initGenerator","execSync","enquirer","readFileSync","yaml","readModulePackageJson","GeneratorsJson","type","SYNC_GENERATOR_NAME","TS_SYNC_GENERATOR_NAME","ensureAwsNxPluginConfig","updateAwsNxPluginConfig","inferContainers","DEFAULT_BIOME_CONFIG","formatFilesInSubtree","installDependencies","configureMcpServers","getNpmScope","getGeneratorInfo","getPackageManagerDisplayCommands","withVersions","WORKSPACES","NX_TYPESCRIPT_SYNC_GENERATOR","PNPM_BUILT_DEPENDENCIES","PRESET_GENERATOR_INFO","filename","setUpWorkspaces","tree","write","dump","packages","allowBuilds","Object","fromEntries","map","dep","onlyBuiltDependencies","quotingType","json","workspaces","isAmazonian","gitEmail","encoding","trim","emailParts","split","length","domain","toLowerCase","startsWith","error","setUpGitSecrets","gitSecretsDir","dirname","huskyDir","scripts","prepare","presetGenerator","iac","gitSecrets","mcp","containers","preferInstallDependencies","resolvedContainers","process","env","VITEST","CI","NX_DRY_RUN","NX_INTERACTIVE","engagementId","prompt","name","message","initial","tags","provider","engine","formatter","addTsPlugin","delete","nxJson","analytics","targetDefaults","compile","syncGenerators","filter","g","includes","packageJson","dev","build","lint","test","version","exists","JSON","stringify","projectName","generators","entries","_","v","k","description","cmds","pkgMgrCmd","exec","buildCmd","run","lintCmd","overwriteStrategy","Overwrite","languages"],"mappings":"AAAA;;;CAGC,GACD,SACEA,4BAA4B,EAC5BC,oBAAoB,EAEpBC,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EACjBC,UAAU,EAEVC,UAAU,EACVC,YAAY,QACP,aAAa;AACpB,SAASC,aAAa,QAAQ,SAAS;AACvC,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,YAAYC,cAAc,WAAW;AACrC,SAASC,YAAY,QAAQ,KAAK;AAClC,OAAOC,UAAU,UAAU;AAC3B,SAASC,qBAAqB,QAAQ,4BAA4B;AAClE,OAAOC,oBAAoB,6BAA6B;IAAEC,MAAM;AAAO,EAAE;AACzE,SAASC,uBAAuBC,sBAAsB,QAAQ,0BAAuB;AACrF,SACEC,uBAAuB,EACvBC,uBAAuB,QAClB,2BAAwB;AAC/B,SAASC,eAAe,QAAQ,yBAAsB;AACtD,SAASC,oBAAoB,EAAEC,oBAAoB,QAAQ,qBAAkB;AAC7E,SAASC,mBAAmB,QAAQ,sBAAmB;AACvD,SAASC,mBAAmB,QAAQ,kBAAe;AAEnD,SAASC,WAAW,QAAQ,wBAAqB;AACjD,SAASC,gBAAgB,QAA8B,iBAAc;AACrE,SAASC,gCAAgC,QAAQ,0BAAuB;AACxE,SAASC,YAAY,QAAQ,uBAAoB;AAGjD,MAAMC,aAAa;IAAC;CAAa;AACjC,MAAMC,+BAA+B;AAErC,2EAA2E;AAC3E,4EAA4E;AAC5E,0EAA0E;AAC1E,uEAAuE;AACvE,0EAA0E;AAC1E,MAAMC,0BAA0B;IAAC;IAAa;IAAW;IAAM;CAAQ;AAEvE,OAAO,MAAMC,wBAAyCN,iBACpD,YAAYO,QAAQ,EACpB;AAEF,MAAMC,kBAAkB,CAACC;IACvB,IAAIlC,2BAA2B,QAAQ;QACrCkC,KAAKC,KAAK,CACR,uBACAxB,KAAKyB,IAAI,CACP;YACEC,UAAUT;YACVU,aAAaC,OAAOC,WAAW,CAC7BV,wBAAwBW,GAAG,CAAC,CAACC,MAAQ;oBAACA;oBAAK;iBAAK;YAElDC,uBAAuBb;QACzB,GACA;YAAEc,aAAa;QAAI;IAGzB,OAAO;QACLvC,WAAW6B,MAAM,gBAAgB,CAACW;YAChCA,KAAKC,UAAU,GAAGlB;YAClB,OAAOiB;QACT;IACF;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,SAASE;IACd,IAAI;QACF,sEAAsE;QACtE,MAAMC,WAAWxC,SAAS,yBAAyB;YACjDyC,UAAU;QACZ,GAAGC,IAAI;QAEP,yCAAyC;QACzC,IAAI,CAACF,UAAU;YACb,OAAO;QACT;QAEA,6CAA6C;QAC7C,MAAMG,aAAaH,SAASI,KAAK,CAAC;QAClC,IAAID,WAAWE,MAAM,GAAG,GAAG;YACzB,OAAO;QACT;QAEA,2DAA2D;QAC3D,MAAMC,SAASH,UAAU,CAAC,EAAE,CAACI,WAAW;QAExC,gFAAgF;QAChF,OAAOD,OAAOE,UAAU,CAAC;IAC3B,EAAE,OAAOC,OAAO;QACd,8DAA8D;QAC9D,8DAA8D;QAC9D,OAAO;IACT;AACF;AAEA,MAAMC,kBAAkB,CAACxB;IACvB,MAAMyB,gBAAgBzD,kBACpB,YAAY0D,OAAO,EACnB,qBACA;IAEF,MAAMC,WAAW3D,kBACf,YAAY0D,OAAO,EACnB,qBACA;IAGF1B,KAAKC,KAAK,CACR,4BACAzB,aAAaR,kBAAkByD,eAAe,gBAAgB;IAEhEzB,KAAKC,KAAK,CACR,qBACAzB,aAAaR,kBAAkB2D,UAAU,eAAe;IAE1D3B,KAAKC,KAAK,CAAC,eAAe;IAE1B9B,WAAW6B,MAAM,gBAAgB,CAACW,OAAU,CAAA;YAC1C,GAAGA,IAAI;YACPiB,SAAS;gBACP,GAAGjB,KAAKiB,OAAO;gBACfC,SAAS;YACX;QACF,CAAA;IAEAhE,6BAA6BmC,MAAM,CAAC,GAAGP,aAAa;QAAC;KAAQ;AAC/D;AAEA,OAAO,MAAMqC,kBAAkB,OAC7B9B,MACA,EACE+B,GAAG,EACHC,UAAU,EACVC,GAAG,EACHC,UAAU,EACVC,yBAAyB,EACH;IAExB,MAAMC,qBACJ,CAACF,cAAcA,eAAe,UAAUjD,oBAAoBiD;IAC9D,IACErB,iBACA,CAACwB,QAAQC,GAAG,CAACC,MAAM,IACnB,CAACF,QAAQC,GAAG,CAACE,EAAE,IACfH,QAAQC,GAAG,CAACG,UAAU,KAAK,UAC3BJ,QAAQC,GAAG,CAACI,cAAc,KAAK,SAC/B;QACA,MAAM,EAAEC,YAAY,EAAE,GAAG,MAAMpE,SAASqE,MAAM,CAA4B;YACxE;gBACEC,MAAM;gBACNC,SAAS;gBACTlE,MAAM;gBACNmE,SAAS;YACX;SACD;QAED,IAAIJ,gBAAgB,QAAQ;YAC1B,MAAM5D,wBAAwBiB;YAC9B,MAAMhB,wBAAwBgB,MAAM;gBAAEgD,MAAM;oBAACL;iBAAa;YAAC;QAC7D;IACF;IAEA,2DAA2D;IAC3D,MAAM5D,wBAAwBiB;IAC9B,MAAMhB,wBAAwBgB,MAAM;QAClC+B,KAAK;YAAEkB,UAAUlB;QAAI;QACrBG,YAAY;YAAEgB,QAAQd;QAAmB;IAC3C;IAEA,MAAM/D,cAAc2B,MAAM;QACxBmD,WAAW;QACXC,aAAa;IACf;IAEApD,KAAKqD,MAAM,CAAC;IACZrD,KAAKqD,MAAM,CAAC;IACZrD,KAAKC,KAAK,CAAC,qBAAqB;IAEhCF,gBAAgBC;IAEhB,MAAMsD,SAASpF,WAAW8B;IAC1B5B,aAAa4B,MAAM;QACjB,GAAGsD,MAAM;QACTC,WAAW;QACXC,gBAAgB;YACd,GAAGF,OAAOE,cAAc;YACxBC,SAAS;gBACP,GAAGH,OAAOE,cAAc,EAAEC,OAAO;gBACjCC,gBAAgB;uBACX,AAACJ,CAAAA,OAAOE,cAAc,EAAEC,SAASC,kBAAkB,EAAE,AAAD,EAAGC,MAAM,CAC9D,CAACC,IACC,CAAC;4BAAC9E;4BAAwBa;yBAA6B,CAACkE,QAAQ,CAC9DD;oBAGNjE;oBACAb;iBACD;YACH;QACF;IACF;IAEAX,WAAW6B,MAAM,gBAAgB,CAAC8D,cAAiB,CAAA;YACjD,GAAGA,WAAW;YACdlF,MAAM;YACNgD,SAAS;gBACP,GAAGkC,YAAYlC,OAAO;gBACtBmC,KAAK;gBACLC,OAAO;gBACPC,MAAM;gBACNC,MAAM;gBACN,mBAAmB;gBACnB,aAAa;gBACb,gBAAgB;YAClB;QACF,CAAA;IAEArG,6BACEmC,MACA,CAAC,GACD;QACE,iBAAiBtB,sBAAsB,UAAUoF,WAAW,CAACK,OAAO;QACpE,GAAG1E,aAAa;YAAC;YAAc;SAAiB,CAAC;IACnD;IAGF,8CAA8C;IAC9C,IAAI,CAACO,KAAKoE,MAAM,CAAC,eAAe;QAC9BpE,KAAKC,KAAK,CAAC,cAAcoE,KAAKC,SAAS,CAACpF,sBAAsB,MAAM;IACtE;IAEAnB,cACEiC,MACAhC,kBAAkB,YAAY0D,OAAO,EAAE,UACvC,KACA;QACE6C,aAAajF,YAAYU;QACzBwE,YAAYnE,OAAOoE,OAAO,CAAC9F,eAAe6F,UAAU,EACjDb,MAAM,CAAC,CAAC,CAACe,GAAGC,EAAE,GAAK,CAACA,CAAC,CAAC,SAAS,EAC/BpE,GAAG,CAAC,CAAC,CAACqE,GAAGD,EAAE,GAAM,CAAA;gBAAE9B,MAAM+B;gBAAGC,aAAaF,EAAEE,WAAW;YAAC,CAAA;QAC1D,GAAG,AAAC,CAAA;YACF,MAAMC,OAAOtF;YACb,OAAO;gBACLuF,WAAWD,KAAKE,IAAI;gBACpBC,UAAU,GAAGH,KAAKI,GAAG,CAAC,MAAM,CAAC;gBAC7BC,SAAS,GAAGL,KAAKI,GAAG,CAAC,KAAK,CAAC;YAC7B;QACF,CAAA,GAAI;IACN,GACA;QACEE,mBAAmBnH,kBAAkBoH,SAAS;IAChD;IAGF,IAAIrD,eAAe,OAAO;QACxBR,gBAAgBxB;IAClB;IAEA,IAAIiC,QAAQ,OAAO;QACjB5C,oBAAoBW;IACtB;IAEA,MAAMb,qBAAqBa;IAC3B,OAAO,IACLZ,oBAAoBY,MAAMmC,2BAA2B;YACnDmD,WAAW;gBAAC;aAAa;QAC3B;AACJ,EAAE;AAEF,eAAexD,gBAAgB"}
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/preset/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addDependenciesToPackageJson,\n detectPackageManager,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n readNxJson,\n type Tree,\n updateJson,\n updateNxJson,\n} from '@nx/devkit';\nimport { initGenerator } from '@nx/js';\nimport { execSync } from 'child_process';\nimport enquirer from 'enquirer';\nimport { readFileSync } from 'fs';\nimport yaml from 'js-yaml';\nimport { readModulePackageJson } from 'nx/src/utils/package-json';\nimport GeneratorsJson from '../../generators.json' with { type: 'json' };\nimport { SYNC_GENERATOR_NAME as TS_SYNC_GENERATOR_NAME } from '../ts/sync/generator';\nimport {\n ensureAwsNxPluginConfig,\n updateAwsNxPluginConfig,\n} from '../utils/config/utils';\nimport { inferContainers } from '../utils/containers';\nimport { DEFAULT_BIOME_CONFIG, formatFilesInSubtree } from '../utils/format';\nimport { installDependencies } from '../utils/install';\nimport { configureMcpServers } from '../utils/mcp';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics';\nimport { getNpmScope } from '../utils/npm-scope';\nimport { getGeneratorInfo, type NxGeneratorInfo } from '../utils/nx';\nimport { getPackageManagerDisplayCommands } from '../utils/pkg-manager';\nimport { withVersions } from '../utils/versions';\nimport type { PresetGeneratorSchema } from './schema';\n\nconst WORKSPACES = ['packages/*'];\nconst NX_TYPESCRIPT_SYNC_GENERATOR = '@nx/js:typescript-sync';\n\n// Built dependencies whose install scripts the generated workspace trusts.\n// `onlyBuiltDependencies` is the pnpm 10 key (silently ignored by pnpm 11);\n// pnpm 11 reads `allowBuilds` instead. Any dep NOT in this allowlist will\n// have its install scripts skipped with a warning — matching pnpm 10's\n// default behaviour. The user can opt-in later via `pnpm approve-builds`.\nconst PNPM_BUILT_DEPENDENCIES = ['@swc/core', 'esbuild', 'nx', 'sharp'];\n\nexport const PRESET_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nconst setUpWorkspaces = (tree: Tree) => {\n if (detectPackageManager() === 'pnpm') {\n tree.write(\n 'pnpm-workspace.yaml',\n yaml.dump(\n {\n packages: WORKSPACES,\n allowBuilds: Object.fromEntries(\n PNPM_BUILT_DEPENDENCIES.map((dep) => [dep, true]),\n ),\n onlyBuiltDependencies: PNPM_BUILT_DEPENDENCIES,\n },\n { quotingType: \"'\" },\n ),\n );\n } else {\n updateJson(tree, 'package.json', (json) => {\n json.workspaces = WORKSPACES;\n return json;\n });\n }\n};\n\n/**\n * Determines if the current user is an Amazon employee based on their git configuration.\n *\n * This function checks the git user email configuration to identify Amazon employees\n * by looking for email addresses with Amazon domains (e.g., @amazon.com, @amazon.co.uk).\n *\n * @returns {boolean} True if the user's git email has an Amazon domain, false otherwise\n *\n * @example\n * // Returns true for Amazon employee emails\n * // git config user.email = \"john.doe@amazon.com\"\n * isAmazonian(); // true\n *\n * @example\n * // Returns false for non-Amazon emails\n * // git config user.email = \"user@example.com\"\n * isAmazonian(); // false\n *\n * @example\n * // Returns false when git config is not available or throws an error\n * isAmazonian(); // false\n */\nexport function isAmazonian(): boolean {\n try {\n // Execute git command to retrieve the user's configured email address\n const gitEmail = execSync('git config user.email', {\n encoding: 'utf8',\n }).trim();\n\n // Return false if no email is configured\n if (!gitEmail) {\n return false;\n }\n\n // Split email address to extract domain part\n const emailParts = gitEmail.split('@');\n if (emailParts.length < 2) {\n return false;\n }\n\n // Extract domain and normalize to lowercase for comparison\n const domain = emailParts[1].toLowerCase();\n\n // Check if domain starts with 'amazon.' (covers amazon.com, amazon.co.uk, etc.)\n return domain.startsWith('amazon.');\n } catch (error) {\n // Return false if git command fails or any other error occurs\n // This handles cases where git is not installed or configured\n return false;\n }\n}\n\nconst setUpGitSecrets = (tree: Tree) => {\n const gitSecretsDir = joinPathFragments(\n import.meta.dirname,\n 'git-secrets-files',\n 'git-secrets-dir',\n );\n const huskyDir = joinPathFragments(\n import.meta.dirname,\n 'git-secrets-files',\n 'husky-dir',\n );\n\n tree.write(\n '.git-secrets/git-secrets',\n readFileSync(joinPathFragments(gitSecretsDir, 'git-secrets'), 'utf-8'),\n );\n tree.write(\n '.husky/pre-commit',\n readFileSync(joinPathFragments(huskyDir, 'pre-commit'), 'utf-8'),\n );\n tree.write('.gitallowed', '\\\\.git-secrets/git-secrets:\\n');\n\n updateJson(tree, 'package.json', (json) => ({\n ...json,\n scripts: {\n ...json.scripts,\n prepare: 'husky',\n },\n }));\n\n addDependenciesToPackageJson(tree, {}, withVersions(['husky']));\n};\n\nexport const presetGenerator = async (\n tree: Tree,\n {\n iac,\n gitSecrets,\n mcp,\n containers,\n preferInstallDependencies,\n }: PresetGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const resolvedContainers =\n !containers || containers === 'infer' ? inferContainers() : containers;\n if (\n isAmazonian() &&\n !process.env.VITEST &&\n !process.env.CI &&\n process.env.NX_DRY_RUN !== 'true' &&\n process.env.NX_INTERACTIVE !== 'false'\n ) {\n const { engagementId } = await enquirer.prompt<{ engagementId?: string }>([\n {\n name: 'engagementId',\n message: 'Please enter your engagementId (if known)',\n type: 'input',\n initial: 'None',\n },\n ]);\n\n if (engagementId != 'None') {\n await ensureAwsNxPluginConfig(tree);\n await updateAwsNxPluginConfig(tree, { tags: [engagementId] });\n }\n }\n\n // Write IaC provider and container engine to plugin config\n await ensureAwsNxPluginConfig(tree);\n await updateAwsNxPluginConfig(tree, {\n iac: { provider: iac },\n containers: { engine: resolvedContainers },\n });\n\n await initGenerator(tree, {\n formatter: 'none',\n addTsPlugin: true,\n });\n\n tree.delete('apps/.gitkeep');\n tree.delete('libs/.gitkeep');\n tree.write('packages/.gitkeep', '');\n\n setUpWorkspaces(tree);\n\n const nxJson = readNxJson(tree);\n updateNxJson(tree, {\n ...nxJson,\n analytics: false,\n targetDefaults: {\n ...nxJson.targetDefaults,\n compile: {\n ...nxJson.targetDefaults?.compile,\n syncGenerators: [\n ...(nxJson.targetDefaults?.compile?.syncGenerators ?? []).filter(\n (g) =>\n ![TS_SYNC_GENERATOR_NAME, NX_TYPESCRIPT_SYNC_GENERATOR].includes(\n g,\n ),\n ),\n NX_TYPESCRIPT_SYNC_GENERATOR,\n TS_SYNC_GENERATOR_NAME,\n ],\n },\n },\n });\n\n updateJson(tree, 'package.json', (packageJson) => ({\n ...packageJson,\n type: 'module',\n scripts: {\n ...packageJson.scripts,\n dev: 'nx run-many --target dev',\n build: 'nx run-many --target build',\n lint: 'nx run-many --target lint --configuration=fix',\n test: 'nx run-many --target test --all',\n 'build:skip-lint': 'nx run-many --target build --configuration=skip-lint',\n 'build:all': 'nx run-many --target build --all',\n 'affected:all': 'nx affected --target build',\n },\n }));\n\n addDependenciesToPackageJson(\n tree,\n {},\n {\n '@nx/workspace': readModulePackageJson('@nx/js').packageJson.version,\n ...withVersions(['typescript', '@biomejs/biome']),\n },\n );\n\n // Write biome.json for formatting and linting\n if (!tree.exists('biome.json')) {\n tree.write('biome.json', JSON.stringify(DEFAULT_BIOME_CONFIG, null, 2));\n }\n\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, 'files'),\n '.',\n {\n projectName: getNpmScope(tree),\n generators: Object.entries(GeneratorsJson.generators)\n .filter(([_, v]) => !v['hidden'])\n .map(([k, v]) => ({ name: k, description: v.description })),\n ...(() => {\n const cmds = getPackageManagerDisplayCommands();\n return {\n pkgMgrCmd: cmds.exec,\n buildCmd: `${cmds.run} build`,\n lintCmd: `${cmds.run} lint`,\n };\n })(),\n },\n {\n overwriteStrategy: OverwriteStrategy.Overwrite,\n },\n );\n\n if (gitSecrets !== false) {\n setUpGitSecrets(tree);\n }\n\n if (mcp !== false) {\n configureMcpServers(tree);\n }\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\nexport default presetGenerator;\n"],"names":["addDependenciesToPackageJson","detectPackageManager","generateFiles","joinPathFragments","OverwriteStrategy","readNxJson","updateJson","updateNxJson","initGenerator","execSync","enquirer","readFileSync","yaml","readModulePackageJson","GeneratorsJson","type","SYNC_GENERATOR_NAME","TS_SYNC_GENERATOR_NAME","ensureAwsNxPluginConfig","updateAwsNxPluginConfig","inferContainers","DEFAULT_BIOME_CONFIG","formatFilesInSubtree","installDependencies","configureMcpServers","getNpmScope","getGeneratorInfo","getPackageManagerDisplayCommands","withVersions","WORKSPACES","NX_TYPESCRIPT_SYNC_GENERATOR","PNPM_BUILT_DEPENDENCIES","PRESET_GENERATOR_INFO","filename","setUpWorkspaces","tree","write","dump","packages","allowBuilds","Object","fromEntries","map","dep","onlyBuiltDependencies","quotingType","json","workspaces","isAmazonian","gitEmail","encoding","trim","emailParts","split","length","domain","toLowerCase","startsWith","error","setUpGitSecrets","gitSecretsDir","dirname","huskyDir","scripts","prepare","presetGenerator","iac","gitSecrets","mcp","containers","preferInstallDependencies","resolvedContainers","process","env","VITEST","CI","NX_DRY_RUN","NX_INTERACTIVE","engagementId","prompt","name","message","initial","tags","provider","engine","formatter","addTsPlugin","delete","nxJson","analytics","targetDefaults","compile","syncGenerators","filter","g","includes","packageJson","dev","build","lint","test","version","exists","JSON","stringify","projectName","generators","entries","_","v","k","description","cmds","pkgMgrCmd","exec","buildCmd","run","lintCmd","overwriteStrategy","Overwrite","languages"],"mappings":"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"}
|
|
@@ -552,6 +552,7 @@ resource "aws_cloudfront_response_headers_policy" "website" {
|
|
|
552
552
|
|
|
553
553
|
# CloudFront Distribution
|
|
554
554
|
resource "aws_cloudfront_distribution" "website" {
|
|
555
|
+
# See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistValuesGeneral.html
|
|
555
556
|
#checkov:skip=CKV_AWS_174:Using CloudFront default certificate which does not support TLS v1.2
|
|
556
557
|
#checkov:skip=CKV_AWS_310:Origin failover not required for single S3 origin static website
|
|
557
558
|
#checkov:skip=CKV_AWS_374:Geo restrictions not required for global web application
|
|
@@ -1731,6 +1732,7 @@ export class StaticWebsite extends Construct {
|
|
|
1731
1732
|
],
|
|
1732
1733
|
},
|
|
1733
1734
|
);
|
|
1735
|
+
// See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistValuesGeneral.html
|
|
1734
1736
|
suppressRules(
|
|
1735
1737
|
this.cloudFrontDistribution,
|
|
1736
1738
|
['CKV_AWS_174'],
|
|
@@ -3306,6 +3308,7 @@ export class StaticWebsite extends Construct {
|
|
|
3306
3308
|
],
|
|
3307
3309
|
},
|
|
3308
3310
|
);
|
|
3311
|
+
// See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistValuesGeneral.html
|
|
3309
3312
|
suppressRules(
|
|
3310
3313
|
this.cloudFrontDistribution,
|
|
3311
3314
|
['CKV_AWS_174'],
|
|
@@ -4808,6 +4811,7 @@ export class StaticWebsite extends Construct {
|
|
|
4808
4811
|
],
|
|
4809
4812
|
},
|
|
4810
4813
|
);
|
|
4814
|
+
// See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistValuesGeneral.html
|
|
4811
4815
|
suppressRules(
|
|
4812
4816
|
this.cloudFrontDistribution,
|
|
4813
4817
|
['CKV_AWS_174'],
|
|
@@ -3,12 +3,21 @@ import { Construct } from 'constructs';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import * as url from 'node:url';
|
|
5
5
|
<%_ } _%>
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
AgentCoreGateway,
|
|
8
|
+
AgentCoreGatewayProps,
|
|
9
|
+
} from '../../../core/agentcore-gateway/agentcore-gateway.js';
|
|
7
10
|
import { RuntimeConfig } from '../../../core/runtime-config.js';
|
|
8
11
|
<%_ if (cedarPolicy) { _%>
|
|
9
12
|
import { findWorkspaceRoot } from '../../../core/workspace.js';
|
|
10
13
|
<%_ } _%>
|
|
11
14
|
|
|
15
|
+
<%_ if (cedarPolicy) { _%>
|
|
16
|
+
export type <%- nameClassName %>Props = Omit<AgentCoreGatewayProps, 'cedarPolicyPath'>;
|
|
17
|
+
<%_ } else { _%>
|
|
18
|
+
export type <%- nameClassName %>Props = AgentCoreGatewayProps;
|
|
19
|
+
<%_ } _%>
|
|
20
|
+
|
|
12
21
|
/**
|
|
13
22
|
* AgentCore Gateway wired for MCP protocol with IAM inbound auth.
|
|
14
23
|
<%_ if (cedarPolicy) { _%>
|
|
@@ -21,7 +30,7 @@ export class <%- nameClassName %> extends AgentCoreGateway {
|
|
|
21
30
|
/** Default Gateway target name when added to another Gateway. */
|
|
22
31
|
public readonly gatewayName = '<%- nameKebabCase %>';
|
|
23
32
|
|
|
24
|
-
constructor(scope: Construct, id: string) {
|
|
33
|
+
constructor(scope: Construct, id: string, props?: <%- nameClassName %>Props) {
|
|
25
34
|
super(scope, id, {
|
|
26
35
|
<%_ if (cedarPolicy) { _%>
|
|
27
36
|
cedarPolicyPath: path.join(
|
|
@@ -29,6 +38,7 @@ export class <%- nameClassName %> extends AgentCoreGateway {
|
|
|
29
38
|
'<%- projectDirectory %>/policies',
|
|
30
39
|
),
|
|
31
40
|
<%_ } _%>
|
|
41
|
+
...props,
|
|
32
42
|
});
|
|
33
43
|
|
|
34
44
|
const rc = RuntimeConfig.ensure(this);
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as cdk from 'aws-cdk-lib';
|
|
2
2
|
import * as agentcore from 'aws-cdk-lib/aws-bedrockagentcore';
|
|
3
3
|
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
4
|
+
import * as kms from 'aws-cdk-lib/aws-kms';
|
|
4
5
|
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
6
|
+
import * as logs from 'aws-cdk-lib/aws-logs';
|
|
5
7
|
import * as triggers from 'aws-cdk-lib/triggers';
|
|
8
|
+
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
|
|
6
9
|
import { Construct } from 'constructs';
|
|
7
10
|
import ejs from 'ejs';
|
|
8
11
|
import * as fs from 'node:fs';
|
|
@@ -24,6 +27,13 @@ export interface AgentCoreGatewayProps {
|
|
|
24
27
|
* Additional variables available to the Cedar policy EJS templates.
|
|
25
28
|
*/
|
|
26
29
|
readonly cedarPolicyVariables?: Record<string, string>;
|
|
30
|
+
/**
|
|
31
|
+
* Associate a regional WAFv2 web ACL (default AWS managed rule groups) with
|
|
32
|
+
* the gateway to inspect inbound requests.
|
|
33
|
+
*
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
readonly enableWaf?: boolean;
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
/**
|
|
@@ -33,6 +43,8 @@ export interface AgentCoreGatewayProps {
|
|
|
33
43
|
export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
34
44
|
public readonly gateway: agentcore.Gateway;
|
|
35
45
|
public readonly policyEngine?: agentcore.CfnPolicyEngine;
|
|
46
|
+
/** The WAFv2 web ACL associated with the gateway, if WAF is enabled. */
|
|
47
|
+
public readonly webAcl?: wafv2.CfnWebACL;
|
|
36
48
|
private readonly policies: agentcore.CfnPolicy[] = [];
|
|
37
49
|
private targetReadinessProbe?: triggers.TriggerFunction;
|
|
38
50
|
private readonly targetRuntimeArns: string[] = [];
|
|
@@ -41,6 +53,9 @@ export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
|
41
53
|
super(scope, id);
|
|
42
54
|
|
|
43
55
|
this.gateway = new agentcore.Gateway(this, 'Gateway', {
|
|
56
|
+
// Cap at 39 chars so the 11-char service suffix keeps the gateway id
|
|
57
|
+
// within its 50-char limit.
|
|
58
|
+
gatewayName: cdk.Names.uniqueResourceName(this, { maxLength: 39 }),
|
|
44
59
|
protocolConfiguration: new agentcore.McpProtocolConfiguration({
|
|
45
60
|
searchType: agentcore.McpGatewaySearchType.SEMANTIC,
|
|
46
61
|
supportedVersions: [agentcore.MCPProtocolVersion.MCP_2025_03_26],
|
|
@@ -128,6 +143,103 @@ export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
|
128
143
|
}
|
|
129
144
|
}
|
|
130
145
|
}
|
|
146
|
+
|
|
147
|
+
if (props?.enableWaf ?? true) {
|
|
148
|
+
this.webAcl = this.createWebAcl();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Create a regional WAFv2 web ACL with the default AWS managed rule groups,
|
|
154
|
+
* associate it with the gateway, and log requests to CloudWatch.
|
|
155
|
+
*/
|
|
156
|
+
private createWebAcl(): wafv2.CfnWebACL {
|
|
157
|
+
const metricPrefix = cdk.Names.uniqueResourceName(this, { maxLength: 40 });
|
|
158
|
+
|
|
159
|
+
const webAcl = new wafv2.CfnWebACL(this, 'WebAcl', {
|
|
160
|
+
defaultAction: { allow: {} },
|
|
161
|
+
// AgentCore Gateway requires a REGIONAL web ACL; CloudFront (global) is
|
|
162
|
+
// not supported.
|
|
163
|
+
scope: 'REGIONAL',
|
|
164
|
+
visibilityConfig: {
|
|
165
|
+
cloudWatchMetricsEnabled: true,
|
|
166
|
+
metricName: `${metricPrefix}WebAcl`,
|
|
167
|
+
sampledRequestsEnabled: true,
|
|
168
|
+
},
|
|
169
|
+
rules: [
|
|
170
|
+
{
|
|
171
|
+
name: 'CRSRule',
|
|
172
|
+
priority: 0,
|
|
173
|
+
statement: {
|
|
174
|
+
managedRuleGroupStatement: {
|
|
175
|
+
name: 'AWSManagedRulesCommonRuleSet',
|
|
176
|
+
vendorName: 'AWS',
|
|
177
|
+
// Count instead of Block: the CRS 8 KB body limit is too
|
|
178
|
+
// restrictive for typical MCP tool payloads.
|
|
179
|
+
ruleActionOverrides: [
|
|
180
|
+
{
|
|
181
|
+
name: 'SizeRestrictions_BODY',
|
|
182
|
+
actionToUse: { count: {} },
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
visibilityConfig: {
|
|
188
|
+
cloudWatchMetricsEnabled: true,
|
|
189
|
+
metricName: `${metricPrefix}WebAcl-CRS`,
|
|
190
|
+
sampledRequestsEnabled: true,
|
|
191
|
+
},
|
|
192
|
+
overrideAction: {
|
|
193
|
+
none: {},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: 'KnownBadInputsRule',
|
|
198
|
+
priority: 1,
|
|
199
|
+
statement: {
|
|
200
|
+
managedRuleGroupStatement: {
|
|
201
|
+
name: 'AWSManagedRulesKnownBadInputsRuleSet',
|
|
202
|
+
vendorName: 'AWS',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
visibilityConfig: {
|
|
206
|
+
cloudWatchMetricsEnabled: true,
|
|
207
|
+
metricName: `${metricPrefix}WebAcl-KnownBadInputs`,
|
|
208
|
+
sampledRequestsEnabled: true,
|
|
209
|
+
},
|
|
210
|
+
overrideAction: {
|
|
211
|
+
none: {},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
new wafv2.CfnWebACLAssociation(this, 'WebAclAssociation', {
|
|
218
|
+
resourceArn: this.gateway.gatewayArn,
|
|
219
|
+
webAclArn: webAcl.attrArn,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// WAFv2 logging destination requires the `aws-waf-logs-` name prefix.
|
|
223
|
+
const logsKey = new kms.Key(this, 'WebAclLogsKey', {
|
|
224
|
+
enableKeyRotation: true,
|
|
225
|
+
});
|
|
226
|
+
logsKey.grantEncryptDecrypt(
|
|
227
|
+
new iam.ServicePrincipal(
|
|
228
|
+
`logs.${cdk.Stack.of(this).region}.amazonaws.com`,
|
|
229
|
+
),
|
|
230
|
+
);
|
|
231
|
+
const wafLogGroup = new logs.LogGroup(this, 'WebAclLogs', {
|
|
232
|
+
logGroupName: `aws-waf-logs-${metricPrefix}-${this.node.addr.slice(-8)}`,
|
|
233
|
+
retention: logs.RetentionDays.ONE_YEAR,
|
|
234
|
+
encryptionKey: logsKey,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
new wafv2.CfnLoggingConfiguration(this, 'WebAclLoggingConfig', {
|
|
238
|
+
resourceArn: webAcl.attrArn,
|
|
239
|
+
logDestinationConfigs: [wafLogGroup.logGroupArn],
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return webAcl;
|
|
131
243
|
}
|
|
132
244
|
|
|
133
245
|
/**
|
|
@@ -34,6 +34,12 @@ variable "tool_dependencies" {
|
|
|
34
34
|
type = list(string)
|
|
35
35
|
default = []
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
variable "enable_waf" {
|
|
39
|
+
description = "Associate a regional WAFv2 web ACL (default AWS managed rule groups) with the gateway to inspect inbound requests."
|
|
40
|
+
type = bool
|
|
41
|
+
default = true
|
|
42
|
+
}
|
|
37
43
|
<%_ if (cedarPolicy) { _%>
|
|
38
44
|
|
|
39
45
|
variable "policy_dependencies" {
|
|
@@ -141,7 +147,9 @@ resource "aws_bedrockagentcore_policy_engine" "this" {
|
|
|
141
147
|
<%_ } _%>
|
|
142
148
|
|
|
143
149
|
resource "aws_bedrockagentcore_gateway" "this" {
|
|
144
|
-
name
|
|
150
|
+
# Cap the name so the 11-char service suffix keeps the gateway id within its
|
|
151
|
+
# 50-char limit (30 prefix + "-<8 hex>" + 11 = 50).
|
|
152
|
+
name = "${substr("<%- nameClassName %>", 0, 30)}-${random_id.unique_suffix.hex}"
|
|
145
153
|
description = "AgentCore Gateway for <%- nameClassName %>"
|
|
146
154
|
role_arn = aws_iam_role.gateway_role.arn
|
|
147
155
|
|
|
@@ -164,6 +172,107 @@ resource "aws_bedrockagentcore_gateway" "this" {
|
|
|
164
172
|
depends_on = [aws_iam_role_policy.gateway_role_policy]
|
|
165
173
|
<%_ } _%>
|
|
166
174
|
}
|
|
175
|
+
|
|
176
|
+
# WAFv2 protection for the gateway. AgentCore Gateway requires a REGIONAL web
|
|
177
|
+
# ACL; CloudFront (global) is not supported.
|
|
178
|
+
resource "aws_wafv2_web_acl" "gateway_waf" {
|
|
179
|
+
#checkov:skip=CKV2_AWS_31:Logging configuration is defined below in aws_wafv2_web_acl_logging_configuration.gateway_waf_logging; Checkov does not resolve the separate resource
|
|
180
|
+
count = var.enable_waf ? 1 : 0
|
|
181
|
+
|
|
182
|
+
name = "<%- nameClassName %>-waf-${random_id.unique_suffix.hex}"
|
|
183
|
+
scope = "REGIONAL"
|
|
184
|
+
|
|
185
|
+
default_action {
|
|
186
|
+
allow {}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
rule {
|
|
190
|
+
name = "CRSRule"
|
|
191
|
+
priority = 0
|
|
192
|
+
|
|
193
|
+
override_action {
|
|
194
|
+
none {}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
statement {
|
|
198
|
+
managed_rule_group_statement {
|
|
199
|
+
name = "AWSManagedRulesCommonRuleSet"
|
|
200
|
+
vendor_name = "AWS"
|
|
201
|
+
|
|
202
|
+
# Count instead of Block: the CRS 8 KB body limit is too restrictive
|
|
203
|
+
# for typical MCP tool payloads.
|
|
204
|
+
rule_action_override {
|
|
205
|
+
name = "SizeRestrictions_BODY"
|
|
206
|
+
action_to_use {
|
|
207
|
+
count {}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
visibility_config {
|
|
214
|
+
cloudwatch_metrics_enabled = true
|
|
215
|
+
metric_name = "<%- nameClassName %>WebAcl-CRS"
|
|
216
|
+
sampled_requests_enabled = true
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
rule {
|
|
221
|
+
name = "KnownBadInputsRule"
|
|
222
|
+
priority = 1
|
|
223
|
+
|
|
224
|
+
override_action {
|
|
225
|
+
none {}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
statement {
|
|
229
|
+
managed_rule_group_statement {
|
|
230
|
+
name = "AWSManagedRulesKnownBadInputsRuleSet"
|
|
231
|
+
vendor_name = "AWS"
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
visibility_config {
|
|
236
|
+
cloudwatch_metrics_enabled = true
|
|
237
|
+
metric_name = "<%- nameClassName %>WebAcl-KnownBadInputs"
|
|
238
|
+
sampled_requests_enabled = true
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
visibility_config {
|
|
243
|
+
cloudwatch_metrics_enabled = true
|
|
244
|
+
metric_name = "<%- nameClassName %>WebAcl"
|
|
245
|
+
sampled_requests_enabled = true
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
lifecycle {
|
|
249
|
+
create_before_destroy = true
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
resource "aws_wafv2_web_acl_association" "gateway_waf" {
|
|
254
|
+
count = var.enable_waf ? 1 : 0
|
|
255
|
+
|
|
256
|
+
resource_arn = aws_bedrockagentcore_gateway.this.gateway_arn
|
|
257
|
+
web_acl_arn = aws_wafv2_web_acl.gateway_waf[0].arn
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
# WAF request logs. WAFv2 requires the `aws-waf-logs-` name prefix.
|
|
261
|
+
resource "aws_cloudwatch_log_group" "gateway_waf_logs" {
|
|
262
|
+
#checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
|
|
263
|
+
#checkov:skip=CKV_AWS_338:Log retention set to one year which is sufficient for WAF logs
|
|
264
|
+
count = var.enable_waf ? 1 : 0
|
|
265
|
+
|
|
266
|
+
name = "aws-waf-logs-<%- nameKebabCase %>-${random_id.unique_suffix.hex}"
|
|
267
|
+
retention_in_days = 365
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
resource "aws_wafv2_web_acl_logging_configuration" "gateway_waf_logging" {
|
|
271
|
+
count = var.enable_waf ? 1 : 0
|
|
272
|
+
|
|
273
|
+
log_destination_configs = [aws_cloudwatch_log_group.gateway_waf_logs[0].arn]
|
|
274
|
+
resource_arn = aws_wafv2_web_acl.gateway_waf[0].arn
|
|
275
|
+
}
|
|
167
276
|
<%_ if (cedarPolicy) { _%>
|
|
168
277
|
|
|
169
278
|
# Anchor for the policy_dependencies variable — depends_on only accepts
|
|
@@ -333,3 +442,8 @@ output "gateway_role_arn" {
|
|
|
333
442
|
description = "ARN of the IAM role assumed by the gateway service"
|
|
334
443
|
value = aws_iam_role.gateway_role.arn
|
|
335
444
|
}
|
|
445
|
+
|
|
446
|
+
output "waf_web_acl_arn" {
|
|
447
|
+
description = "ARN of the WAFv2 web ACL associated with the gateway, or null if WAF is disabled"
|
|
448
|
+
value = var.enable_waf ? aws_wafv2_web_acl.gateway_waf[0].arn : null
|
|
449
|
+
}
|
package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template
CHANGED
|
@@ -423,6 +423,7 @@ resource "aws_cloudfront_response_headers_policy" "website" {
|
|
|
423
423
|
|
|
424
424
|
# CloudFront Distribution
|
|
425
425
|
resource "aws_cloudfront_distribution" "website" {
|
|
426
|
+
# See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistValuesGeneral.html
|
|
426
427
|
#checkov:skip=CKV_AWS_174:Using CloudFront default certificate which does not support TLS v1.2
|
|
427
428
|
#checkov:skip=CKV_AWS_310:Origin failover not required for single S3 origin static website
|
|
428
429
|
#checkov:skip=CKV_AWS_374:Geo restrictions not required for global web application
|