diff --git a/.envrc b/.envrc index 6e96ed56..44c3c4c3 100644 --- a/.envrc +++ b/.envrc @@ -77,6 +77,7 @@ export DOCKER_BUILDKIT=1 # API_STACK__EKS__DEFAULT_SECRETS_ENCRYPTION # API_STACK__EKS__K8S__VERSION # API_STACK__EKS__PLATFORM_ARNS +# API_STACK__DATABASE__DATABASE_NAME # API_STACK__DATABASE__SNAPSHOT_IDENTIFIER # API_STACK__DATABASE__ENGINE_VERSION # API_STACK__DATABASE__IO_OPTIMIZED @@ -85,6 +86,7 @@ export DOCKER_BUILDKIT=1 # API_STACK__DATABASE__NUM_REPLICAS # API_STACK__DATABASE__NUM_REPLICAS_SCALED_WITH_WRITER # API_STACK__DATABASE__PERFORMANCE_INSIGHTS +# API_STACK__DATABASE__PERFORMANCE_INSIGHTS_RETENTION # API_STACK__DATABASE__CLOUDWATCH_LOGS_RETENTION_DAYS # API_STACK__DATABASE__DELETION_PROTECTION # API_STACK__DATABASE__BACKUP_RETENTION_DAYS @@ -92,6 +94,13 @@ export DOCKER_BUILDKIT=1 # API_STACK__NETWORK__MAX_AZS # API_STACK__NETWORK__NAT_GATEWAYS # API_STACK__NETWORK__CREATE_ISOLATED_SUBNET +# API_STACK__CACHE__ENABLED +# API_STACK__CACHE__NODE_TYPE +# API_STACK__CACHE__ENGINE_VERSION +# API_STACK__CACHE__NODES +# API_STACK__CACHE__REPLICAS +# API_STACK__CACHE__CLUSTER_MODE +# API_STACK__CACHE__MEMORY_AUTOSCALING_TARGET # API__CONFIG__CELERY__ALWAYS_EAGER # API__CONFIG__DJANGO__ACCOUNT_ALLOW_REGISTRATION # API__CONFIG__DJANGO__ALLOWED_HOSTS diff --git a/.nxignore b/.nxignore index c1c49fe1..25b1db98 100644 --- a/.nxignore +++ b/.nxignore @@ -2,3 +2,4 @@ .tmp .env .pytest_cache +**/cdk.out/** diff --git a/.projenrc.ts b/.projenrc.ts index 98a4b3cd..09255838 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -110,6 +110,7 @@ const monorepo = MonorepoBuilder.build({ }) monorepo.nx.useNxCloud(nxReadOnlyPublicToken) monorepo.nx.npmScope = '@crisiscleanup' +monorepo.nx.nxIgnore.addPatterns('**/cdk.out/**') const esmTsConfig = monorepo.tsconfigContainer.configs.get(TSConfig.ESM)! monorepo.tryRemoveFile(esmTsConfig.file.path) monorepo.tsconfigContainer.defineConfig(TSConfig.ESM, { @@ -469,6 +470,26 @@ stackPostCompile.spawn(apiStack.tasks.tryFind('synth:silent')!, { }) new Vitest(apiStack) +const maintenanceStack = AwsCdkTsAppBuilder.build({ + name: 'stacks.maintenance-site', + integrationTestAutoDiscover: true, + workspaceDeps: [config, ghPipelineConstruct], + deps: ['@aws-prototyping-sdk/static-website'], + jest: false, + prettier: true, +}) +maintenanceStack.addGitIgnore('cdk.context.json') +maintenanceStack.cdkConfig.json.addOverride( + 'app', + maintenanceStack.formatExecCommand('tsx', 'src/main.ts'), +) +const maintenancePostCompile = maintenanceStack.tasks.tryFind('post-compile')! +maintenancePostCompile.reset() +maintenancePostCompile.spawn(maintenanceStack.tasks.tryFind('synth:silent')!, { + condition: '[[ -z "$SKIP_SYNTH" ]] && [[ -n "$MAINTENANCE_SITE_SOURCE" ]]', +}) +new Vitest(maintenanceStack) + monorepo.addWorkspaceDeps( { depType: DependencyType.DEVENV, addTsPath: true }, crisiscleanup, diff --git a/package.json b/package.json index 8131d4fa..604cf88e 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,8 @@ "packages/construct/awscdk/github-pipeline", "packages/k8s/construct/api", "packages/k8s/construct/component", - "packages/stacks/api" + "packages/stacks/api", + "packages/stacks/maintenance-site" ] }, "packageManager": "pnpm@8.6.9", diff --git a/packages/stacks/maintenance-site/.eslintrc.json b/packages/stacks/maintenance-site/.eslintrc.json new file mode 100644 index 00000000..6a42e50b --- /dev/null +++ b/packages/stacks/maintenance-site/.eslintrc.json @@ -0,0 +1,231 @@ +// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +{ + "env": { + "jest": true, + "node": true + }, + "root": true, + "plugins": [ + "@typescript-eslint", + "import", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module", + "project": "./tsconfig.dev.json", + "tsconfigRootDir": "." + }, + "extends": [ + "plugin:import/typescript", + "prettier", + "plugin:prettier/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking" + ], + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [ + ".ts", + ".tsx" + ] + }, + "import/resolver": { + "node": { + "extensions": [ + ".js", + ".jsx", + ".mjs", + ".cjs", + ".ts", + ".tsx", + ".mts", + ".cts" + ] + }, + "typescript": { + "project": "./tsconfig.dev.json", + "alwaysTryTypes": true + } + }, + "import/extensions": [ + ".js", + ".jsx", + ".mjs", + ".cjs", + ".ts", + ".tsx", + ".mts", + ".cts" + ] + }, + "ignorePatterns": [ + "*.js", + "*.d.ts", + "node_modules/", + "*.generated.ts", + "coverage", + ".eslintrc.json", + ".gitattributes", + ".gitignore", + ".npmignore", + ".prettierignore", + ".prettierrc.json", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "cdk.json", + "LICENSE", + "project.json", + "tsconfig.dev.json", + "tsconfig.json", + ".eslintrc.json", + ".gitattributes", + ".gitignore", + ".npmignore", + ".prettierignore", + ".prettierrc.json", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "cdk.json", + "LICENSE", + "project.json", + "tsconfig.dev.json", + "tsconfig.json" + ], + "rules": { + "prettier/prettier": [ + "error" + ], + "@typescript-eslint/no-require-imports": [ + "error" + ], + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": [ + "**/test/**", + "**/build-tools/**" + ], + "optionalDependencies": false, + "peerDependencies": true + } + ], + "import/no-unresolved": [ + "error" + ], + "import/order": [ + "warn", + { + "groups": [ + "builtin", + "external" + ], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + } + } + ], + "no-duplicate-imports": [ + "error" + ], + "no-shadow": [ + "off" + ], + "@typescript-eslint/no-shadow": [ + "error" + ], + "key-spacing": [ + "off" + ], + "no-multiple-empty-lines": [ + "off" + ], + "@typescript-eslint/no-floating-promises": [ + "error" + ], + "no-return-await": [ + "off" + ], + "@typescript-eslint/return-await": [ + "error" + ], + "no-trailing-spaces": [ + "off" + ], + "dot-notation": [ + "error" + ], + "no-bitwise": [ + "error" + ], + "@typescript-eslint/member-ordering": [ + "error", + { + "default": [ + "public-static-field", + "public-static-method", + "protected-static-field", + "protected-static-method", + "private-static-field", + "private-static-method", + "field", + "constructor", + "method" + ] + } + ], + "@typescript-eslint/consistent-type-definitions": [ + "error", + "interface" + ], + "@typescript-eslint/consistent-type-imports": [ + "error", + { + "prefer": "type-imports", + "fixStyle": "inline-type-imports" + } + ], + "import/no-duplicates": [ + "error", + { + "prefer-inline": true + } + ] + }, + "overrides": [ + { + "files": [ + "test/**" + ], + "rules": { + "@typescript-eslint/require-await": [ + "warn" + ] + } + }, + { + "files": [ + "vitest.config.ts", + "test/**/*.spec.ts" + ], + "rules": { + "import/no-extraneous-dependencies": [ + "off" + ] + } + }, + { + "files": [ + "vitest.config.ts" + ], + "rules": { + "import/order": [ + "off" + ] + } + } + ] +} diff --git a/packages/stacks/maintenance-site/.gitattributes b/packages/stacks/maintenance-site/.gitattributes new file mode 100644 index 00000000..5db7e947 --- /dev/null +++ b/packages/stacks/maintenance-site/.gitattributes @@ -0,0 +1,21 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.eslintrc.json linguist-generated +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.npmignore linguist-generated +/.npmrc linguist-generated +/.prettierignore linguist-generated +/.prettierrc.json linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/cdk.json linguist-generated +/LICENSE linguist-generated +/package.json linguist-generated +/pnpm-lock.yaml linguist-generated +/project.json linguist-generated +/tsconfig.dev.json linguist-generated +/tsconfig.json linguist-generated +/vitest.config.ts linguist-generated \ No newline at end of file diff --git a/packages/stacks/maintenance-site/.gitignore b/packages/stacks/maintenance-site/.gitignore new file mode 100644 index 00000000..6612dc2c --- /dev/null +++ b/packages/stacks/maintenance-site/.gitignore @@ -0,0 +1,50 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/package.json +!/LICENSE +!/.npmignore +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +build/Release +node_modules/ +jspm_packages/ +*.tsbuildinfo +.eslintcache +*.tgz +.yarn-integrity +.cache +!/.projenrc.js +!/.prettierignore +!/.prettierrc.json +!/.npmrc +!/test/ +!/src/ +/dist +/dist/ +!/.eslintrc.json +/assets/ +!/cdk.json +/cdk.out/ +.cdk.staging/ +.parcel-cache/ +!/tsconfig.json +!/tsconfig.dev.json +cdk.context.json +!/vitest.config.ts +!/project.json diff --git a/packages/stacks/maintenance-site/.npmignore b/packages/stacks/maintenance-site/.npmignore new file mode 100644 index 00000000..79c3be7a --- /dev/null +++ b/packages/stacks/maintenance-site/.npmignore @@ -0,0 +1,19 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/.projen/ +/test/ +/src/ +!/dist/ +!/dist/**/*.js +!/dist/**/*.d.ts +dist +/.github/ +/.vscode/ +/.idea/ +/.projenrc.js +tsconfig.tsbuildinfo +/.eslintrc.json +!/assets/ +cdk.out/ +.cdk.staging/ +/tsconfig.json +/tsconfig.dev.json diff --git a/packages/stacks/maintenance-site/.prettierignore b/packages/stacks/maintenance-site/.prettierignore new file mode 100644 index 00000000..3df05444 --- /dev/null +++ b/packages/stacks/maintenance-site/.prettierignore @@ -0,0 +1,15 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.eslintrc.json +.gitattributes +.gitignore +.npmignore +.prettierignore +.prettierrc.json +.projen/deps.json +.projen/files.json +.projen/tasks.json +cdk.json +LICENSE +project.json +tsconfig.dev.json +tsconfig.json diff --git a/packages/stacks/maintenance-site/.prettierrc.json b/packages/stacks/maintenance-site/.prettierrc.json new file mode 100644 index 00000000..7afe062b --- /dev/null +++ b/packages/stacks/maintenance-site/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "overrides": [], + "singleQuote": true, + "semi": false, + "useTabs": true, + "tabWidth": 2 +} diff --git a/packages/stacks/maintenance-site/.projen/deps.json b/packages/stacks/maintenance-site/.projen/deps.json new file mode 100644 index 00000000..5f775ad1 --- /dev/null +++ b/packages/stacks/maintenance-site/.projen/deps.json @@ -0,0 +1,108 @@ +{ + "dependencies": [ + { + "name": "@types/node", + "version": "^18", + "type": "build" + }, + { + "name": "@typescript-eslint/eslint-plugin", + "version": "^5", + "type": "build" + }, + { + "name": "@typescript-eslint/parser", + "version": "^5", + "type": "build" + }, + { + "name": "aws-cdk", + "version": "^2.91.0", + "type": "build" + }, + { + "name": "esbuild", + "type": "build" + }, + { + "name": "eslint-config-prettier", + "type": "build" + }, + { + "name": "eslint-import-resolver-node", + "type": "build" + }, + { + "name": "eslint-import-resolver-typescript", + "type": "build" + }, + { + "name": "eslint-plugin-import", + "type": "build" + }, + { + "name": "eslint-plugin-prettier", + "type": "build" + }, + { + "name": "eslint", + "version": "^8", + "type": "build" + }, + { + "name": "lint-staged", + "type": "build" + }, + { + "name": "npm-check-updates", + "version": "^16", + "type": "build" + }, + { + "name": "prettier", + "type": "build" + }, + { + "name": "projen", + "type": "build" + }, + { + "name": "ts-node", + "type": "build" + }, + { + "name": "typescript", + "version": "~5.1", + "type": "build" + }, + { + "name": "vitest", + "type": "build" + }, + { + "name": "@aws-prototyping-sdk/static-website", + "type": "runtime" + }, + { + "name": "@crisiscleanup/config", + "version": "workspace:*", + "type": "runtime" + }, + { + "name": "@crisiscleanup/construct.awscdk.github-pipeline", + "version": "workspace:*", + "type": "runtime" + }, + { + "name": "aws-cdk-lib", + "version": "^2.91.0", + "type": "runtime" + }, + { + "name": "constructs", + "version": "^10.2.69", + "type": "runtime" + } + ], + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." +} diff --git a/packages/stacks/maintenance-site/.projen/files.json b/packages/stacks/maintenance-site/.projen/files.json new file mode 100644 index 00000000..2214ba40 --- /dev/null +++ b/packages/stacks/maintenance-site/.projen/files.json @@ -0,0 +1,19 @@ +{ + "files": [ + ".eslintrc.json", + ".gitattributes", + ".gitignore", + ".npmignore", + ".prettierignore", + ".prettierrc.json", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "cdk.json", + "LICENSE", + "project.json", + "tsconfig.dev.json", + "tsconfig.json" + ], + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." +} diff --git a/packages/stacks/maintenance-site/.projen/tasks.json b/packages/stacks/maintenance-site/.projen/tasks.json new file mode 100644 index 00000000..9cbfc6f9 --- /dev/null +++ b/packages/stacks/maintenance-site/.projen/tasks.json @@ -0,0 +1,213 @@ +{ + "tasks": { + "build": { + "name": "build", + "description": "Full release build", + "steps": [ + { + "spawn": "pre-compile" + }, + { + "spawn": "compile" + }, + { + "spawn": "post-compile" + }, + { + "spawn": "test" + }, + { + "spawn": "package" + } + ] + }, + "bundle": { + "name": "bundle", + "description": "Prepare assets" + }, + "clean": { + "name": "clean", + "steps": [ + { + "exec": "pnpm exec tsc --build --clean" + }, + { + "exec": "pnpm exec rimraf dist lib tsconfig.tsbuildinfo" + } + ] + }, + "compile": { + "name": "compile", + "description": "Only compile" + }, + "default": { + "name": "default", + "description": "Synthesize project files" + }, + "deploy": { + "name": "deploy", + "description": "Deploys your CDK app to the AWS cloud", + "steps": [ + { + "exec": "cdk deploy", + "receiveArgs": true + } + ] + }, + "destroy": { + "name": "destroy", + "description": "Destroys your cdk app in the AWS cloud", + "steps": [ + { + "exec": "cdk destroy", + "receiveArgs": true + } + ] + }, + "diff": { + "name": "diff", + "description": "Diffs the currently deployed app against your code", + "steps": [ + { + "exec": "cdk diff" + } + ] + }, + "eslint": { + "name": "eslint", + "description": "Runs eslint against the codebase", + "steps": [ + { + "exec": "eslint --cache --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools" + } + ] + }, + "install": { + "name": "install", + "description": "Install project dependencies and update lockfile (non-frozen)", + "steps": [ + { + "exec": "pnpm i --no-frozen-lockfile" + } + ] + }, + "install:ci": { + "name": "install:ci", + "description": "Install project dependencies using frozen lockfile", + "steps": [ + { + "exec": "pnpm i --frozen-lockfile" + } + ] + }, + "package": { + "name": "package", + "description": "Creates the distribution package" + }, + "post-compile": { + "name": "post-compile", + "description": "Runs after successful compilation", + "steps": [ + { + "spawn": "synth:silent", + "condition": "[[ -z \"$SKIP_SYNTH\" ]] && [[ -n \"$MAINTENANCE_SITE_SOURCE\" ]]" + } + ] + }, + "post-upgrade": { + "name": "post-upgrade", + "description": "Runs after upgrading dependencies" + }, + "pre-compile": { + "name": "pre-compile", + "description": "Prepare the project for compilation" + }, + "synth": { + "name": "synth", + "description": "Synthesizes your cdk app into cdk.out", + "steps": [ + { + "exec": "cdk synth" + } + ] + }, + "synth:silent": { + "name": "synth:silent", + "description": "Synthesizes your cdk app into cdk.out and suppresses the template in stdout (part of \"yarn build\")", + "steps": [ + { + "exec": "cdk synth -q" + } + ] + }, + "test": { + "name": "test", + "description": "Run tests", + "steps": [ + { + "spawn": "eslint" + }, + { + "exec": "vitest", + "args": [ + "--run" + ], + "receiveArgs": true + } + ] + }, + "test:watch": { + "name": "test:watch", + "description": "Run tests on changes.", + "steps": [ + { + "exec": "vitest", + "receiveArgs": true + } + ] + }, + "upgrade": { + "name": "upgrade", + "description": "upgrade dependencies", + "env": { + "CI": "0" + }, + "steps": [ + { + "exec": "pnpm update npm-check-updates" + }, + { + "exec": "npm-check-updates --upgrade --target=minor --filter=@types/node,@typescript-eslint/eslint-plugin,@typescript-eslint/parser,aws-cdk,esbuild,eslint-config-prettier,eslint-import-resolver-node,eslint-import-resolver-typescript,eslint-plugin-import,eslint-plugin-prettier,eslint,lint-staged,npm-check-updates,prettier,projen,ts-node,vitest,@aws-prototyping-sdk/static-website,aws-cdk-lib,constructs" + }, + { + "exec": "pnpm i --no-frozen-lockfile" + }, + { + "exec": "pnpm update @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser aws-cdk esbuild eslint-config-prettier eslint-import-resolver-node eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-prettier eslint lint-staged npm-check-updates prettier projen ts-node vitest @aws-prototyping-sdk/static-website aws-cdk-lib constructs" + }, + { + "exec": "npx projen" + }, + { + "spawn": "post-upgrade" + } + ] + }, + "watch": { + "name": "watch", + "description": "Watches changes in your source code and rebuilds and deploys to the current account", + "steps": [ + { + "exec": "cdk deploy --hotswap" + }, + { + "exec": "cdk watch" + } + ] + } + }, + "env": { + "PATH": "$(pnpm -c exec \"node --print process.env.PATH\")" + }, + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." +} diff --git a/packages/stacks/maintenance-site/LICENSE b/packages/stacks/maintenance-site/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/packages/stacks/maintenance-site/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/stacks/maintenance-site/README.md b/packages/stacks/maintenance-site/README.md new file mode 100644 index 00000000..b3fa7ddc --- /dev/null +++ b/packages/stacks/maintenance-site/README.md @@ -0,0 +1 @@ +# replace this \ No newline at end of file diff --git a/packages/stacks/maintenance-site/cdk.json b/packages/stacks/maintenance-site/cdk.json new file mode 100644 index 00000000..68b77def --- /dev/null +++ b/packages/stacks/maintenance-site/cdk.json @@ -0,0 +1,22 @@ +{ + "app": "pnpm exec tsx src/main.ts", + "output": "cdk.out", + "build": "npx projen bundle", + "watch": { + "include": [ + "src/**/*.ts", + "test/**/*.ts" + ], + "exclude": [ + "README.md", + "cdk*.json", + "**/*.d.ts", + "**/*.js", + "tsconfig.json", + "package*.json", + "yarn.lock", + "node_modules" + ] + }, + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." +} diff --git a/packages/stacks/maintenance-site/package.json b/packages/stacks/maintenance-site/package.json new file mode 100644 index 00000000..847ea6fe --- /dev/null +++ b/packages/stacks/maintenance-site/package.json @@ -0,0 +1,73 @@ +{ + "name": "@crisiscleanup/stacks.maintenance-site", + "scripts": { + "build": "npx projen build", + "bundle": "npx projen bundle", + "clean": "pnpm exec projen clean", + "compile": "npx projen compile", + "default": "npx projen default", + "deploy": "npx projen deploy", + "destroy": "npx projen destroy", + "diff": "npx projen diff", + "eslint": "npx projen eslint", + "package": "npx projen package", + "post-compile": "npx projen post-compile", + "post-upgrade": "npx projen post-upgrade", + "pre-compile": "npx projen pre-compile", + "synth": "npx projen synth", + "synth:silent": "npx projen synth:silent", + "test": "npx projen test", + "test:watch": "npx projen test:watch", + "upgrade": "npx projen upgrade", + "watch": "npx projen watch" + }, + "author": { + "name": "CrisisCleanup", + "url": "https://crisiscleanup.org", + "organization": true + }, + "devDependencies": { + "@types/node": "^18", + "@typescript-eslint/eslint-plugin": "^5", + "@typescript-eslint/parser": "^5", + "aws-cdk": "^2.91.0", + "esbuild": "^0.19.1", + "eslint": "^8", + "eslint-config-prettier": "^8.10.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-import-resolver-typescript": "^3.6.0", + "eslint-plugin-import": "^2.28.0", + "eslint-plugin-prettier": "^5.0.0", + "lint-staged": "^13.2.3", + "npm-check-updates": "^16", + "prettier": "^3.0.1", + "projen": "^0.72.11", + "ts-node": "^10.9.1", + "typescript": "~5.1", + "vitest": "^0.34.1" + }, + "dependencies": { + "@aws-prototyping-sdk/static-website": "^0.19.66", + "@crisiscleanup/config": "workspace:*", + "@crisiscleanup/construct.awscdk.github-pipeline": "workspace:*", + "aws-cdk-lib": "^2.91.0", + "constructs": "^10.2.69" + }, + "engines": { + "node": ">= 18.16.0" + }, + "license": "Apache-2.0", + "version": "0.0.0", + "type": "module", + "sideEffects": true, + "packageManager": "pnpm@8.6.9", + "lint-staged": { + "*.{ts,tsx,mts,cts,js,jsx,jts,jts}": [ + "pnpm exec eslint --cache --fix --no-error-on-unmatched-pattern" + ], + "*.{yaml,yml}": [ + "pnpm exec prettier --write" + ] + }, + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." +} diff --git a/packages/stacks/maintenance-site/project.json b/packages/stacks/maintenance-site/project.json new file mode 100644 index 00000000..7e48a23f --- /dev/null +++ b/packages/stacks/maintenance-site/project.json @@ -0,0 +1,140 @@ +{ + "name": "stacks.maintenance-site", + "root": "packages/stacks/maintenance-site", + "targets": { + "default": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen default", + "cwd": "packages/stacks/maintenance-site" + } + }, + "pre-compile": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen pre-compile", + "cwd": "packages/stacks/maintenance-site" + } + }, + "compile": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen compile", + "cwd": "packages/stacks/maintenance-site" + } + }, + "post-compile": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen post-compile", + "cwd": "packages/stacks/maintenance-site" + } + }, + "test": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen test", + "cwd": "packages/stacks/maintenance-site" + } + }, + "package": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen package", + "cwd": "packages/stacks/maintenance-site" + } + }, + "build": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen build", + "cwd": "packages/stacks/maintenance-site" + } + }, + "post-upgrade": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen post-upgrade", + "cwd": "packages/stacks/maintenance-site" + } + }, + "upgrade": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen upgrade", + "cwd": "packages/stacks/maintenance-site" + } + }, + "watch": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen watch", + "cwd": "packages/stacks/maintenance-site" + } + }, + "synth": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen synth", + "cwd": "packages/stacks/maintenance-site" + } + }, + "synth:silent": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen synth:silent", + "cwd": "packages/stacks/maintenance-site" + } + }, + "deploy": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen deploy", + "cwd": "packages/stacks/maintenance-site" + } + }, + "destroy": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen destroy", + "cwd": "packages/stacks/maintenance-site" + } + }, + "diff": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen diff", + "cwd": "packages/stacks/maintenance-site" + } + }, + "bundle": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen bundle", + "cwd": "packages/stacks/maintenance-site" + } + }, + "eslint": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen eslint", + "cwd": "packages/stacks/maintenance-site" + } + }, + "test:watch": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen test:watch", + "cwd": "packages/stacks/maintenance-site" + } + }, + "clean": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen clean", + "cwd": "packages/stacks/maintenance-site" + } + } + }, + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." +} diff --git a/packages/stacks/maintenance-site/src/main.ts b/packages/stacks/maintenance-site/src/main.ts new file mode 100644 index 00000000..3de1e4ac --- /dev/null +++ b/packages/stacks/maintenance-site/src/main.ts @@ -0,0 +1,23 @@ +import { getConfig } from '@crisiscleanup/config' +import { App } from 'aws-cdk-lib' +import { MaintenanceSite } from './maintenance-site' + +const { config } = await getConfig({ strict: true, useEnvOverrides: true }) + +const app = new App() + +const source = process.env.MAINTENANCE_SITE_SOURCE +if (!source) throw new Error('MAINTENANCE_SITE_SOURCE is required') + +new MaintenanceSite( + app, + 'maintenance-site', + { + source, + }, + { + env: config.cdkEnvironment, + }, +) + +app.synth() diff --git a/packages/stacks/maintenance-site/src/maintenance-site.ts b/packages/stacks/maintenance-site/src/maintenance-site.ts new file mode 100644 index 00000000..97cfb6b4 --- /dev/null +++ b/packages/stacks/maintenance-site/src/maintenance-site.ts @@ -0,0 +1,76 @@ +import { + StaticWebsite, + StaticWebsiteOrigin, +} from '@aws-prototyping-sdk/static-website' +import { Duration, Stack, type StackProps } from 'aws-cdk-lib' +import * as acm from 'aws-cdk-lib/aws-certificatemanager' +import * as cloudfront from 'aws-cdk-lib/aws-cloudfront' +import * as route53 from 'aws-cdk-lib/aws-route53' +import * as route53Targets from 'aws-cdk-lib/aws-route53-targets' +import type { Construct } from 'constructs' + +export interface MaintenanceSiteProps { + /** + * Path to site source files. + */ + readonly source: string +} + +/** + * Maintenance site for crisiscleanup.org + */ +export class MaintenanceSite extends Stack { + readonly zone?: route53.IHostedZone + readonly certificate?: acm.ICertificate + readonly website: StaticWebsite + + constructor( + scope: Construct, + id: string, + props: MaintenanceSiteProps, + stackProps?: StackProps, + ) { + super(scope, id, stackProps) + + if (stackProps?.env) { + this.zone = route53.HostedZone.fromLookup(this, id + '-hosted-zone', { + domainName: 'crisiscleanup.org', + }) + + this.certificate = new acm.Certificate(this, id + '-certificate', { + domainName: 'crisiscleanup.org', + validation: acm.CertificateValidation.fromDns(this.zone), + subjectAlternativeNames: ['maintenance.crisiscleanup.org'], + }) + } + + this.website = new StaticWebsite(this, id + '-static-site', { + webAclProps: { disable: true }, + websiteContentPath: props.source, + distributionProps: { + defaultBehavior: { + // no-op class; `StaticWebsite` maps this later. + origin: new StaticWebsiteOrigin(), + }, + comment: 'Maintenance Site', + certificate: this.certificate, + priceClass: cloudfront.PriceClass.PRICE_CLASS_100, + domainNames: ['maintenance.crisiscleanup.org'], + }, + }) + + if (this.zone) { + new route53.ARecord(this, id + '-alias-record', { + zone: this.zone, + comment: 'Maintenance Site', + target: route53.RecordTarget.fromAlias( + new route53Targets.CloudFrontTarget( + this.website.cloudFrontDistribution, + ), + ), + ttl: Duration.seconds(300), + recordName: 'maintenance.crisiscleanup.org', + }) + } + } +} diff --git a/packages/stacks/maintenance-site/test/__snapshots__/main.spec.ts.snap b/packages/stacks/maintenance-site/test/__snapshots__/main.spec.ts.snap new file mode 100644 index 00000000..1931a45a --- /dev/null +++ b/packages/stacks/maintenance-site/test/__snapshots__/main.spec.ts.snap @@ -0,0 +1,1778 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`MaintenanceSite > renders expected template 1`] = ` +{ + "Outputs": { + "testmaintenancesitestaticsiteDistributionDomainName98FBA8BF": { + "Value": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteCloudfrontDistributionC473D8AA", + "DomainName", + ], + }, + }, + }, + "Parameters": { + "BootstrapVersion": { + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]", + "Type": "AWS::SSM::Parameter::Value", + }, + }, + "Resources": { + "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536": { + "DependsOn": [ + "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF", + "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265", + ], + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", + }, + "S3Key": "9eb41a5505d37607ac419321497a4f8c21cf0ee1f9b4a6b29aa04301aea5c7fd.zip", + }, + "Environment": { + "Variables": { + "AWS_CA_BUNDLE": "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", + }, + }, + "Handler": "index.handler", + "Layers": [ + { + "Ref": "testmaintenancesitestaticsiteWebsiteDeploymentAwsCliLayer76CA91FD", + }, + ], + "Role": { + "Fn::GetAtt": [ + "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265", + "Arn", + ], + }, + "Runtime": "python3.9", + "Timeout": 900, + }, + "Type": "AWS::Lambda::Function", + }, + "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265": { + "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", + ], + ], + }, + ], + }, + "Type": "AWS::IAM::Role", + }, + "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF": { + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", + }, + ], + ], + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", + }, + "/*", + ], + ], + }, + ], + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging", + "s3:Abort*", + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + { + "Action": [ + "cloudfront:GetInvalidation", + "cloudfront:CreateInvalidation", + ], + "Effect": "Allow", + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy88902FDF", + "Roles": [ + { + "Ref": "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRole89A01265", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { + "DependsOn": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + ], + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", + }, + "S3Key": "a657308e723bb9460b800cb3b47dadb74e28243edfe246bf7755c45ec312eb97.zip", + }, + "Description": { + "Fn::Join": [ + "", + [ + "Lambda function for auto-deleting objects in ", + { + "Ref": "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + }, + " S3 bucket.", + ], + ], + }, + "Handler": "index.handler", + "MemorySize": 128, + "Role": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn", + ], + }, + "Runtime": "nodejs18.x", + "Timeout": 900, + }, + "Type": "AWS::Lambda::Function", + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:\${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + }, + ], + }, + "Type": "AWS::IAM::Role", + }, + "testmaintenancesitestaticsiteAccessLogsBucketAutoDeleteObjectsCustomResource6E95A8C4": { + "DeletionPolicy": "Delete", + "DependsOn": [ + "testmaintenancesitestaticsiteAccessLogsBucketPolicy6E0CFF16", + ], + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "BucketName": { + "Ref": "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + }, + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn", + ], + }, + }, + "Type": "Custom::S3AutoDeleteObjects", + "UpdateReplacePolicy": "Delete", + }, + "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6": { + "DeletionPolicy": "Delete", + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "BucketEncryption": { + "ServerSideEncryptionConfiguration": [ + { + "ServerSideEncryptionByDefault": { + "SSEAlgorithm": "AES256", + }, + }, + ], + }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter", + }, + ], + }, + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true, + }, + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true", + }, + ], + }, + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + }, + "testmaintenancesitestaticsiteAccessLogsBucketPolicy6E0CFF16": { + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "Bucket": { + "Ref": "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": { + "AWS": "*", + }, + "Resource": [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + "Arn", + ], + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + { + "Action": [ + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn", + ], + }, + }, + "Resource": [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + "Arn", + ], + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId", + }, + }, + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com", + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + "Arn", + ], + }, + "/website-access-logs*", + ], + ], + }, + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + "Arn", + ], + }, + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId", + }, + }, + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com", + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + "Arn", + ], + }, + "/distribution-access-logs*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::S3::BucketPolicy", + }, + "testmaintenancesitestaticsiteCloudfrontDistributionC473D8AA": { + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-CFR4", + "reason": "Certificate is not mandatory therefore the Cloudfront certificate will be used.", + }, + { + "id": "AwsPrototyping-CloudFrontDistributionHttpsViewerNoOutdatedSSL", + "reason": "Certificate is not mandatory therefore the Cloudfront certificate will be used.", + }, + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "DistributionConfig": { + "Aliases": [ + "maintenance.crisiscleanup.org", + ], + "Comment": "Maintenance Site", + "CustomErrorResponses": [ + { + "ErrorCode": 404, + "ResponseCode": 200, + "ResponsePagePath": "/index.html", + }, + ], + "DefaultCacheBehavior": { + "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "Compress": true, + "TargetOriginId": "testmaintenancesitetestmaintenancesitestaticsiteCloudfrontDistributionOrigin12CA64569", + "ViewerProtocolPolicy": "redirect-to-https", + }, + "DefaultRootObject": "index.html", + "Enabled": true, + "HttpVersion": "http2", + "IPV6Enabled": true, + "Logging": { + "Bucket": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + "RegionalDomainName", + ], + }, + }, + "Origins": [ + { + "DomainName": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "RegionalDomainName", + ], + }, + "Id": "testmaintenancesitetestmaintenancesitestaticsiteCloudfrontDistributionOrigin12CA64569", + "S3OriginConfig": { + "OriginAccessIdentity": { + "Fn::Join": [ + "", + [ + "origin-access-identity/cloudfront/", + { + "Ref": "testmaintenancesitestaticsiteOriginAccessIdentity6B417CF8", + }, + ], + ], + }, + }, + }, + ], + "PriceClass": "PriceClass_100", + }, + }, + "Type": "AWS::CloudFront::Distribution", + }, + "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E": { + "DeletionPolicy": "Delete", + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "BucketEncryption": { + "ServerSideEncryptionConfiguration": [ + { + "ServerSideEncryptionByDefault": { + "SSEAlgorithm": "AES256", + }, + }, + ], + }, + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + }, + "LogFilePrefix": "distribution-access-logs", + }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "BucketOwnerPreferred", + }, + ], + }, + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true, + }, + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true", + }, + ], + }, + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + }, + "testmaintenancesitestaticsiteDistributionLogBucketAutoDeleteObjectsCustomResource5F2FB661": { + "DeletionPolicy": "Delete", + "DependsOn": [ + "testmaintenancesitestaticsiteDistributionLogBucketPolicy232B94B1", + ], + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "BucketName": { + "Ref": "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + }, + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn", + ], + }, + }, + "Type": "Custom::S3AutoDeleteObjects", + "UpdateReplacePolicy": "Delete", + }, + "testmaintenancesitestaticsiteDistributionLogBucketPolicy232B94B1": { + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "Bucket": { + "Ref": "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": { + "AWS": "*", + }, + "Resource": [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + "Arn", + ], + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + { + "Action": [ + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn", + ], + }, + }, + "Resource": [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + "Arn", + ], + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteDistributionLogBucketAF2F2F4E", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::S3::BucketPolicy", + }, + "testmaintenancesitestaticsiteOriginAccessIdentity6B417CF8": { + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "CloudFrontOriginAccessIdentityConfig": { + "Comment": "Allows CloudFront to reach the bucket", + }, + }, + "Type": "AWS::CloudFront::CloudFrontOriginAccessIdentity", + }, + "testmaintenancesitestaticsiteWebsiteBucket734B2C11": { + "DeletionPolicy": "Delete", + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "BucketEncryption": { + "ServerSideEncryptionConfiguration": [ + { + "ServerSideEncryptionByDefault": { + "SSEAlgorithm": "AES256", + }, + }, + ], + }, + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "testmaintenancesitestaticsiteAccessLogsBucketEA3BB1E6", + }, + "LogFilePrefix": "website-access-logs", + }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "BucketOwnerEnforced", + }, + ], + }, + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true, + }, + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true", + }, + { + "Key": "aws-cdk:cr-owned:e1136a52", + "Value": "true", + }, + ], + "VersioningConfiguration": { + "Status": "Enabled", + }, + }, + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + }, + "testmaintenancesitestaticsiteWebsiteBucketAutoDeleteObjectsCustomResourceF23427B2": { + "DeletionPolicy": "Delete", + "DependsOn": [ + "testmaintenancesitestaticsiteWebsiteBucketPolicy6CC28212", + ], + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "BucketName": { + "Ref": "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + }, + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn", + ], + }, + }, + "Type": "Custom::S3AutoDeleteObjects", + "UpdateReplacePolicy": "Delete", + }, + "testmaintenancesitestaticsiteWebsiteBucketPolicy6CC28212": { + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "Bucket": { + "Ref": "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": { + "AWS": "*", + }, + "Resource": [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + { + "Action": [ + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn", + ], + }, + }, + "Resource": [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + { + "Action": "s3:ListBucket", + "Effect": "Allow", + "Principal": { + "CanonicalUser": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteOriginAccessIdentity6B417CF8", + "S3CanonicalUserId", + ], + }, + }, + "Resource": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + }, + { + "Action": "s3:GetObject", + "Effect": "Allow", + "Principal": { + "CanonicalUser": { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteOriginAccessIdentity6B417CF8", + "S3CanonicalUserId", + ], + }, + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + "Arn", + ], + }, + "/*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::S3::BucketPolicy", + }, + "testmaintenancesitestaticsiteWebsiteDeploymentAwsCliLayer76CA91FD": { + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "Content": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", + }, + "S3Key": "e2277687077a2abf9ae1af1cc9565e6715e2ebb62f79ec53aa75a1af9298f642.zip", + }, + "Description": "/opt/awscli/aws", + }, + "Type": "AWS::Lambda::LayerVersion", + }, + "testmaintenancesitestaticsiteWebsiteDeploymentCustomResourceB75382EC": { + "DeletionPolicy": "Delete", + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-L1", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "id": "AwsPrototyping-LambdaLatestVersion", + "reason": "Latest runtime cannot be configured. CDK will need to upgrade the BucketDeployment construct accordingly.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsSolutions-IAM5", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Action::s3:.*$/g", + }, + { + "regex": "/^Resource::.*$/g", + }, + ], + "id": "AwsPrototyping-IAMNoWildcardPermissions", + "reason": "All Policies have been scoped to a Bucket. Given Buckets can contain arbitrary content, wildcard resources with bucket scope are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsSolutions-IAM4", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "applies_to": [ + { + "regex": "/^Policy::arn::iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g", + }, + ], + "id": "AwsPrototyping-IAMNoManagedPolicies", + "reason": "Buckets can contain arbitrary content, therefore wildcard resources under a bucket are required.", + }, + { + "id": "AwsSolutions-S1", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + { + "id": "AwsPrototyping-S3BucketLoggingEnabled", + "reason": "Access Log buckets should not have s3 bucket logging", + }, + ], + }, + }, + "Properties": { + "DestinationBucketName": { + "Ref": "testmaintenancesitestaticsiteWebsiteBucket734B2C11", + }, + "DistributionId": { + "Ref": "testmaintenancesitestaticsiteCloudfrontDistributionC473D8AA", + }, + "Prune": true, + "ServiceToken": { + "Fn::GetAtt": [ + "CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C81C01536", + "Arn", + ], + }, + "SourceBucketNames": [ + { + "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", + }, + ], + "SourceObjectKeys": [ + "1ebc9d3ac2033816c4abb63e4afd69d350b4aba8704cc9236b82ea520b74f4b0.zip", + ], + }, + "Type": "Custom::CDKBucketDeployment", + "UpdateReplacePolicy": "Delete", + }, + }, + "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.", + }, + ], + }, + }, +} +`; diff --git a/packages/stacks/maintenance-site/test/main.spec.ts b/packages/stacks/maintenance-site/test/main.spec.ts new file mode 100644 index 00000000..720d929f --- /dev/null +++ b/packages/stacks/maintenance-site/test/main.spec.ts @@ -0,0 +1,20 @@ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' +import { App } from 'aws-cdk-lib' +import { Template } from 'aws-cdk-lib/assertions' +import { describe, expect, test } from 'vitest' +import { MaintenanceSite } from '../src/maintenance-site' + +describe('MaintenanceSite', () => { + test('renders expected template', async () => { + const sourcePath = path.join(os.tmpdir(), 'maintenance-test') + const tempDir = await fs.mkdtemp(sourcePath) + const app = new App() + const stack = new MaintenanceSite(app, 'test-maintenance-site', { + source: tempDir, + }) + const template = Template.fromStack(stack) + expect(template.toJSON()).toMatchSnapshot() + }) +}) diff --git a/packages/stacks/maintenance-site/tsconfig.dev.json b/packages/stacks/maintenance-site/tsconfig.dev.json new file mode 100644 index 00000000..296dba7a --- /dev/null +++ b/packages/stacks/maintenance-site/tsconfig.dev.json @@ -0,0 +1,17 @@ +// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +{ + "extends": "./tsconfig.json", + "compilerOptions": {}, + "include": [ + ".projenrc.js", + "src/**/*.ts", + "test/**/*.ts", + "src/*.ts", + "*.ts", + "**/*.ts", + "vitest.config.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/packages/stacks/maintenance-site/tsconfig.json b/packages/stacks/maintenance-site/tsconfig.json new file mode 100644 index 00000000..93ec5b6b --- /dev/null +++ b/packages/stacks/maintenance-site/tsconfig.json @@ -0,0 +1,35 @@ +// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +{ + "extends": [ + "../../../tsconfig/tsconfig.base.json", + "../../../tsconfig/tsconfig.esm.json", + "../../../tsconfig/tsconfig.bundler.json", + "../../../tsconfig/tsconfig.composite.json" + ], + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "declarationDir": "src" + }, + "include": [ + "src/**/*.ts", + "src/*.ts" + ], + "exclude": [ + "cdk.out" + ], + "typedocOptions": { + "entryPoints": [ + "src/index.ts" + ], + "useTsLinkResolution": true + }, + "references": [ + { + "path": "../../config/tsconfig.json" + }, + { + "path": "../../construct/awscdk/github-pipeline/tsconfig.json" + } + ] +} diff --git a/packages/stacks/maintenance-site/vitest.config.ts b/packages/stacks/maintenance-site/vitest.config.ts new file mode 100644 index 00000000..2d3005a0 --- /dev/null +++ b/packages/stacks/maintenance-site/vitest.config.ts @@ -0,0 +1,10 @@ +// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +import { defineProject } from 'vitest/config' + +export default defineProject({ + test: { + name: 'stacks.maintenance-site', + include: ['test/**/*.spec.ts'], + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76b83300..80c75309 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -724,6 +724,79 @@ importers: specifier: ^0.34.1 version: 0.34.1(supports-color@8.1.1) + packages/stacks/maintenance-site: + dependencies: + '@aws-prototyping-sdk/static-website': + specifier: ^0.19.66 + version: 0.19.66(aws-cdk-lib@2.91.0)(cdk-nag@2.27.99)(constructs@10.2.69)(projen@0.72.11) + '@crisiscleanup/config': + specifier: workspace:* + version: link:../../config + '@crisiscleanup/construct.awscdk.github-pipeline': + specifier: workspace:* + version: link:../../construct/awscdk/github-pipeline + aws-cdk-lib: + specifier: 2.91.0 + version: 2.91.0(constructs@10.2.69) + constructs: + specifier: 10.2.69 + version: 10.2.69 + devDependencies: + '@types/node': + specifier: ^18 + version: 18.16.19 + '@typescript-eslint/eslint-plugin': + specifier: ^5 + version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.45.0)(supports-color@8.1.1)(typescript@5.1.6) + '@typescript-eslint/parser': + specifier: ^5 + version: 5.62.0(eslint@8.45.0)(supports-color@8.1.1)(typescript@5.1.6) + aws-cdk: + specifier: ^2.91.0 + version: 2.91.0 + esbuild: + specifier: ^0.19.1 + version: 0.19.1 + eslint: + specifier: ^8 + version: 8.45.0(supports-color@8.1.1) + eslint-config-prettier: + specifier: ^8.10.0 + version: 8.10.0(eslint@8.45.0) + eslint-import-resolver-node: + specifier: ^0.3.9 + version: 0.3.9(supports-color@8.1.1) + eslint-import-resolver-typescript: + specifier: ^3.6.0 + version: 3.6.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.0)(eslint@8.45.0) + eslint-plugin-import: + specifier: ^2.28.0 + version: 2.28.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.0)(eslint@8.45.0) + eslint-plugin-prettier: + specifier: ^5.0.0 + version: 5.0.0(eslint-config-prettier@8.10.0)(eslint@8.45.0)(prettier@3.0.1) + lint-staged: + specifier: ^13.2.3 + version: 13.2.3(supports-color@8.1.1) + npm-check-updates: + specifier: ^16 + version: 16.11.1(supports-color@8.1.1) + prettier: + specifier: ^3.0.1 + version: 3.0.1 + projen: + specifier: ^0.72.11 + version: 0.72.11 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@18.16.19)(typescript@5.1.6) + typescript: + specifier: ~5.1 + version: 5.1.6 + vitest: + specifier: ^0.34.1 + version: 0.34.1(supports-color@8.1.1) + packages: /@aashutoshrathi/word-wrap@1.2.6: resolution: @@ -1206,6 +1279,39 @@ packages: - fs-extra - semver + /@aws-prototyping-sdk/pdk-nag@0.19.66(aws-cdk-lib@2.91.0)(cdk-nag@2.27.99)(constructs@10.2.69): + resolution: + { + integrity: sha512-5ZFBZlzqyt06J9bSu/iz++MmCeC6Z6Ic7P3bU5Ojv9e1pbPBF3nG7am2aJo1EQKf5AoMpugevyjUAkqrzNhLHg==, + } + peerDependencies: + aws-cdk-lib: ^2.81.0 + cdk-nag: ^2.27.24 + constructs: ^10.2.39 + dependencies: + aws-cdk-lib: 2.91.0(constructs@10.2.69) + cdk-nag: 2.27.99(aws-cdk-lib@2.91.0)(constructs@10.2.69) + constructs: 10.2.69 + dev: false + + /@aws-prototyping-sdk/static-website@0.19.66(aws-cdk-lib@2.91.0)(cdk-nag@2.27.99)(constructs@10.2.69)(projen@0.72.11): + resolution: + { + integrity: sha512-cwYpaAa+GLoPTtfiqMNI1F/ltYGIGgfBLHLbd1QjEGpJxi1x1+ARnUpfnI1NV05DsOlIdId3WOWkHsUaQZO7Lw==, + } + peerDependencies: + aws-cdk-lib: ^2.81.0 + cdk-nag: ^2.27.24 + constructs: ^10.2.39 + projen: ^0.71.92 + dependencies: + '@aws-prototyping-sdk/pdk-nag': 0.19.66(aws-cdk-lib@2.91.0)(cdk-nag@2.27.99)(constructs@10.2.69) + aws-cdk-lib: 2.91.0(constructs@10.2.69) + cdk-nag: 2.27.99(aws-cdk-lib@2.91.0)(constructs@10.2.69) + constructs: 10.2.69 + projen: 0.72.11 + dev: false + /@aws-quickstart/eks-blueprints@1.10.1(patch_hash=zm4z4irgexfyyzn6zapko5vjlq): resolution: { @@ -3137,7 +3243,6 @@ packages: { integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==, } - dev: true /@isaacs/cliui@8.0.2: resolution: @@ -3714,7 +3819,6 @@ packages: '@oozcitak/infra': 1.0.8 '@oozcitak/url': 1.0.4 '@oozcitak/util': 8.3.8 - dev: true /@oozcitak/infra@1.0.8: resolution: @@ -3724,7 +3828,6 @@ packages: engines: { node: '>=6.0' } dependencies: '@oozcitak/util': 8.3.8 - dev: true /@oozcitak/url@1.0.4: resolution: @@ -3735,7 +3838,6 @@ packages: dependencies: '@oozcitak/infra': 1.0.8 '@oozcitak/util': 8.3.8 - dev: true /@oozcitak/util@8.3.8: resolution: @@ -3743,7 +3845,6 @@ packages: integrity: sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==, } engines: { node: '>=8.0' } - dev: true /@parcel/watcher@2.0.4: resolution: @@ -5669,7 +5770,6 @@ packages: } dependencies: sprintf-js: 1.0.3 - dev: true /argparse@2.0.1: resolution: @@ -5713,7 +5813,6 @@ packages: { integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==, } - dev: true /array-union@2.1.0: resolution: @@ -6068,7 +6167,6 @@ packages: } dependencies: balanced-match: 1.0.2 - dev: true /braces@3.0.2: resolution: @@ -6832,7 +6930,6 @@ packages: esprima: 4.0.1 has-own-prop: 2.0.0 repeat-string: 1.6.1 - dev: true /commondir@1.0.1: resolution: @@ -6985,7 +7082,6 @@ packages: { integrity: sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==, } - dev: true /conventional-changelog-conventionalcommits@4.6.3: resolution: @@ -8334,7 +8430,6 @@ packages: } engines: { node: '>=4' } hasBin: true - dev: true /esquery@1.5.0: resolution: @@ -9184,7 +9279,6 @@ packages: inherits: 2.0.4 minimatch: 5.1.6 once: 1.4.0 - dev: true /global-dirs@3.0.1: resolution: @@ -9374,7 +9468,6 @@ packages: integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==, } engines: { node: '>=8' } - dev: true /has-property-descriptors@1.0.0: resolution: @@ -9688,7 +9781,6 @@ packages: integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==, } engines: { node: '>=10' } - dev: true /ini@4.1.1: resolution: @@ -9740,7 +9832,6 @@ packages: integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==, } engines: { node: '>= 0.10' } - dev: true /ip@2.0.0: resolution: @@ -9839,7 +9930,6 @@ packages: } dependencies: has: 1.0.3 - dev: true /is-date-object@1.0.5: resolution: @@ -10215,7 +10305,6 @@ packages: dependencies: argparse: 1.0.10 esprima: 4.0.1 - dev: true /js-yaml@4.1.0: resolution: @@ -11186,7 +11275,6 @@ packages: engines: { node: '>=10' } dependencies: brace-expansion: 2.0.1 - dev: true /minimatch@7.4.6: resolution: @@ -11225,7 +11313,6 @@ packages: { integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, } - dev: true /minipass-collect@1.0.2: resolution: @@ -12398,7 +12485,6 @@ packages: { integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, } - dev: true /path-scurry@1.10.1: resolution: @@ -12608,7 +12694,6 @@ packages: xmlbuilder2: 3.1.1 yaml: 2.3.1 yargs: 17.7.2 - dev: true bundledDependencies: - '@iarna/toml' - case @@ -12946,7 +13031,6 @@ packages: engines: { node: '>= 0.10' } dependencies: resolve: 1.22.4 - dev: true /redent@3.0.0: resolution: @@ -13011,7 +13095,6 @@ packages: integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==, } engines: { node: '>=0.10' } - dev: true /require-directory@2.1.1: resolution: @@ -13074,7 +13157,6 @@ packages: is-core-module: 2.13.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /responselike@3.0.0: resolution: @@ -13368,7 +13450,6 @@ packages: glob: 7.2.3 interpret: 1.4.0 rechoir: 0.6.2 - dev: true /shiki@0.14.3: resolution: @@ -13392,7 +13473,6 @@ packages: dependencies: minimist: 1.2.8 shelljs: 0.8.5 - dev: true /side-channel@1.0.4: resolution: @@ -13696,7 +13776,6 @@ packages: { integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, } - dev: true /sscaff@1.2.274: resolution: @@ -14054,7 +14133,6 @@ packages: integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, } engines: { node: '>= 0.4' } - dev: true /svg-tags@1.0.0: resolution: @@ -15325,7 +15403,6 @@ packages: '@oozcitak/infra': 1.0.8 '@oozcitak/util': 8.3.8 js-yaml: 3.14.1 - dev: true /xmlbuilder@15.1.1: resolution: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 36d86721..422839f3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -7,3 +7,4 @@ packages: - packages/k8s/construct/api - packages/k8s/construct/component - packages/stacks/api + - packages/stacks/maintenance-site diff --git a/tsconfig.json b/tsconfig.json index 3d3207af..b6b8bab9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -40,7 +40,8 @@ "./packages/construct/awscdk/github-pipeline", "./packages/k8s/construct/api", "./packages/k8s/construct/component", - "./packages/stacks/api" + "./packages/stacks/api", + "./packages/stacks/maintenance-site" ], "entryPointStrategy": "packages", "out": "docs", diff --git a/vitest.workspace.json b/vitest.workspace.json index 5599dd4b..5af3a0f8 100644 --- a/vitest.workspace.json +++ b/vitest.workspace.json @@ -1,5 +1,6 @@ [ "./packages/config/vitest.config.ts", "./packages/charts/crisiscleanup/vitest.config.ts", - "./packages/stacks/api/vitest.config.ts" + "./packages/stacks/api/vitest.config.ts", + "./packages/stacks/maintenance-site/vitest.config.ts" ]