@guardian/cdk 50.10.5 → 50.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/lib/aspects/cfn-include-reporter.js.map +1 -1
  2. package/lib/aspects/cfn-parameter-reporter.js.map +1 -1
  3. package/lib/bin/aws-credential-provider.js.map +1 -1
  4. package/lib/bin/commands/account-readiness/index.js.map +1 -1
  5. package/lib/bin/commands/account-readiness/ssm.js.map +1 -1
  6. package/lib/bin/commands/new-project/index.js.map +1 -1
  7. package/lib/bin/commands/new-project/utils/app.js.map +1 -1
  8. package/lib/bin/commands/new-project/utils/init.js +1 -1
  9. package/lib/bin/commands/new-project/utils/init.js.map +1 -1
  10. package/lib/bin/commands/new-project/utils/snapshot.js.map +1 -1
  11. package/lib/bin/commands/new-project/utils/utils.js.map +1 -1
  12. package/lib/bin/index.js.map +1 -1
  13. package/lib/constants/ssm-parameter-paths.js.map +1 -1
  14. package/lib/constructs/autoscaling/asg.js.map +1 -1
  15. package/lib/constructs/core/stack.js.map +1 -1
  16. package/lib/constructs/dns/dns-records.js.map +1 -1
  17. package/lib/constructs/ec2/vpc.js.map +1 -1
  18. package/lib/constructs/ecs/ecs-task.js.map +1 -1
  19. package/lib/constructs/iam/policies/base-policy.js.map +1 -1
  20. package/lib/constructs/iam/roles/github-actions.js.map +1 -1
  21. package/lib/constructs/vpc/vpc.js.map +1 -1
  22. package/lib/experimental/constructs/error-budget-alarm.js.map +1 -1
  23. package/lib/experimental/constructs/iam/roles/fastly-kinesis-log.js.map +1 -1
  24. package/lib/experimental/patterns/kinesis-lambda.js.map +1 -1
  25. package/lib/experimental/patterns/sns-lambda.js.map +1 -1
  26. package/lib/experimental/riff-raff-yaml-file/deployments/autoscaling.js.map +1 -1
  27. package/lib/experimental/riff-raff-yaml-file/deployments/cloudformation.js.map +1 -1
  28. package/lib/experimental/riff-raff-yaml-file/deployments/lambda.js.map +1 -1
  29. package/lib/experimental/riff-raff-yaml-file/group-by.js.map +1 -1
  30. package/lib/experimental/riff-raff-yaml-file/index.js.map +1 -1
  31. package/lib/patterns/api-multiple-lambdas.js.map +1 -1
  32. package/lib/patterns/ec2-app/base.js.map +1 -1
  33. package/lib/types/access.js.map +1 -1
  34. package/lib/utils/cli/vpc.js.map +1 -1
  35. package/lib/utils/security-groups/helpers.js.map +1 -1
  36. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"cfn-include-reporter.js","sourceRoot":"","sources":["../../src/aspects/cfn-include-reporter.ts"],"names":[],"mappings":";;;AACA,6CAA0C;AAC1C,+EAAgE;AAEhE,4CAA2C;AAE3C;;GAEG;AACH,MAAa,kBAAkB;IACtB,KAAK,CAAC,IAAgB;QAC3B,IAAI,IAAI,YAAY,mCAAU,EAAE;YAC9B,yBAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,CAC7B,+CAA+C,uBAAW,CAAC,IAAI,0HAA0H,CAC1L,CAAC;SACH;IACH,CAAC;CACF;AARD,gDAQC","sourcesContent":["import type { IAspect } from \"aws-cdk-lib\";\nimport { Annotations } from \"aws-cdk-lib\";\nimport { CfnInclude } from \"aws-cdk-lib/cloudformation-include\";\nimport type { IConstruct } from \"constructs\";\nimport { LibraryInfo } from \"../constants\";\n\n/**\n * An Aspect to remind users to check for stateful resources when migrating a YAML/JSON template.\n */\nexport class CfnIncludeReporter implements IAspect {\n public visit(node: IConstruct) {\n if (node instanceof CfnInclude) {\n Annotations.of(node).addWarning(\n `As you're migrating a YAML/JSON template to ${LibraryInfo.NAME}, be sure to check for any stateful resources! See https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md.`\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"cfn-include-reporter.js","sourceRoot":"","sources":["../../src/aspects/cfn-include-reporter.ts"],"names":[],"mappings":";;;AACA,6CAA0C;AAC1C,+EAAgE;AAEhE,4CAA2C;AAE3C;;GAEG;AACH,MAAa,kBAAkB;IACtB,KAAK,CAAC,IAAgB;QAC3B,IAAI,IAAI,YAAY,mCAAU,EAAE;YAC9B,yBAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,CAC7B,+CAA+C,uBAAW,CAAC,IAAI,0HAA0H,CAC1L,CAAC;SACH;IACH,CAAC;CACF;AARD,gDAQC","sourcesContent":["import type { IAspect } from \"aws-cdk-lib\";\nimport { Annotations } from \"aws-cdk-lib\";\nimport { CfnInclude } from \"aws-cdk-lib/cloudformation-include\";\nimport type { IConstruct } from \"constructs\";\nimport { LibraryInfo } from \"../constants\";\n\n/**\n * An Aspect to remind users to check for stateful resources when migrating a YAML/JSON template.\n */\nexport class CfnIncludeReporter implements IAspect {\n public visit(node: IConstruct) {\n if (node instanceof CfnInclude) {\n Annotations.of(node).addWarning(\n `As you're migrating a YAML/JSON template to ${LibraryInfo.NAME}, be sure to check for any stateful resources! See https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md.`,\n );\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cfn-parameter-reporter.js","sourceRoot":"","sources":["../../src/aspects/cfn-parameter-reporter.ts"],"names":[],"mappings":";;;AACA,6CAAwD;AAGxD;;GAEG;AACH,MAAa,oBAAoB;IACxB,KAAK,CAAC,IAAgB;QAC3B,IAAI,IAAI,YAAY,0BAAY,EAAE;YAChC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAiB,CAAC;YAC5C,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC;YAClC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAC;YAE1E,IAAI,cAAc,IAAI,UAAU,EAAE;gBAChC,yBAAW,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAChC,kCAAkC,YAAY,0CAA0C,CACzF,CAAC;aACH;SACF;IACH,CAAC;CACF;AAdD,oDAcC","sourcesContent":["import type { IAspect } from \"aws-cdk-lib\";\nimport { Annotations, CfnParameter } from \"aws-cdk-lib\";\nimport type { IConstruct } from \"constructs\";\n\n/**\n * An Aspect to remind users to check Parameters to ensure Riff-Raff can successfully deploy the stack.\n */\nexport class CfnParameterReporter implements IAspect {\n public visit(node: IConstruct): void {\n if (node instanceof CfnParameter) {\n const defaultValue = node.default as string;\n const hasDefault = !!defaultValue;\n const isSsmParameter = node.type.startsWith(\"AWS::SSM::Parameter::Value\");\n\n if (isSsmParameter && hasDefault) {\n Annotations.of(node.stack).addInfo(\n `Stack reads the SSM Parameter '${defaultValue}'. Ensure it exists prior to deployment.`\n );\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"cfn-parameter-reporter.js","sourceRoot":"","sources":["../../src/aspects/cfn-parameter-reporter.ts"],"names":[],"mappings":";;;AACA,6CAAwD;AAGxD;;GAEG;AACH,MAAa,oBAAoB;IACxB,KAAK,CAAC,IAAgB;QAC3B,IAAI,IAAI,YAAY,0BAAY,EAAE;YAChC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAiB,CAAC;YAC5C,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC;YAClC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAC;YAE1E,IAAI,cAAc,IAAI,UAAU,EAAE;gBAChC,yBAAW,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAChC,kCAAkC,YAAY,0CAA0C,CACzF,CAAC;aACH;SACF;IACH,CAAC;CACF;AAdD,oDAcC","sourcesContent":["import type { IAspect } from \"aws-cdk-lib\";\nimport { Annotations, CfnParameter } from \"aws-cdk-lib\";\nimport type { IConstruct } from \"constructs\";\n\n/**\n * An Aspect to remind users to check Parameters to ensure Riff-Raff can successfully deploy the stack.\n */\nexport class CfnParameterReporter implements IAspect {\n public visit(node: IConstruct): void {\n if (node instanceof CfnParameter) {\n const defaultValue = node.default as string;\n const hasDefault = !!defaultValue;\n const isSsmParameter = node.type.startsWith(\"AWS::SSM::Parameter::Value\");\n\n if (isSsmParameter && hasDefault) {\n Annotations.of(node.stack).addInfo(\n `Stack reads the SSM Parameter '${defaultValue}'. Ensure it exists prior to deployment.`,\n );\n }\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"aws-credential-provider.js","sourceRoot":"","sources":["../../src/bin/aws-credential-provider.ts"],"names":[],"mappings":";;;;;;AACA,sDAA0B;AAEnB,MAAM,0BAA0B,GAA6D,CAClG,OAA2B,EAC3B,EAAE;IACF,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,iBAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAEnE,OAAO,OAAO;QACZ,CAAC,CAAC,IAAI,iBAAG,CAAC,uBAAuB,CAAC,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,iBAAG,CAAC,wBAAwB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACxG,CAAC,CAAC,IAAI,iBAAG,CAAC,uBAAuB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AARW,QAAA,0BAA0B,8BAQrC","sourcesContent":["import type { CredentialProviderChain } from \"aws-sdk\";\nimport AWS from \"aws-sdk\";\n\nexport const awsCredentialProviderChain: (profile: string | undefined) => CredentialProviderChain = (\n profile: string | undefined\n) => {\n const envCredentials = () => new AWS.EnvironmentCredentials(\"AWS\");\n\n return profile\n ? new AWS.CredentialProviderChain([envCredentials, () => new AWS.SharedIniFileCredentials({ profile })])\n : new AWS.CredentialProviderChain([envCredentials]);\n};\n"]}
1
+ {"version":3,"file":"aws-credential-provider.js","sourceRoot":"","sources":["../../src/bin/aws-credential-provider.ts"],"names":[],"mappings":";;;;;;AACA,sDAA0B;AAEnB,MAAM,0BAA0B,GAA6D,CAClG,OAA2B,EAC3B,EAAE;IACF,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,iBAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAEnE,OAAO,OAAO;QACZ,CAAC,CAAC,IAAI,iBAAG,CAAC,uBAAuB,CAAC,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,iBAAG,CAAC,wBAAwB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACxG,CAAC,CAAC,IAAI,iBAAG,CAAC,uBAAuB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AARW,QAAA,0BAA0B,8BAQrC","sourcesContent":["import type { CredentialProviderChain } from \"aws-sdk\";\nimport AWS from \"aws-sdk\";\n\nexport const awsCredentialProviderChain: (profile: string | undefined) => CredentialProviderChain = (\n profile: string | undefined,\n) => {\n const envCredentials = () => new AWS.EnvironmentCredentials(\"AWS\");\n\n return profile\n ? new AWS.CredentialProviderChain([envCredentials, () => new AWS.SharedIniFileCredentials({ profile })])\n : new AWS.CredentialProviderChain([envCredentials]);\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bin/commands/account-readiness/index.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,+BAA4C;AAWrC,MAAM,uBAAuB,GAAG,KAAK,EAAE,KAAgB,EAAsB,EAAE;IACpF,MAAM,MAAM,GAAG,MAAM,IAAA,YAAS,EAAC,KAAK,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEzF,IAAI,MAAM,CAAC,eAAe,KAAK,CAAC,EAAE;QAChC,OAAO,CAAC,GAAG,CACT,yHAAyH,CAC1H,CAAC;QAEF,OAAO,CAAC,CAAC;KACV;IAED,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;QAClB,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,EAAE,CAAC;KACf;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC;AApBW,QAAA,uBAAuB,2BAoBlC","sourcesContent":["import chalk from \"chalk\";\nimport type { AwsConfig, CliCommandResponse } from \"../../../types/cli\";\nimport { report as reportSSM } from \"./ssm\";\n\nexport interface Report {\n name: string;\n isPass: boolean;\n msg?: string;\n errors: Map<string, string>;\n parametersFound: number;\n parametersMissing: number;\n}\n\nexport const accountReadinessCommand = async (props: AwsConfig): CliCommandResponse => {\n const report = await reportSSM(props);\n\n console.log(chalk.bold(report.name + \":\") + \" \" + (report.isPass ? \"✅ Pass\" : \"❌ Fail\"));\n\n if (report.parametersFound === 0) {\n console.log(\n `It looks like this account has not been set up for @guardian/cdk yet. See https://github.com/guardian/aws-account-setup`\n );\n\n return 1;\n }\n\n if (!report.isPass) {\n report.msg && console.log(report.msg + \"\\n\");\n report.errors.forEach((errMsg, name) => console.log(`${chalk.red(name)}: ${errMsg}`));\n console.log();\n }\n\n return report.isPass ? 0 : 1;\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bin/commands/account-readiness/index.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,+BAA4C;AAWrC,MAAM,uBAAuB,GAAG,KAAK,EAAE,KAAgB,EAAsB,EAAE;IACpF,MAAM,MAAM,GAAG,MAAM,IAAA,YAAS,EAAC,KAAK,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEzF,IAAI,MAAM,CAAC,eAAe,KAAK,CAAC,EAAE;QAChC,OAAO,CAAC,GAAG,CACT,yHAAyH,CAC1H,CAAC;QAEF,OAAO,CAAC,CAAC;KACV;IAED,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;QAClB,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,EAAE,CAAC;KACf;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC;AApBW,QAAA,uBAAuB,2BAoBlC","sourcesContent":["import chalk from \"chalk\";\nimport type { AwsConfig, CliCommandResponse } from \"../../../types/cli\";\nimport { report as reportSSM } from \"./ssm\";\n\nexport interface Report {\n name: string;\n isPass: boolean;\n msg?: string;\n errors: Map<string, string>;\n parametersFound: number;\n parametersMissing: number;\n}\n\nexport const accountReadinessCommand = async (props: AwsConfig): CliCommandResponse => {\n const report = await reportSSM(props);\n\n console.log(chalk.bold(report.name + \":\") + \" \" + (report.isPass ? \"✅ Pass\" : \"❌ Fail\"));\n\n if (report.parametersFound === 0) {\n console.log(\n `It looks like this account has not been set up for @guardian/cdk yet. See https://github.com/guardian/aws-account-setup`,\n );\n\n return 1;\n }\n\n if (!report.isPass) {\n report.msg && console.log(report.msg + \"\\n\");\n report.errors.forEach((errMsg, name) => console.log(`${chalk.red(name)}: ${errMsg}`));\n console.log();\n }\n\n return report.isPass ? 0 : 1;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ssm.js","sourceRoot":"","sources":["../../../../src/bin/commands/account-readiness/ssm.ts"],"names":[],"mappings":"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","sourcesContent":["import AWS from \"aws-sdk\";\nimport chalk from \"chalk\";\nimport type { SsmParameterPath } from \"../../../constants\";\nimport { ALL_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport type { AwsConfig } from \"../../../types/cli\";\nimport { getSsmParametersForVpc, getVpcsInDetail } from \"../../../utils/cli/vpc\";\nimport type { Report } from \".\";\n\ninterface SSMParameterReadinessOutput {\n missingParameters: SsmParameterPath[];\n foundParameters: SsmParameterPath[];\n defaultVPCReferences: SsmParameterPath[];\n}\n\nconst ssmParamReadiness = async ({ credentialProvider, region }: AwsConfig): Promise<SSMParameterReadinessOutput> => {\n const ssmClient = new AWS.SSM({\n credentialProvider,\n region,\n });\n\n const ec2Client = new AWS.EC2({\n credentialProvider,\n region,\n });\n\n const ssmParams = ALL_SSM_PARAMETER_PATHS.filter((param) => !param.optional);\n const paths: string[] = ssmParams.map((param: SsmParameterPath) => param.path);\n\n const awsResponse = await ssmClient.getParameters({ Names: paths }).promise();\n\n const notFoundParameters = awsResponse.InvalidParameters ?? [];\n const notFoundInDetail = ssmParams.filter((_) => notFoundParameters.includes(_.path));\n const foundInDetail = ssmParams.filter((_) => !notFoundParameters.includes(_.path));\n\n const vpcs = await getVpcsInDetail(ec2Client);\n const ssmParamsFromAccount = await getSsmParametersForVpc(ssmClient);\n const defaultVpcs: string[] = vpcs\n .filter((vpc) => vpc.IsDefault)\n .map((vpc) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- a VPC always has an ID, the type in CDK is odd!\n return vpc.VpcId!;\n });\n\n const ssmParametersMatchingDefaultVpc = ssmParamsFromAccount.filter(\n ({ Value }) => Value && defaultVpcs.includes(Value)\n );\n\n const defaultVPCReferencePaths = ssmParametersMatchingDefaultVpc\n .map((param) => {\n return ssmParams.find((p) => p.path === param.Name);\n })\n .filter((p): p is SsmParameterPath => p !== undefined);\n\n return {\n foundParameters: foundInDetail,\n missingParameters: notFoundInDetail,\n defaultVPCReferences: defaultVPCReferencePaths,\n };\n};\n\nexport const report = async (props: AwsConfig): Promise<Report> => {\n const output = await ssmParamReadiness(props);\n const isPass = output.missingParameters.length === 0 && output.defaultVPCReferences.length === 0;\n\n const errs = new Map<string, string>();\n const parametersMsg =\n \"CDK uses predefined SSM parameters within patterns and constructs. For example, the EC2 APP pattern uses a parameter to determine which Kinesis stream to forward logs to. Your CDK app may fail at runtime if these parameters do not exist.\";\n\n const missingParamsMsg = \"Required parameters are missing\";\n const missingParams = output.missingParameters.map((p) => ` ${chalk.yellowBright(p.path)}: ${p.description}`);\n\n if (output.missingParameters.length > 0) {\n errs.set(missingParamsMsg, `\\n${missingParams.join(\"\\n\")}`);\n }\n\n if (output.defaultVPCReferences.length > 0) {\n errs.set(\n \"Default VPC referenced in VPC parameters\",\n `you should use a custom VPC instead. Default VPC is referenced in paths: ${output.defaultVPCReferences.join(\n \", \"\n )}.`\n );\n }\n\n return {\n name: \"SSM Parameter Readiness\",\n isPass: isPass,\n msg: parametersMsg,\n errors: errs,\n parametersFound: output.foundParameters.length,\n parametersMissing: output.missingParameters.length,\n };\n};\n\nexport const isPass = (output: SSMParameterReadinessOutput): boolean => {\n return output.missingParameters.length === 0;\n};\n"]}
1
+ {"version":3,"file":"ssm.js","sourceRoot":"","sources":["../../../../src/bin/commands/account-readiness/ssm.ts"],"names":[],"mappings":"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","sourcesContent":["import AWS from \"aws-sdk\";\nimport chalk from \"chalk\";\nimport type { SsmParameterPath } from \"../../../constants\";\nimport { ALL_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport type { AwsConfig } from \"../../../types/cli\";\nimport { getSsmParametersForVpc, getVpcsInDetail } from \"../../../utils/cli/vpc\";\nimport type { Report } from \".\";\n\ninterface SSMParameterReadinessOutput {\n missingParameters: SsmParameterPath[];\n foundParameters: SsmParameterPath[];\n defaultVPCReferences: SsmParameterPath[];\n}\n\nconst ssmParamReadiness = async ({ credentialProvider, region }: AwsConfig): Promise<SSMParameterReadinessOutput> => {\n const ssmClient = new AWS.SSM({\n credentialProvider,\n region,\n });\n\n const ec2Client = new AWS.EC2({\n credentialProvider,\n region,\n });\n\n const ssmParams = ALL_SSM_PARAMETER_PATHS.filter((param) => !param.optional);\n const paths: string[] = ssmParams.map((param: SsmParameterPath) => param.path);\n\n const awsResponse = await ssmClient.getParameters({ Names: paths }).promise();\n\n const notFoundParameters = awsResponse.InvalidParameters ?? [];\n const notFoundInDetail = ssmParams.filter((_) => notFoundParameters.includes(_.path));\n const foundInDetail = ssmParams.filter((_) => !notFoundParameters.includes(_.path));\n\n const vpcs = await getVpcsInDetail(ec2Client);\n const ssmParamsFromAccount = await getSsmParametersForVpc(ssmClient);\n const defaultVpcs: string[] = vpcs\n .filter((vpc) => vpc.IsDefault)\n .map((vpc) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- a VPC always has an ID, the type in CDK is odd!\n return vpc.VpcId!;\n });\n\n const ssmParametersMatchingDefaultVpc = ssmParamsFromAccount.filter(\n ({ Value }) => Value && defaultVpcs.includes(Value),\n );\n\n const defaultVPCReferencePaths = ssmParametersMatchingDefaultVpc\n .map((param) => {\n return ssmParams.find((p) => p.path === param.Name);\n })\n .filter((p): p is SsmParameterPath => p !== undefined);\n\n return {\n foundParameters: foundInDetail,\n missingParameters: notFoundInDetail,\n defaultVPCReferences: defaultVPCReferencePaths,\n };\n};\n\nexport const report = async (props: AwsConfig): Promise<Report> => {\n const output = await ssmParamReadiness(props);\n const isPass = output.missingParameters.length === 0 && output.defaultVPCReferences.length === 0;\n\n const errs = new Map<string, string>();\n const parametersMsg =\n \"CDK uses predefined SSM parameters within patterns and constructs. For example, the EC2 APP pattern uses a parameter to determine which Kinesis stream to forward logs to. Your CDK app may fail at runtime if these parameters do not exist.\";\n\n const missingParamsMsg = \"Required parameters are missing\";\n const missingParams = output.missingParameters.map((p) => ` ${chalk.yellowBright(p.path)}: ${p.description}`);\n\n if (output.missingParameters.length > 0) {\n errs.set(missingParamsMsg, `\\n${missingParams.join(\"\\n\")}`);\n }\n\n if (output.defaultVPCReferences.length > 0) {\n errs.set(\n \"Default VPC referenced in VPC parameters\",\n `you should use a custom VPC instead. Default VPC is referenced in paths: ${output.defaultVPCReferences.join(\n \", \",\n )}.`,\n );\n }\n\n return {\n name: \"SSM Parameter Readiness\",\n isPass: isPass,\n msg: parametersMsg,\n errors: errs,\n parametersFound: output.foundParameters.length,\n parametersMissing: output.missingParameters.length,\n };\n};\n\nexport const isPass = (output: SSMParameterReadinessOutput): boolean => {\n return output.missingParameters.length === 0;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bin/commands/new-project/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"fs\";\nimport { basename, dirname, join } from \"path\";\nimport { ux } from \"@oclif/core\";\nimport chalk from \"chalk\";\nimport kebabCase from \"lodash.kebabcase\";\nimport type { CliCommandResponse } from \"../../../types/cli\";\nimport { execute } from \"../../../utils/exec\";\nimport { gitRootOrCwd } from \"../../../utils/git\";\nimport { constructApp } from \"./utils/app\";\nimport { Imports } from \"./utils/imports\";\nimport { buildDirectory } from \"./utils/init\";\nimport { constructTest } from \"./utils/snapshot\";\nimport { constructStack } from \"./utils/stack\";\nimport type { Name } from \"./utils/utils\";\nimport { getCommands, pascalCase } from \"./utils/utils\";\n\nexport type PackageManager = \"npm\" | \"yarn\";\n\ninterface NewProjectProps {\n init: boolean;\n app: string;\n stack: string;\n stages: string[];\n yamlTemplateLocation?: string;\n packageManager: PackageManager;\n}\n\ninterface NewProjectConfig extends Omit<NewProjectProps, \"stack\" | \"app\"> {\n cdkDir: string;\n appPath: string;\n appName: Name;\n stackPath: string;\n stackName: Name;\n testPath: string;\n}\n\nconst checkPathExists = (path: string): void => {\n if (!existsSync(path)) {\n throw new Error(`File not found - ${path}`);\n }\n};\n\nconst checkPathDoesNotExist = (path: string): void => {\n if (existsSync(path)) {\n throw new Error(`There is already a file at - ${path}`);\n }\n};\n\nfunction validateConfig(config: NewProjectConfig): void {\n if (!config.init) {\n checkPathExists(config.cdkDir);\n }\n checkPathDoesNotExist(config.appPath); // TODO: Update the app file if it already exists\n checkPathDoesNotExist(config.stackPath);\n\n if (config.yamlTemplateLocation) {\n checkPathExists(config.yamlTemplateLocation);\n }\n}\n\nfunction getConfig(props: NewProjectProps): NewProjectConfig {\n const { init, app, stack, stages, yamlTemplateLocation, packageManager } = props;\n\n const rootDir = gitRootOrCwd();\n const cdkDir = join(rootDir, \"/cdk\");\n\n const appName = pascalCase(app);\n const kebabAppName = kebabCase(appName);\n const stackName = pascalCase(stack);\n const kebabStackName = kebabCase(stackName);\n\n const config: NewProjectConfig = {\n init,\n yamlTemplateLocation,\n stages,\n cdkDir,\n appName: {\n kebab: kebabAppName,\n pascal: appName,\n },\n appPath: `${cdkDir}/bin/${kebabAppName}.ts`,\n stackName: {\n kebab: kebabStackName,\n pascal: stackName,\n },\n stackPath: `${cdkDir}/lib/${kebabAppName}.ts`,\n testPath: `${cdkDir}/lib/${kebabAppName}.test.ts`,\n packageManager,\n };\n\n validateConfig(config);\n\n return config;\n}\n\nexport const newCdkProject = async (props: NewProjectProps): CliCommandResponse => {\n console.log(\"Starting CDK generator\");\n\n const config = getConfig(props);\n\n if (config.init) {\n buildDirectory({ outputDir: config.cdkDir });\n }\n\n console.log(`New app ${config.appName.pascal} will be written to ${config.appPath}`);\n console.log(`New stack ${config.stackName.pascal} will be written to ${config.stackPath}`);\n\n // bin directory\n await constructApp({\n appName: config.appName,\n outputFile: \"cdk.ts\",\n outputDir: dirname(config.appPath),\n stack: config.stackName,\n imports: Imports.newAppImports(config.appName),\n stages: config.stages,\n });\n\n // lib directory\n await constructStack({\n imports: Imports.newStackImports(),\n appName: config.appName,\n outputFile: basename(config.stackPath),\n outputDir: dirname(config.stackPath),\n yamlTemplateLocation: config.yamlTemplateLocation,\n });\n\n // lib directory\n await constructTest({\n imports: Imports.newTestImports(config.appName),\n stackName: config.stackName,\n appName: config.appName,\n outputFile: basename(config.testPath),\n outputDir: dirname(config.stackPath),\n });\n\n const commands = getCommands(config.packageManager, config.cdkDir);\n\n if (config.init) {\n ux.action.start(chalk.yellow(\"Installing dependencies. This may take a while...\"));\n await commands.installDependencies();\n ux.action.stop();\n }\n\n // Run `eslint --fix` on the generated files instead of trying to generate code that completely satisfies the linter\n await execute(\n \"./node_modules/.bin/eslint\",\n [\"lib/** bin/**\", \"--ext .ts\", \"--no-error-on-unmatched-pattern\", \"--fix\"],\n {\n cwd: config.cdkDir,\n }\n );\n\n ux.action.start(chalk.yellow(\"Running lint check...\"));\n await commands.lint();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running tests...\"));\n await commands.test();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running initial synthesis...\"));\n await commands.synth();\n ux.action.stop();\n\n console.log(chalk.green(\"Success! Here's a summary of the created files:\"));\n const tree = await execute(\"tree\", [\"-I 'node_modules|cdk.out'\"], {\n cwd: config.cdkDir,\n });\n console.log(tree);\n\n const docsUrl = \"https://github.com/guardian/cdk/tree/main/docs\";\n ux.url(chalk.green(`Please see the docs (${docsUrl}) for next steps.`), docsUrl);\n\n return Promise.resolve(0);\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bin/commands/new-project/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"fs\";\nimport { basename, dirname, join } from \"path\";\nimport { ux } from \"@oclif/core\";\nimport chalk from \"chalk\";\nimport kebabCase from \"lodash.kebabcase\";\nimport type { CliCommandResponse } from \"../../../types/cli\";\nimport { execute } from \"../../../utils/exec\";\nimport { gitRootOrCwd } from \"../../../utils/git\";\nimport { constructApp } from \"./utils/app\";\nimport { Imports } from \"./utils/imports\";\nimport { buildDirectory } from \"./utils/init\";\nimport { constructTest } from \"./utils/snapshot\";\nimport { constructStack } from \"./utils/stack\";\nimport type { Name } from \"./utils/utils\";\nimport { getCommands, pascalCase } from \"./utils/utils\";\n\nexport type PackageManager = \"npm\" | \"yarn\";\n\ninterface NewProjectProps {\n init: boolean;\n app: string;\n stack: string;\n stages: string[];\n yamlTemplateLocation?: string;\n packageManager: PackageManager;\n}\n\ninterface NewProjectConfig extends Omit<NewProjectProps, \"stack\" | \"app\"> {\n cdkDir: string;\n appPath: string;\n appName: Name;\n stackPath: string;\n stackName: Name;\n testPath: string;\n}\n\nconst checkPathExists = (path: string): void => {\n if (!existsSync(path)) {\n throw new Error(`File not found - ${path}`);\n }\n};\n\nconst checkPathDoesNotExist = (path: string): void => {\n if (existsSync(path)) {\n throw new Error(`There is already a file at - ${path}`);\n }\n};\n\nfunction validateConfig(config: NewProjectConfig): void {\n if (!config.init) {\n checkPathExists(config.cdkDir);\n }\n checkPathDoesNotExist(config.appPath); // TODO: Update the app file if it already exists\n checkPathDoesNotExist(config.stackPath);\n\n if (config.yamlTemplateLocation) {\n checkPathExists(config.yamlTemplateLocation);\n }\n}\n\nfunction getConfig(props: NewProjectProps): NewProjectConfig {\n const { init, app, stack, stages, yamlTemplateLocation, packageManager } = props;\n\n const rootDir = gitRootOrCwd();\n const cdkDir = join(rootDir, \"/cdk\");\n\n const appName = pascalCase(app);\n const kebabAppName = kebabCase(appName);\n const stackName = pascalCase(stack);\n const kebabStackName = kebabCase(stackName);\n\n const config: NewProjectConfig = {\n init,\n yamlTemplateLocation,\n stages,\n cdkDir,\n appName: {\n kebab: kebabAppName,\n pascal: appName,\n },\n appPath: `${cdkDir}/bin/${kebabAppName}.ts`,\n stackName: {\n kebab: kebabStackName,\n pascal: stackName,\n },\n stackPath: `${cdkDir}/lib/${kebabAppName}.ts`,\n testPath: `${cdkDir}/lib/${kebabAppName}.test.ts`,\n packageManager,\n };\n\n validateConfig(config);\n\n return config;\n}\n\nexport const newCdkProject = async (props: NewProjectProps): CliCommandResponse => {\n console.log(\"Starting CDK generator\");\n\n const config = getConfig(props);\n\n if (config.init) {\n buildDirectory({ outputDir: config.cdkDir });\n }\n\n console.log(`New app ${config.appName.pascal} will be written to ${config.appPath}`);\n console.log(`New stack ${config.stackName.pascal} will be written to ${config.stackPath}`);\n\n // bin directory\n await constructApp({\n appName: config.appName,\n outputFile: \"cdk.ts\",\n outputDir: dirname(config.appPath),\n stack: config.stackName,\n imports: Imports.newAppImports(config.appName),\n stages: config.stages,\n });\n\n // lib directory\n await constructStack({\n imports: Imports.newStackImports(),\n appName: config.appName,\n outputFile: basename(config.stackPath),\n outputDir: dirname(config.stackPath),\n yamlTemplateLocation: config.yamlTemplateLocation,\n });\n\n // lib directory\n await constructTest({\n imports: Imports.newTestImports(config.appName),\n stackName: config.stackName,\n appName: config.appName,\n outputFile: basename(config.testPath),\n outputDir: dirname(config.stackPath),\n });\n\n const commands = getCommands(config.packageManager, config.cdkDir);\n\n if (config.init) {\n ux.action.start(chalk.yellow(\"Installing dependencies. This may take a while...\"));\n await commands.installDependencies();\n ux.action.stop();\n }\n\n // Run `eslint --fix` on the generated files instead of trying to generate code that completely satisfies the linter\n await execute(\n \"./node_modules/.bin/eslint\",\n [\"lib/** bin/**\", \"--ext .ts\", \"--no-error-on-unmatched-pattern\", \"--fix\"],\n {\n cwd: config.cdkDir,\n },\n );\n\n ux.action.start(chalk.yellow(\"Running lint check...\"));\n await commands.lint();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running tests...\"));\n await commands.test();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running initial synthesis...\"));\n await commands.synth();\n ux.action.stop();\n\n console.log(chalk.green(\"Success! Here's a summary of the created files:\"));\n const tree = await execute(\"tree\", [\"-I 'node_modules|cdk.out'\"], {\n cwd: config.cdkDir,\n });\n console.log(tree);\n\n const docsUrl = \"https://github.com/guardian/cdk/tree/main/docs\";\n ux.url(chalk.green(`Please see the docs (${docsUrl}) for next steps.`), docsUrl);\n\n return Promise.resolve(0);\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/app.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAetC,MAAa,UAAU;IAKrB,YAAY,KAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAExF,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAClB;QAED,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAEzC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CACZ,OAAO,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,IAAI,KAAK,gBAAgB,KAAK,CAAC,KAAK,cAAc,KAAK,OAAO,CAC5G,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;CACF;AAlCD,gCAkCC;AAEM,MAAM,YAAY,GAAG,KAAK,EAAE,KAAsB,EAAiB,EAAE;IAC1E,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC;AACnC,CAAC,CAAC;AAHW,QAAA,YAAY,gBAGvB","sourcesContent":["import { CodeMaker } from \"codemaker\";\nimport type { Imports } from \"./imports\";\nimport type { Name } from \"./utils\";\n\ninterface AppBuilderProps {\n imports: Imports;\n appName: Name;\n stack: Name;\n stages: string[];\n outputFile: string;\n outputDir: string;\n comment?: string;\n migrated?: boolean;\n}\n\nexport class AppBuilder {\n config: AppBuilderProps;\n\n code: CodeMaker;\n\n constructor(props: AppBuilderProps) {\n this.config = props;\n\n this.code = new CodeMaker({ indentationLevel: 2 });\n this.code.closeBlockFormatter = (s?: string): string => s ?? \"}\";\n }\n\n async constructCdkFile(): Promise<void> {\n const { comment, outputFile, imports, appName, stack, outputDir, stages } = this.config;\n\n this.code.openFile(outputFile);\n if (comment) {\n this.code.line(comment);\n this.code.line();\n }\n\n imports.render(this.code);\n\n this.code.line(\"const app = new App();\");\n\n stages.forEach((stage) => {\n this.code.line(\n `new ${appName.pascal}(app, \"${appName.pascal}-${stage}\", { stack: \"${stack.kebab}\", stage: \"${stage}\" });`\n );\n });\n\n this.code.closeFile(outputFile);\n await this.code.save(outputDir);\n }\n}\n\nexport const constructApp = async (props: AppBuilderProps): Promise<void> => {\n const builder = new AppBuilder(props);\n await builder.constructCdkFile();\n};\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/app.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAetC,MAAa,UAAU;IAKrB,YAAY,KAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAExF,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAClB;QAED,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAEzC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CACZ,OAAO,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,IAAI,KAAK,gBAAgB,KAAK,CAAC,KAAK,cAAc,KAAK,OAAO,CAC5G,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;CACF;AAlCD,gCAkCC;AAEM,MAAM,YAAY,GAAG,KAAK,EAAE,KAAsB,EAAiB,EAAE;IAC1E,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC;AACnC,CAAC,CAAC;AAHW,QAAA,YAAY,gBAGvB","sourcesContent":["import { CodeMaker } from \"codemaker\";\nimport type { Imports } from \"./imports\";\nimport type { Name } from \"./utils\";\n\ninterface AppBuilderProps {\n imports: Imports;\n appName: Name;\n stack: Name;\n stages: string[];\n outputFile: string;\n outputDir: string;\n comment?: string;\n migrated?: boolean;\n}\n\nexport class AppBuilder {\n config: AppBuilderProps;\n\n code: CodeMaker;\n\n constructor(props: AppBuilderProps) {\n this.config = props;\n\n this.code = new CodeMaker({ indentationLevel: 2 });\n this.code.closeBlockFormatter = (s?: string): string => s ?? \"}\";\n }\n\n async constructCdkFile(): Promise<void> {\n const { comment, outputFile, imports, appName, stack, outputDir, stages } = this.config;\n\n this.code.openFile(outputFile);\n if (comment) {\n this.code.line(comment);\n this.code.line();\n }\n\n imports.render(this.code);\n\n this.code.line(\"const app = new App();\");\n\n stages.forEach((stage) => {\n this.code.line(\n `new ${appName.pascal}(app, \"${appName.pascal}-${stage}\", { stack: \"${stack.kebab}\", stage: \"${stage}\" });`,\n );\n });\n\n this.code.closeFile(outputFile);\n await this.code.save(outputDir);\n }\n}\n\nexport const constructApp = async (props: AppBuilderProps): Promise<void> => {\n const builder = new AppBuilder(props);\n await builder.constructCdkFile();\n};\n"]}
@@ -86,7 +86,7 @@ function createPackageJson(outputDirectory) {
86
86
  };
87
87
  const customDeps = {
88
88
  "source-map-support": "^0.5.20",
89
- "@guardian/prettier": "1.0.0",
89
+ "@guardian/prettier": "5.0.0",
90
90
  };
91
91
  const allDeps = { ...coreDeps, ...cdkDeps, ...customDeps };
92
92
  const devDependencies = Object.keys(allDeps)
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getDevDependency, LibraryInfo } from \"../../../../constants\";\n\nexport interface InitConfig {\n outputDir: string;\n}\n\n// TODO: Add project name flag\nexport class ProjectBuilder {\n templateDir = `${__dirname}/../template`;\n config: InitConfig;\n\n static validateConfig = (config: InitConfig): void => {\n const path = config.outputDir;\n if (existsSync(path) && readdirSync(path).length > 0) {\n throw new Error(`Directory ${path} is not empty`);\n }\n };\n\n constructor(config: InitConfig) {\n this.config = config;\n }\n\n buildDirectory(): void {\n ProjectBuilder.validateConfig(this.config);\n\n if (!existsSync(this.config.outputDir)) {\n console.log(`Creating ${this.config.outputDir}`);\n mkdirSync(this.config.outputDir);\n }\n\n console.log(\"Creating package.json\");\n createPackageJson(this.config.outputDir);\n\n console.log(\"Copying template files\");\n // TODO: Replace any params in files with .template extensions\n this.copyFiles(this.templateDir, this.config.outputDir);\n\n console.log(\"Success!\");\n }\n\n copyFiles(sourcePath: string, targetPath: string): void {\n for (const file of readdirSync(sourcePath)) {\n const path = join(sourcePath, file);\n\n if (path.endsWith(\".ignore\")) {\n continue;\n } else if (lstatSync(path).isDirectory()) {\n const nestedTargetPath = join(targetPath, file);\n if (!existsSync(nestedTargetPath)) {\n mkdirSync(nestedTargetPath);\n }\n this.copyFiles(path, nestedTargetPath);\n } else if (path.endsWith(\".template\")) {\n copyFileSync(path, join(targetPath, file.replace(\".template\", \"\")));\n } else {\n copyFileSync(path, join(targetPath, file));\n }\n }\n }\n}\n\nexport const buildDirectory = (config: InitConfig): void => {\n const builder = new ProjectBuilder(config);\n builder.buildDirectory();\n};\n\nfunction createPackageJson(outputDirectory: string): void {\n const { NODE_ENV, CI } = process.env;\n const isTest = NODE_ENV?.toUpperCase() === \"TEST\" || CI?.toUpperCase() === \"TRUE\";\n\n const coreDeps: Record<string, string> = [\n \"@guardian/eslint-config-typescript\",\n \"@types/jest\",\n \"@types/node\",\n \"eslint\",\n \"jest\",\n \"prettier\",\n \"ts-jest\",\n \"ts-node\",\n \"typescript\",\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- deps come from `package.json`, so shouldn't be `undefined`\n ].reduce((acc, depName) => ({ ...acc, [depName]: getDevDependency(depName)! }), {});\n\n const cdkDeps: Record<string, string> = {\n /*\n Do not add `@guardian/cdk` to the generated `package.json` file when in TEST as we'll `npm link` it instead.\n See https://docs.npmjs.com/cli/v8/commands/npm-link#caveat\n\n TODO remove this once the `new` command allows opting out of automatic dependency installation\n */\n ...(!isTest && { \"@guardian/cdk\": LibraryInfo.VERSION }),\n\n \"aws-cdk\": LibraryInfo.AWS_CDK_VERSION,\n \"aws-cdk-lib\": LibraryInfo.AWS_CDK_VERSION,\n constructs: LibraryInfo.CONSTRUCTS_VERSION,\n };\n\n const customDeps = {\n \"source-map-support\": \"^0.5.20\",\n \"@guardian/prettier\": \"1.0.0\",\n };\n\n const allDeps: Record<string, string> = { ...coreDeps, ...cdkDeps, ...customDeps };\n\n const devDependencies: Record<string, string> = Object.keys(allDeps)\n .sort()\n .reduce((acc, depName) => ({ ...acc, [depName]: allDeps[depName] }), {});\n\n const contents = {\n name: \"cdk\",\n version: \"0.0.0\",\n private: true,\n scripts: {\n build: \"tsc\",\n test: \"jest\",\n \"test-update\": \"jest -u\",\n format: 'prettier --write \"{lib,bin}/**/*.ts\"',\n lint: \"eslint lib/** bin/** --ext .ts --no-error-on-unmatched-pattern\",\n synth: \"cdk synth --path-metadata false --version-reporting false\",\n diff: \"cdk diff --path-metadata false --version-reporting false\",\n },\n devDependencies,\n\n prettier: \"@guardian/prettier\",\n\n jest: {\n testMatch: [\"<rootDir>/lib/**/*.test.ts\"],\n transform: {\n \"^.+\\\\.tsx?$\": \"ts-jest\",\n },\n setupFilesAfterEnv: [\"./jest.setup.js\"],\n },\n\n eslintConfig: {\n root: true,\n env: {\n node: true,\n jest: true,\n },\n extends: [\"@guardian/eslint-config-typescript\"],\n parserOptions: {\n ecmaVersion: 2020,\n sourceType: \"module\",\n },\n plugins: [\"@typescript-eslint\"],\n rules: {\n \"@typescript-eslint/no-inferrable-types\": 0,\n \"import/no-namespace\": 2,\n },\n ignorePatterns: [\"**/*.js\", \"node_modules\", \"cdk.out\", \".eslintrc.js\", \"jest.config.js\"],\n },\n };\n writeFileSync(`${outputDirectory}/package.json`, JSON.stringify(contents, null, 2));\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getDevDependency, LibraryInfo } from \"../../../../constants\";\n\nexport interface InitConfig {\n outputDir: string;\n}\n\n// TODO: Add project name flag\nexport class ProjectBuilder {\n templateDir = `${__dirname}/../template`;\n config: InitConfig;\n\n static validateConfig = (config: InitConfig): void => {\n const path = config.outputDir;\n if (existsSync(path) && readdirSync(path).length > 0) {\n throw new Error(`Directory ${path} is not empty`);\n }\n };\n\n constructor(config: InitConfig) {\n this.config = config;\n }\n\n buildDirectory(): void {\n ProjectBuilder.validateConfig(this.config);\n\n if (!existsSync(this.config.outputDir)) {\n console.log(`Creating ${this.config.outputDir}`);\n mkdirSync(this.config.outputDir);\n }\n\n console.log(\"Creating package.json\");\n createPackageJson(this.config.outputDir);\n\n console.log(\"Copying template files\");\n // TODO: Replace any params in files with .template extensions\n this.copyFiles(this.templateDir, this.config.outputDir);\n\n console.log(\"Success!\");\n }\n\n copyFiles(sourcePath: string, targetPath: string): void {\n for (const file of readdirSync(sourcePath)) {\n const path = join(sourcePath, file);\n\n if (path.endsWith(\".ignore\")) {\n continue;\n } else if (lstatSync(path).isDirectory()) {\n const nestedTargetPath = join(targetPath, file);\n if (!existsSync(nestedTargetPath)) {\n mkdirSync(nestedTargetPath);\n }\n this.copyFiles(path, nestedTargetPath);\n } else if (path.endsWith(\".template\")) {\n copyFileSync(path, join(targetPath, file.replace(\".template\", \"\")));\n } else {\n copyFileSync(path, join(targetPath, file));\n }\n }\n }\n}\n\nexport const buildDirectory = (config: InitConfig): void => {\n const builder = new ProjectBuilder(config);\n builder.buildDirectory();\n};\n\nfunction createPackageJson(outputDirectory: string): void {\n const { NODE_ENV, CI } = process.env;\n const isTest = NODE_ENV?.toUpperCase() === \"TEST\" || CI?.toUpperCase() === \"TRUE\";\n\n const coreDeps: Record<string, string> = [\n \"@guardian/eslint-config-typescript\",\n \"@types/jest\",\n \"@types/node\",\n \"eslint\",\n \"jest\",\n \"prettier\",\n \"ts-jest\",\n \"ts-node\",\n \"typescript\",\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- deps come from `package.json`, so shouldn't be `undefined`\n ].reduce((acc, depName) => ({ ...acc, [depName]: getDevDependency(depName)! }), {});\n\n const cdkDeps: Record<string, string> = {\n /*\n Do not add `@guardian/cdk` to the generated `package.json` file when in TEST as we'll `npm link` it instead.\n See https://docs.npmjs.com/cli/v8/commands/npm-link#caveat\n\n TODO remove this once the `new` command allows opting out of automatic dependency installation\n */\n ...(!isTest && { \"@guardian/cdk\": LibraryInfo.VERSION }),\n\n \"aws-cdk\": LibraryInfo.AWS_CDK_VERSION,\n \"aws-cdk-lib\": LibraryInfo.AWS_CDK_VERSION,\n constructs: LibraryInfo.CONSTRUCTS_VERSION,\n };\n\n const customDeps = {\n \"source-map-support\": \"^0.5.20\",\n \"@guardian/prettier\": \"5.0.0\",\n };\n\n const allDeps: Record<string, string> = { ...coreDeps, ...cdkDeps, ...customDeps };\n\n const devDependencies: Record<string, string> = Object.keys(allDeps)\n .sort()\n .reduce((acc, depName) => ({ ...acc, [depName]: allDeps[depName] }), {});\n\n const contents = {\n name: \"cdk\",\n version: \"0.0.0\",\n private: true,\n scripts: {\n build: \"tsc\",\n test: \"jest\",\n \"test-update\": \"jest -u\",\n format: 'prettier --write \"{lib,bin}/**/*.ts\"',\n lint: \"eslint lib/** bin/** --ext .ts --no-error-on-unmatched-pattern\",\n synth: \"cdk synth --path-metadata false --version-reporting false\",\n diff: \"cdk diff --path-metadata false --version-reporting false\",\n },\n devDependencies,\n\n prettier: \"@guardian/prettier\",\n\n jest: {\n testMatch: [\"<rootDir>/lib/**/*.test.ts\"],\n transform: {\n \"^.+\\\\.tsx?$\": \"ts-jest\",\n },\n setupFilesAfterEnv: [\"./jest.setup.js\"],\n },\n\n eslintConfig: {\n root: true,\n env: {\n node: true,\n jest: true,\n },\n extends: [\"@guardian/eslint-config-typescript\"],\n parserOptions: {\n ecmaVersion: 2020,\n sourceType: \"module\",\n },\n plugins: [\"@typescript-eslint\"],\n rules: {\n \"@typescript-eslint/no-inferrable-types\": 0,\n \"import/no-namespace\": 2,\n },\n ignorePatterns: [\"**/*.js\", \"node_modules\", \"cdk.out\", \".eslintrc.js\", \"jest.config.js\"],\n },\n };\n writeFileSync(`${outputDirectory}/package.json`, JSON.stringify(contents, null, 2));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/snapshot.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAatC,MAAa,WAAW;IAMtB,YAAY,KAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAE7B,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAClB;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtC,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;QAExD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CACZ,qBAAqB,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,gBAAgB,SAAS,CAAC,KAAK,sBAAsB,CACjH,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QAE/D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;CACF;AA9CD,kCA8CC;AAEM,MAAM,aAAa,GAAG,KAAK,EAAE,KAAuB,EAAiB,EAAE;IAC5E,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC;AACnC,CAAC,CAAC;AAHW,QAAA,aAAa,iBAGxB","sourcesContent":["import { CodeMaker } from \"codemaker\";\nimport type { Imports } from \"./imports\";\nimport type { Name } from \"./utils\";\n\nexport interface TestBuilderProps {\n imports: Imports;\n appName: Name;\n stackName: Name;\n outputFile: string;\n outputDir: string;\n comment?: string;\n}\n\nexport class TestBuilder {\n config: TestBuilderProps;\n imports: Imports;\n\n code: CodeMaker;\n\n constructor(props: TestBuilderProps) {\n this.config = props;\n this.imports = props.imports;\n\n this.code = new CodeMaker({ indentationLevel: 2 });\n this.code.closeBlockFormatter = (s?: string): string => s ?? \"}\";\n }\n\n async constructCdkFile(): Promise<void> {\n this.code.openFile(this.config.outputFile);\n if (this.config.comment) {\n this.code.line(this.config.comment);\n this.code.line();\n }\n\n this.config.imports.render(this.code);\n\n this.addTest();\n\n this.code.closeFile(this.config.outputFile);\n await this.code.save(this.config.outputDir);\n }\n\n addTest(): void {\n const { appName, stackName } = this.config;\n\n this.code.openBlock(`describe(\"The ${appName.pascal} stack\", () =>`);\n this.code.openBlock(`it(\"matches the snapshot\", () =>`);\n\n this.code.line(\"const app = new App();\");\n this.code.line(\n `const stack = new ${appName.pascal}(app, \"${appName.pascal}\", { stack: \"${stackName.kebab}\", stage: \"TEST\" });`\n );\n\n this.code.line(`const template = Template.fromStack(stack);`);\n this.code.line(`expect(template.toJSON()).toMatchSnapshot();`);\n\n this.code.closeBlock(\"});\");\n this.code.closeBlock(\"});\");\n }\n}\n\nexport const constructTest = async (props: TestBuilderProps): Promise<void> => {\n const builder = new TestBuilder(props);\n await builder.constructCdkFile();\n};\n"]}
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/snapshot.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAatC,MAAa,WAAW;IAMtB,YAAY,KAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAE7B,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAClB;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtC,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;QAExD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CACZ,qBAAqB,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,gBAAgB,SAAS,CAAC,KAAK,sBAAsB,CACjH,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QAE/D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;CACF;AA9CD,kCA8CC;AAEM,MAAM,aAAa,GAAG,KAAK,EAAE,KAAuB,EAAiB,EAAE;IAC5E,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC;AACnC,CAAC,CAAC;AAHW,QAAA,aAAa,iBAGxB","sourcesContent":["import { CodeMaker } from \"codemaker\";\nimport type { Imports } from \"./imports\";\nimport type { Name } from \"./utils\";\n\nexport interface TestBuilderProps {\n imports: Imports;\n appName: Name;\n stackName: Name;\n outputFile: string;\n outputDir: string;\n comment?: string;\n}\n\nexport class TestBuilder {\n config: TestBuilderProps;\n imports: Imports;\n\n code: CodeMaker;\n\n constructor(props: TestBuilderProps) {\n this.config = props;\n this.imports = props.imports;\n\n this.code = new CodeMaker({ indentationLevel: 2 });\n this.code.closeBlockFormatter = (s?: string): string => s ?? \"}\";\n }\n\n async constructCdkFile(): Promise<void> {\n this.code.openFile(this.config.outputFile);\n if (this.config.comment) {\n this.code.line(this.config.comment);\n this.code.line();\n }\n\n this.config.imports.render(this.code);\n\n this.addTest();\n\n this.code.closeFile(this.config.outputFile);\n await this.code.save(this.config.outputDir);\n }\n\n addTest(): void {\n const { appName, stackName } = this.config;\n\n this.code.openBlock(`describe(\"The ${appName.pascal} stack\", () =>`);\n this.code.openBlock(`it(\"matches the snapshot\", () =>`);\n\n this.code.line(\"const app = new App();\");\n this.code.line(\n `const stack = new ${appName.pascal}(app, \"${appName.pascal}\", { stack: \"${stackName.kebab}\", stage: \"TEST\" });`,\n );\n\n this.code.line(`const template = Template.fromStack(stack);`);\n this.code.line(`expect(template.toJSON()).toMatchSnapshot();`);\n\n this.code.closeBlock(\"});\");\n this.code.closeBlock(\"});\");\n }\n}\n\nexport const constructTest = async (props: TestBuilderProps): Promise<void> => {\n const builder = new TestBuilder(props);\n await builder.constructCdkFile();\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/utils.ts"],"names":[],"mappings":";;;;;;AAAA,wEAAyC;AACzC,0EAA2C;AAC3C,iDAAiD;AAG1C,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE;IAChD,OAAO,IAAA,2BAAU,EAAC,IAAA,0BAAS,EAAC,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC,CAAC;AAFW,QAAA,UAAU,cAErB;AAOF,KAAK,UAAU,OAAO,CAAC,cAA8B,EAAE,GAAW,EAAE,IAAY;IAC9E,OAAO,MAAM,IAAA,cAAO,EAAC,GAAG,cAAc,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,SAAgB,WAAW,CACzB,cAA8B,EAC9B,GAAW;IAOX,OAAO;QACL,mBAAmB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,SAAS,CAAC;QAClE,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,UAAU,CAAC;QACpD,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,YAAY,CAAC;QACtD,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,WAAW,CAAC;KACvD,CAAC;AACJ,CAAC;AAfD,kCAeC","sourcesContent":["import camelCase from \"lodash.camelcase\";\nimport upperFirst from \"lodash.upperfirst\";\nimport { execute } from \"../../../../utils/exec\";\nimport type { PackageManager } from \"../index\";\n\nexport const pascalCase = (str: string): string => {\n return upperFirst(camelCase(str));\n};\n\nexport interface Name {\n kebab: string;\n pascal: string;\n}\n\nasync function runTask(packageManager: PackageManager, cwd: string, task: string): Promise<string> {\n return await execute(`${packageManager} ${task}`, [], { cwd });\n}\n\nexport function getCommands(\n packageManager: PackageManager,\n cwd: string\n): {\n installDependencies: () => Promise<string>;\n lint: () => Promise<string>;\n synth: () => Promise<string>;\n test: () => Promise<string>;\n} {\n return {\n installDependencies: () => runTask(packageManager, cwd, \"install\"),\n lint: () => runTask(packageManager, cwd, \"run lint\"),\n test: () => runTask(packageManager, cwd, \"test -- -u\"),\n synth: () => runTask(packageManager, cwd, \"run synth\"),\n };\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/utils.ts"],"names":[],"mappings":";;;;;;AAAA,wEAAyC;AACzC,0EAA2C;AAC3C,iDAAiD;AAG1C,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE;IAChD,OAAO,IAAA,2BAAU,EAAC,IAAA,0BAAS,EAAC,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC,CAAC;AAFW,QAAA,UAAU,cAErB;AAOF,KAAK,UAAU,OAAO,CAAC,cAA8B,EAAE,GAAW,EAAE,IAAY;IAC9E,OAAO,MAAM,IAAA,cAAO,EAAC,GAAG,cAAc,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,SAAgB,WAAW,CACzB,cAA8B,EAC9B,GAAW;IAOX,OAAO;QACL,mBAAmB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,SAAS,CAAC;QAClE,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,UAAU,CAAC;QACpD,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,YAAY,CAAC;QACtD,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,WAAW,CAAC;KACvD,CAAC;AACJ,CAAC;AAfD,kCAeC","sourcesContent":["import camelCase from \"lodash.camelcase\";\nimport upperFirst from \"lodash.upperfirst\";\nimport { execute } from \"../../../../utils/exec\";\nimport type { PackageManager } from \"../index\";\n\nexport const pascalCase = (str: string): string => {\n return upperFirst(camelCase(str));\n};\n\nexport interface Name {\n kebab: string;\n pascal: string;\n}\n\nasync function runTask(packageManager: PackageManager, cwd: string, task: string): Promise<string> {\n return await execute(`${packageManager} ${task}`, [], { cwd });\n}\n\nexport function getCommands(\n packageManager: PackageManager,\n cwd: string,\n): {\n installDependencies: () => Promise<string>;\n lint: () => Promise<string>;\n synth: () => Promise<string>;\n test: () => Promise<string>;\n} {\n return {\n installDependencies: () => runTask(packageManager, cwd, \"install\"),\n lint: () => runTask(packageManager, cwd, \"run lint\"),\n test: () => runTask(packageManager, cwd, \"test -- -u\"),\n synth: () => runTask(packageManager, cwd, \"run synth\"),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { LibraryInfo } from \"../constants\";\nimport type { CliCommandResponse } from \"../types/cli\";\nimport { awsCredentialProviderChain } from \"./aws-credential-provider\";\nimport { accountReadinessCommand } from \"./commands/account-readiness\";\nimport { awsCdkVersionCommand } from \"./commands/aws-cdk-version\";\nimport type { PackageManager } from \"./commands/new-project\";\nimport { newCdkProject } from \"./commands/new-project\";\n\nconst Commands = {\n AwsCdkVersion: \"aws-cdk-version\",\n AccountReadiness: \"account-readiness\",\n New: \"new\",\n};\n\nconst parseCommandLineArguments = () => {\n /*\n The type of `yargs.argv` is `T | Promise<T>`.\n To avoid creating custom type guards, use `Promise.resolve` which takes `T | PromiseLike<T>` and returns `Promise<T>`.\n That is, use `Promise.resolve` to provide a single type.\n See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/7b2f0d45985538a40df96244481bfc6cd309c250/types/yargs/index.d.ts#L74\n */\n return Promise.resolve(\n yargs\n .usage(\"$0 COMMAND [args]\")\n .command(Commands.AwsCdkVersion, \"Print the version of AWS CDK libraries being used\")\n .command(Commands.AccountReadiness, \"Perform checks on an AWS account to see if it is GuCDK ready\", (yargs) =>\n yargs\n .option(\"profile\", { type: \"string\", description: \"AWS profile\" })\n .option(\"region\", { type: \"string\", description: \"AWS region\", default: \"eu-west-1\" })\n )\n .command(\n Commands.New,\n \"Creates a new CDK project within a `cdk` directory at the root of the repository\",\n (yargs) =>\n yargs\n .option(\"init\", {\n type: \"boolean\",\n description: \"Create the cdk directory before building the app and stack files (defaults to true)\",\n default: true,\n })\n .option(\"app\", {\n type: \"string\",\n description: \"The name of your application e.g. Amigo\",\n demandOption: true,\n })\n .option(\"stack\", {\n type: \"string\",\n description:\n \"The Guardian stack being used (as defined in your riff-raff.yaml). This will be applied as a tag to all of your resources.\",\n demandOption: true,\n })\n .option(\"yaml-template-location\", {\n type: \"string\",\n description: \"Path to the YAML CloudFormation template\",\n })\n .option(\"stage\", {\n description:\n \"The stage(s) for your stack. Can be specified multiple times, e.g. --stage CODE --stage PROD\",\n type: \"array\",\n demandOption: true,\n })\n .option(\"package-manager\", {\n description:\n \"The Node package manager to use. Match this to the repository (package-lock.json = npm, yarn.lock = yarn). If the repository has neither file, and there is no strong convention in your team, we recommend npm.\",\n choices: [\"npm\", \"yarn\"],\n demandOption: true,\n })\n )\n .version(\n `${LibraryInfo.VERSION} (using aws-cdk-lib ${LibraryInfo.AWS_CDK_VERSION}, constructs ${LibraryInfo.CONSTRUCTS_VERSION})`\n )\n .demandCommand(1, \"\") // just print help\n .help()\n .alias(\"h\", \"help\").argv\n );\n};\n\nparseCommandLineArguments()\n .then((argv): CliCommandResponse => {\n const command = argv._[0];\n switch (command) {\n case Commands.AwsCdkVersion: {\n return awsCdkVersionCommand();\n }\n case Commands.AccountReadiness: {\n const { profile, region } = argv;\n return accountReadinessCommand({ credentialProvider: awsCredentialProviderChain(profile), region });\n }\n case Commands.New: {\n const { init, app, stack, yamlTemplateLocation, stage, packageManager } = argv;\n const stages = stage.map((_) => (_ as string).toUpperCase());\n return newCdkProject({\n init,\n app,\n stack,\n yamlTemplateLocation,\n stages,\n packageManager: packageManager as PackageManager,\n });\n }\n default:\n throw new Error(`Unknown command: ${command ?? \"\"}`);\n }\n })\n .then((commandResponse) => {\n if (typeof commandResponse === \"number\") {\n process.exitCode = commandResponse;\n } else if (typeof commandResponse === \"string\") {\n console.log(commandResponse);\n } else {\n const responseWithVersionInfo = { \"@guardian/cdk\": { version: LibraryInfo.VERSION }, ...commandResponse };\n console.log(JSON.stringify(responseWithVersionInfo));\n }\n })\n .catch((err) => {\n console.error(err);\n process.exitCode = 1;\n });\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { LibraryInfo } from \"../constants\";\nimport type { CliCommandResponse } from \"../types/cli\";\nimport { awsCredentialProviderChain } from \"./aws-credential-provider\";\nimport { accountReadinessCommand } from \"./commands/account-readiness\";\nimport { awsCdkVersionCommand } from \"./commands/aws-cdk-version\";\nimport type { PackageManager } from \"./commands/new-project\";\nimport { newCdkProject } from \"./commands/new-project\";\n\nconst Commands = {\n AwsCdkVersion: \"aws-cdk-version\",\n AccountReadiness: \"account-readiness\",\n New: \"new\",\n};\n\nconst parseCommandLineArguments = () => {\n /*\n The type of `yargs.argv` is `T | Promise<T>`.\n To avoid creating custom type guards, use `Promise.resolve` which takes `T | PromiseLike<T>` and returns `Promise<T>`.\n That is, use `Promise.resolve` to provide a single type.\n See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/7b2f0d45985538a40df96244481bfc6cd309c250/types/yargs/index.d.ts#L74\n */\n return Promise.resolve(\n yargs\n .usage(\"$0 COMMAND [args]\")\n .command(Commands.AwsCdkVersion, \"Print the version of AWS CDK libraries being used\")\n .command(Commands.AccountReadiness, \"Perform checks on an AWS account to see if it is GuCDK ready\", (yargs) =>\n yargs\n .option(\"profile\", { type: \"string\", description: \"AWS profile\" })\n .option(\"region\", { type: \"string\", description: \"AWS region\", default: \"eu-west-1\" }),\n )\n .command(\n Commands.New,\n \"Creates a new CDK project within a `cdk` directory at the root of the repository\",\n (yargs) =>\n yargs\n .option(\"init\", {\n type: \"boolean\",\n description: \"Create the cdk directory before building the app and stack files (defaults to true)\",\n default: true,\n })\n .option(\"app\", {\n type: \"string\",\n description: \"The name of your application e.g. Amigo\",\n demandOption: true,\n })\n .option(\"stack\", {\n type: \"string\",\n description:\n \"The Guardian stack being used (as defined in your riff-raff.yaml). This will be applied as a tag to all of your resources.\",\n demandOption: true,\n })\n .option(\"yaml-template-location\", {\n type: \"string\",\n description: \"Path to the YAML CloudFormation template\",\n })\n .option(\"stage\", {\n description:\n \"The stage(s) for your stack. Can be specified multiple times, e.g. --stage CODE --stage PROD\",\n type: \"array\",\n demandOption: true,\n })\n .option(\"package-manager\", {\n description:\n \"The Node package manager to use. Match this to the repository (package-lock.json = npm, yarn.lock = yarn). If the repository has neither file, and there is no strong convention in your team, we recommend npm.\",\n choices: [\"npm\", \"yarn\"],\n demandOption: true,\n }),\n )\n .version(\n `${LibraryInfo.VERSION} (using aws-cdk-lib ${LibraryInfo.AWS_CDK_VERSION}, constructs ${LibraryInfo.CONSTRUCTS_VERSION})`,\n )\n .demandCommand(1, \"\") // just print help\n .help()\n .alias(\"h\", \"help\").argv,\n );\n};\n\nparseCommandLineArguments()\n .then((argv): CliCommandResponse => {\n const command = argv._[0];\n switch (command) {\n case Commands.AwsCdkVersion: {\n return awsCdkVersionCommand();\n }\n case Commands.AccountReadiness: {\n const { profile, region } = argv;\n return accountReadinessCommand({ credentialProvider: awsCredentialProviderChain(profile), region });\n }\n case Commands.New: {\n const { init, app, stack, yamlTemplateLocation, stage, packageManager } = argv;\n const stages = stage.map((_) => (_ as string).toUpperCase());\n return newCdkProject({\n init,\n app,\n stack,\n yamlTemplateLocation,\n stages,\n packageManager: packageManager as PackageManager,\n });\n }\n default:\n throw new Error(`Unknown command: ${command ?? \"\"}`);\n }\n })\n .then((commandResponse) => {\n if (typeof commandResponse === \"number\") {\n process.exitCode = commandResponse;\n } else if (typeof commandResponse === \"string\") {\n console.log(commandResponse);\n } else {\n const responseWithVersionInfo = { \"@guardian/cdk\": { version: LibraryInfo.VERSION }, ...commandResponse };\n console.log(JSON.stringify(responseWithVersionInfo));\n }\n })\n .catch((err) => {\n console.error(err);\n process.exitCode = 1;\n });\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ssm-parameter-paths.js","sourceRoot":"","sources":["../../src/constants/ssm-parameter-paths.ts"],"names":[],"mappings":";;;AAwBa,QAAA,wBAAwB,GAAG,cAAc,CAAC;AAE1C,QAAA,yBAAyB,GAA2B;IAC/D,WAAW,EAAE;QACX,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,+DAA+D;QAC5E,QAAQ,EAAE,IAAI;KACf;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,uCAAuC;QAC7C,WAAW,EAAE,mEAAmE;KACjF;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,mCAAmC;QACzC,WAAW,EAAE,4EAA4E;QACzF,aAAa,EAAE,2BAA2B;KAC3C;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,qCAAqC;KACnD;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,qFAAqF;QAClG,aAAa,EAAE,yBAAyB;KACzC;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,GAAG,gCAAwB,aAAa;QAC9C,WAAW,EAAE,2FAA2F;KACzG;IACD,wBAAwB,EAAE;QACxB,IAAI,EAAE,GAAG,gCAAwB,0BAA0B;QAC3D,WAAW,EAAE,2CAA2C;KACzD;IACD,uBAAuB,EAAE;QACvB,IAAI,EAAE,GAAG,gCAAwB,yBAAyB;QAC1D,WAAW,EAAE,0CAA0C;KACxD;IACD,8BAA8B,EAAE;QAC9B,IAAI,EAAE,wCAAwC;QAC9C,WAAW,EAAE,uFAAuF;KACrG;IACD,gBAAgB,EAAE;QAChB,IAAI,EAAE,sCAAsC;QAC5C,WAAW,EACT,6HAA6H;QAC/H,QAAQ,EAAE,IAAI;KACf;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,oCAAoC;QAC1C,WAAW,EAAE,oFAAoF;KAClG;CACF,CAAC;AAEW,QAAA,uBAAuB,GAAuB,MAAM,CAAC,MAAM,CACtE,iCAAyB,CACJ,CAAC","sourcesContent":["export interface SsmParameterPath {\n path: string;\n description: string;\n optional?: boolean;\n\n // Recommended naming convention for target resource, such as an S3 bucket.\n // $account is substituted as the account name.\n namingPattern?: string;\n}\n\ninterface NamedSsmParameterPaths {\n Anghammarad: SsmParameterPath;\n LoggingStreamName: SsmParameterPath;\n DistributionBucket: SsmParameterPath;\n AccessLoggingBucket: SsmParameterPath;\n ConfigurationBucket: SsmParameterPath;\n PrimaryVpcId: SsmParameterPath;\n PrimaryVpcPrivateSubnets: SsmParameterPath;\n PrimaryVpcPublicSubnets: SsmParameterPath;\n FastlyCustomerId: SsmParameterPath;\n OrganisationDistributionBucket: SsmParameterPath;\n DeployToolsAccountId: SsmParameterPath;\n}\n\nexport const VPC_SSM_PARAMETER_PREFIX = \"/account/vpc\";\n\nexport const NAMED_SSM_PARAMETER_PATHS: NamedSsmParameterPaths = {\n Anghammarad: {\n path: \"/account/services/anghammarad.topic.arn\",\n description: \"SSM parameter containing the ARN of the Anghammarad SNS topic\",\n optional: true,\n },\n LoggingStreamName: {\n path: \"/account/services/logging.stream.name\",\n description: \"SSM parameter containing the Name (not ARN) on the kinesis stream\",\n },\n DistributionBucket: {\n path: \"/account/services/artifact.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding distribution artifacts\",\n namingPattern: \"com-gu-$account-artifacts\",\n },\n AccessLoggingBucket: {\n path: \"/account/services/access-logging/bucket\",\n description: \"S3 bucket to store your access logs\",\n },\n ConfigurationBucket: {\n path: \"/account/services/private.config.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding the app's private configuration\",\n namingPattern: \"com-gu-$account-configs\",\n },\n PrimaryVpcId: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/id`,\n description: \"Virtual Private Cloud to run EC2 instances within. Should NOT be the account default VPC.\",\n },\n PrimaryVpcPrivateSubnets: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/subnets/private`,\n description: \"A comma-separated list of private subnets\",\n },\n PrimaryVpcPublicSubnets: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/subnets/public`,\n description: \"A comma-separated list of public subnets\",\n },\n OrganisationDistributionBucket: {\n path: \"/organisation/services/artifact.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding organisation-level DevX artifacts\",\n },\n FastlyCustomerId: {\n path: \"/account/external/fastly/customer.id\",\n description:\n \"SSM parameter containing the Fastly Customer ID. Can be obtained from https://manage.fastly.com/account/company by an admin\",\n optional: true,\n },\n DeployToolsAccountId: {\n path: \"/organisation/accounts/deployTools\",\n description: \"Account ID of the Deploy Tools account. Useful as some shared resources live here.\",\n },\n};\n\nexport const ALL_SSM_PARAMETER_PATHS: SsmParameterPath[] = Object.values(\n NAMED_SSM_PARAMETER_PATHS\n) as SsmParameterPath[];\n"]}
1
+ {"version":3,"file":"ssm-parameter-paths.js","sourceRoot":"","sources":["../../src/constants/ssm-parameter-paths.ts"],"names":[],"mappings":";;;AAwBa,QAAA,wBAAwB,GAAG,cAAc,CAAC;AAE1C,QAAA,yBAAyB,GAA2B;IAC/D,WAAW,EAAE;QACX,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,+DAA+D;QAC5E,QAAQ,EAAE,IAAI;KACf;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,uCAAuC;QAC7C,WAAW,EAAE,mEAAmE;KACjF;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,mCAAmC;QACzC,WAAW,EAAE,4EAA4E;QACzF,aAAa,EAAE,2BAA2B;KAC3C;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,qCAAqC;KACnD;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,qFAAqF;QAClG,aAAa,EAAE,yBAAyB;KACzC;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,GAAG,gCAAwB,aAAa;QAC9C,WAAW,EAAE,2FAA2F;KACzG;IACD,wBAAwB,EAAE;QACxB,IAAI,EAAE,GAAG,gCAAwB,0BAA0B;QAC3D,WAAW,EAAE,2CAA2C;KACzD;IACD,uBAAuB,EAAE;QACvB,IAAI,EAAE,GAAG,gCAAwB,yBAAyB;QAC1D,WAAW,EAAE,0CAA0C;KACxD;IACD,8BAA8B,EAAE;QAC9B,IAAI,EAAE,wCAAwC;QAC9C,WAAW,EAAE,uFAAuF;KACrG;IACD,gBAAgB,EAAE;QAChB,IAAI,EAAE,sCAAsC;QAC5C,WAAW,EACT,6HAA6H;QAC/H,QAAQ,EAAE,IAAI;KACf;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,oCAAoC;QAC1C,WAAW,EAAE,oFAAoF;KAClG;CACF,CAAC;AAEW,QAAA,uBAAuB,GAAuB,MAAM,CAAC,MAAM,CACtE,iCAAyB,CACJ,CAAC","sourcesContent":["export interface SsmParameterPath {\n path: string;\n description: string;\n optional?: boolean;\n\n // Recommended naming convention for target resource, such as an S3 bucket.\n // $account is substituted as the account name.\n namingPattern?: string;\n}\n\ninterface NamedSsmParameterPaths {\n Anghammarad: SsmParameterPath;\n LoggingStreamName: SsmParameterPath;\n DistributionBucket: SsmParameterPath;\n AccessLoggingBucket: SsmParameterPath;\n ConfigurationBucket: SsmParameterPath;\n PrimaryVpcId: SsmParameterPath;\n PrimaryVpcPrivateSubnets: SsmParameterPath;\n PrimaryVpcPublicSubnets: SsmParameterPath;\n FastlyCustomerId: SsmParameterPath;\n OrganisationDistributionBucket: SsmParameterPath;\n DeployToolsAccountId: SsmParameterPath;\n}\n\nexport const VPC_SSM_PARAMETER_PREFIX = \"/account/vpc\";\n\nexport const NAMED_SSM_PARAMETER_PATHS: NamedSsmParameterPaths = {\n Anghammarad: {\n path: \"/account/services/anghammarad.topic.arn\",\n description: \"SSM parameter containing the ARN of the Anghammarad SNS topic\",\n optional: true,\n },\n LoggingStreamName: {\n path: \"/account/services/logging.stream.name\",\n description: \"SSM parameter containing the Name (not ARN) on the kinesis stream\",\n },\n DistributionBucket: {\n path: \"/account/services/artifact.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding distribution artifacts\",\n namingPattern: \"com-gu-$account-artifacts\",\n },\n AccessLoggingBucket: {\n path: \"/account/services/access-logging/bucket\",\n description: \"S3 bucket to store your access logs\",\n },\n ConfigurationBucket: {\n path: \"/account/services/private.config.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding the app's private configuration\",\n namingPattern: \"com-gu-$account-configs\",\n },\n PrimaryVpcId: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/id`,\n description: \"Virtual Private Cloud to run EC2 instances within. Should NOT be the account default VPC.\",\n },\n PrimaryVpcPrivateSubnets: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/subnets/private`,\n description: \"A comma-separated list of private subnets\",\n },\n PrimaryVpcPublicSubnets: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/subnets/public`,\n description: \"A comma-separated list of public subnets\",\n },\n OrganisationDistributionBucket: {\n path: \"/organisation/services/artifact.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding organisation-level DevX artifacts\",\n },\n FastlyCustomerId: {\n path: \"/account/external/fastly/customer.id\",\n description:\n \"SSM parameter containing the Fastly Customer ID. Can be obtained from https://manage.fastly.com/account/company by an admin\",\n optional: true,\n },\n DeployToolsAccountId: {\n path: \"/organisation/accounts/deployTools\",\n description: \"Account ID of the Deploy Tools account. Useful as some shared resources live here.\",\n },\n};\n\nexport const ALL_SSM_PARAMETER_PATHS: SsmParameterPath[] = Object.values(\n NAMED_SSM_PARAMETER_PATHS,\n) as SsmParameterPath[];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"asg.js","sourceRoot":"","sources":["../../../src/constructs/autoscaling/asg.ts"],"names":[],"mappings":"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","sourcesContent":["import { Token } from \"aws-cdk-lib\";\nimport { AutoScalingGroup } from \"aws-cdk-lib/aws-autoscaling\";\nimport type { AutoScalingGroupProps, CfnAutoScalingGroup } from \"aws-cdk-lib/aws-autoscaling\";\nimport { LaunchTemplate, OperatingSystemType, UserData } from \"aws-cdk-lib/aws-ec2\";\nimport type { InstanceType, ISecurityGroup, MachineImageConfig } from \"aws-cdk-lib/aws-ec2\";\nimport type { ApplicationTargetGroup } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { GuAsgCapacity } from \"../../types\";\nimport type { AmigoProps } from \"../../types/amigo\";\nimport { GuAppAwareConstruct } from \"../../utils/mixin/app-aware-construct\";\nimport { GuAmiParameter } from \"../core\";\nimport type { AppIdentity, GuStack } from \"../core\";\nimport { GuHttpsEgressSecurityGroup, GuWazuhAccess } from \"../ec2\";\nimport { GuInstanceRole } from \"../iam\";\n\n// Since we want to override the types of what gets passed in for the below props,\n// we need to use Omit<T, U> to remove them from the interface this extends\n// https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys\n// TODO avoid prop nesting to improve discoverability. See https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md#flat.\nexport interface GuAutoScalingGroupProps\n extends Omit<\n AutoScalingGroupProps,\n | \"imageId\"\n | \"osType\"\n | \"machineImage\"\n | \"userData\"\n | \"minCapacity\"\n | \"maxCapacity\"\n | \"desiredCapacity\"\n | \"requireImdsv2\"\n | \"securityGroup\"\n >,\n AppIdentity,\n GuAsgCapacity {\n imageId?: GuAmiParameter;\n imageRecipe?: string | AmigoProps;\n instanceType: InstanceType;\n userData: UserData | string;\n additionalSecurityGroups?: ISecurityGroup[];\n targetGroup?: ApplicationTargetGroup;\n withoutImdsv2?: boolean;\n httpPutResponseHopLimit?: number;\n}\n\n/**\n * Construct which creates an Auto Scaling group.\n *\n * By default, all EC2 instances in this group will use [[`GuInstanceRole`]],\n * which provides common permissions (e.g. the ability to download an artifact and write logs to the account's logging Kinesis stream).\n *\n * If additional IAM permissions are required, a custom role can be provided via the `role` prop.\n * You may wish to instantiate [[`GuInstanceRole`]] yourself as a basis for this custom role, as it allows custom permissions\n * to be passed in.\n *\n * All EC2 instances in this group will be automatically associated with two security groups:\n * 1. [[`GuHttpsEgressSecurityGroup`]], which allows outbound traffic over HTTPS.\n * 2. [[`GuWazuhAccess`]], which allows instances to communicate with Wazuh (for security monitoring).\n *\n * If additional ingress or egress rules are required, define custom security groups and pass them in via the\n * `additionalSecurityGroups` prop.\n *\n * All EC2 instances provisioned via this construct will use\n * [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html).\n */\nexport class GuAutoScalingGroup extends GuAppAwareConstruct(AutoScalingGroup) {\n public readonly app: string;\n public readonly amiParameter: GuAmiParameter;\n public readonly imageRecipe?: string | AmigoProps;\n\n constructor(scope: GuStack, id: string, props: GuAutoScalingGroupProps) {\n const {\n app,\n additionalSecurityGroups = [],\n blockDevices,\n imageId = new GuAmiParameter(scope, { app }),\n imageRecipe,\n instanceType,\n minimumInstances,\n maximumInstances,\n role = new GuInstanceRole(scope, { app }),\n targetGroup,\n userData: userDataLike,\n vpc,\n withoutImdsv2 = false,\n httpPutResponseHopLimit,\n } = props;\n\n // Ensure min and max are defined in the same way. Throwing an `Error` when necessary. For example when min is defined via a Mapping, but max is not.\n if (Token.isUnresolved(minimumInstances) && !Token.isUnresolved(maximumInstances)) {\n throw new Error(\n \"minimumInstances is defined via a Mapping, but maximumInstances is not. Create maximumInstances via a Mapping too.\"\n );\n }\n\n const userData = userDataLike instanceof UserData ? userDataLike : UserData.custom(userDataLike);\n\n // Generate an ID unique to this app\n const launchTemplateId = `${scope.stack}-${scope.stage}-${app}`;\n const launchTemplate = new LaunchTemplate(scope, launchTemplateId, {\n blockDevices,\n instanceType,\n machineImage: {\n getImage: (): MachineImageConfig => {\n return {\n osType: OperatingSystemType.LINUX,\n userData,\n imageId: imageId.valueAsString,\n };\n },\n },\n // Do not use the default AWS security group which allows egress on any port.\n // Favour HTTPS only egress rules by default.\n securityGroup: GuHttpsEgressSecurityGroup.forVpc(scope, { app, vpc }),\n requireImdsv2: !withoutImdsv2,\n userData,\n role,\n httpPutResponseHopLimit,\n });\n\n // Add Wazuh & additional consumer specified Security Groups\n // Note: Launch templates via CDK allow specifying only one SG, so use connections\n // https://github.com/aws/aws-cdk/issues/18712\n [GuWazuhAccess.getInstance(scope, vpc), ...additionalSecurityGroups].forEach((sg) =>\n launchTemplate.connections.addSecurityGroup(sg)\n );\n\n const asgProps = {\n ...props,\n launchTemplate,\n maxCapacity: maximumInstances ?? minimumInstances * 2,\n minCapacity: minimumInstances,\n\n // Omit userData, instanceType, blockDevices & role from asgProps\n // As this are specified by the LaunchTemplate and must not be duplicated\n blockDevices: undefined,\n instanceType: undefined,\n role: undefined,\n userData: undefined,\n };\n\n super(scope, id, asgProps);\n\n this.app = app;\n this.amiParameter = imageId;\n this.imageRecipe = imageRecipe;\n\n targetGroup && this.attachToApplicationTargetGroup(targetGroup);\n\n const cfnAsg = this.node.defaultChild as CfnAutoScalingGroup;\n\n // A CDK AutoScalingGroup comes with this update policy, whereas the CFN autscaling group\n // leaves it to the default value, which is actually false.\n // { UpdatePolicy: { autoScalingScheduledAction: { IgnoreUnmodifiedGroupSizeProperties: true }}\n cfnAsg.addDeletionOverride(\"UpdatePolicy\");\n }\n}\n"]}
1
+ {"version":3,"file":"asg.js","sourceRoot":"","sources":["../../../src/constructs/autoscaling/asg.ts"],"names":[],"mappings":"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","sourcesContent":["import { Token } from \"aws-cdk-lib\";\nimport { AutoScalingGroup } from \"aws-cdk-lib/aws-autoscaling\";\nimport type { AutoScalingGroupProps, CfnAutoScalingGroup } from \"aws-cdk-lib/aws-autoscaling\";\nimport { LaunchTemplate, OperatingSystemType, UserData } from \"aws-cdk-lib/aws-ec2\";\nimport type { InstanceType, ISecurityGroup, MachineImageConfig } from \"aws-cdk-lib/aws-ec2\";\nimport type { ApplicationTargetGroup } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { GuAsgCapacity } from \"../../types\";\nimport type { AmigoProps } from \"../../types/amigo\";\nimport { GuAppAwareConstruct } from \"../../utils/mixin/app-aware-construct\";\nimport { GuAmiParameter } from \"../core\";\nimport type { AppIdentity, GuStack } from \"../core\";\nimport { GuHttpsEgressSecurityGroup, GuWazuhAccess } from \"../ec2\";\nimport { GuInstanceRole } from \"../iam\";\n\n// Since we want to override the types of what gets passed in for the below props,\n// we need to use Omit<T, U> to remove them from the interface this extends\n// https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys\n// TODO avoid prop nesting to improve discoverability. See https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md#flat.\nexport interface GuAutoScalingGroupProps\n extends Omit<\n AutoScalingGroupProps,\n | \"imageId\"\n | \"osType\"\n | \"machineImage\"\n | \"userData\"\n | \"minCapacity\"\n | \"maxCapacity\"\n | \"desiredCapacity\"\n | \"requireImdsv2\"\n | \"securityGroup\"\n >,\n AppIdentity,\n GuAsgCapacity {\n imageId?: GuAmiParameter;\n imageRecipe?: string | AmigoProps;\n instanceType: InstanceType;\n userData: UserData | string;\n additionalSecurityGroups?: ISecurityGroup[];\n targetGroup?: ApplicationTargetGroup;\n withoutImdsv2?: boolean;\n httpPutResponseHopLimit?: number;\n}\n\n/**\n * Construct which creates an Auto Scaling group.\n *\n * By default, all EC2 instances in this group will use [[`GuInstanceRole`]],\n * which provides common permissions (e.g. the ability to download an artifact and write logs to the account's logging Kinesis stream).\n *\n * If additional IAM permissions are required, a custom role can be provided via the `role` prop.\n * You may wish to instantiate [[`GuInstanceRole`]] yourself as a basis for this custom role, as it allows custom permissions\n * to be passed in.\n *\n * All EC2 instances in this group will be automatically associated with two security groups:\n * 1. [[`GuHttpsEgressSecurityGroup`]], which allows outbound traffic over HTTPS.\n * 2. [[`GuWazuhAccess`]], which allows instances to communicate with Wazuh (for security monitoring).\n *\n * If additional ingress or egress rules are required, define custom security groups and pass them in via the\n * `additionalSecurityGroups` prop.\n *\n * All EC2 instances provisioned via this construct will use\n * [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html).\n */\nexport class GuAutoScalingGroup extends GuAppAwareConstruct(AutoScalingGroup) {\n public readonly app: string;\n public readonly amiParameter: GuAmiParameter;\n public readonly imageRecipe?: string | AmigoProps;\n\n constructor(scope: GuStack, id: string, props: GuAutoScalingGroupProps) {\n const {\n app,\n additionalSecurityGroups = [],\n blockDevices,\n imageId = new GuAmiParameter(scope, { app }),\n imageRecipe,\n instanceType,\n minimumInstances,\n maximumInstances,\n role = new GuInstanceRole(scope, { app }),\n targetGroup,\n userData: userDataLike,\n vpc,\n withoutImdsv2 = false,\n httpPutResponseHopLimit,\n } = props;\n\n // Ensure min and max are defined in the same way. Throwing an `Error` when necessary. For example when min is defined via a Mapping, but max is not.\n if (Token.isUnresolved(minimumInstances) && !Token.isUnresolved(maximumInstances)) {\n throw new Error(\n \"minimumInstances is defined via a Mapping, but maximumInstances is not. Create maximumInstances via a Mapping too.\",\n );\n }\n\n const userData = userDataLike instanceof UserData ? userDataLike : UserData.custom(userDataLike);\n\n // Generate an ID unique to this app\n const launchTemplateId = `${scope.stack}-${scope.stage}-${app}`;\n const launchTemplate = new LaunchTemplate(scope, launchTemplateId, {\n blockDevices,\n instanceType,\n machineImage: {\n getImage: (): MachineImageConfig => {\n return {\n osType: OperatingSystemType.LINUX,\n userData,\n imageId: imageId.valueAsString,\n };\n },\n },\n // Do not use the default AWS security group which allows egress on any port.\n // Favour HTTPS only egress rules by default.\n securityGroup: GuHttpsEgressSecurityGroup.forVpc(scope, { app, vpc }),\n requireImdsv2: !withoutImdsv2,\n userData,\n role,\n httpPutResponseHopLimit,\n });\n\n // Add Wazuh & additional consumer specified Security Groups\n // Note: Launch templates via CDK allow specifying only one SG, so use connections\n // https://github.com/aws/aws-cdk/issues/18712\n [GuWazuhAccess.getInstance(scope, vpc), ...additionalSecurityGroups].forEach((sg) =>\n launchTemplate.connections.addSecurityGroup(sg),\n );\n\n const asgProps = {\n ...props,\n launchTemplate,\n maxCapacity: maximumInstances ?? minimumInstances * 2,\n minCapacity: minimumInstances,\n\n // Omit userData, instanceType, blockDevices & role from asgProps\n // As this are specified by the LaunchTemplate and must not be duplicated\n blockDevices: undefined,\n instanceType: undefined,\n role: undefined,\n userData: undefined,\n };\n\n super(scope, id, asgProps);\n\n this.app = app;\n this.amiParameter = imageId;\n this.imageRecipe = imageRecipe;\n\n targetGroup && this.attachToApplicationTargetGroup(targetGroup);\n\n const cfnAsg = this.node.defaultChild as CfnAutoScalingGroup;\n\n // A CDK AutoScalingGroup comes with this update policy, whereas the CFN autscaling group\n // leaves it to the default value, which is actually false.\n // { UpdatePolicy: { autoScalingScheduledAction: { IgnoreUnmodifiedGroupSizeProperties: true }}\n cfnAsg.addDeletionOverride(\"UpdatePolicy\");\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/constructs/core/stack.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CfnElement, StackProps } from \"aws-cdk-lib\";\nimport { Annotations, App, Aspects, CfnParameter, LegacyStackSynthesizer, Stack, Tags } from \"aws-cdk-lib\";\nimport { Template } from \"aws-cdk-lib/assertions\";\nimport type { IConstruct } from \"constructs\";\nimport gitUrlParse from \"git-url-parse\";\nimport { CfnIncludeReporter } from \"../../aspects/cfn-include-reporter\";\nimport { CfnParameterReporter } from \"../../aspects/cfn-parameter-reporter\";\nimport { Metadata } from \"../../aspects/metadata\";\nimport { ContextKeys, MetadataKeys, TrackingTag } from \"../../constants\";\nimport { gitRemoteOriginUrl } from \"../../utils/git\";\nimport type { StackStageIdentity } from \"./identity\";\nimport type { GuStaticLogicalId } from \"./migrating\";\n\nexport interface GuStackProps extends Omit<StackProps, \"stackName\"> {\n /**\n * The Guardian stack being used (as defined in your riff-raff.yaml).\n * This will be applied as a tag to all of your resources.\n */\n stack: string;\n\n stage: string;\n\n /**\n * Optional name of the app. If defined, all resources will have an App tag.\n */\n app?: string;\n\n /**\n * The AWS CloudFormation stack name (as shown in the AWS CloudFormation UI).\n * @defaultValue the `GU_CFN_STACK_NAME` environment variable\n */\n cloudFormationStackName?: string;\n /**\n * Set this to true to stop the GuStack from tagging all of your AWS resources.\n * This should only be turned on as part of an initial migration from CloudFormation.\n */\n withoutTags?: boolean;\n\n /**\n * Set to disable CDK metadata. Only for internal use (for disabling for some\n * snapshot tests). We rely on tracking data to prioritise future work so\n * please do not override this.\n */\n withoutMetadata?: boolean;\n}\n\n/**\n * GuStack provides the `stack` and `stage` parameters to a template.\n * It also takes the `app` in the constructor.\n *\n * GuStack will add the Stack, Stage and App tags to all resources.\n *\n * GuStack also adds the tag `X-Gu-CDK-Version`.\n * This tag allows us to measure adoption of this library.\n * It's value is the version of guardian/cdk being used, as defined in `package.json`.\n * As a result, the change sets between version numbers will be fairly noisy,\n * as all resources receive a tag update.\n * It is recommended to upgrade the version of @guardian/cdk being used in two steps:\n * 1. Bump the library, apply the tag updates\n * 2. Make any other stack changes\n *\n * Typical usage is to extend GuStack:\n *\n * ```typescript\n * class MyStack extends GuStack {\n * constructor(scope: App, id: string, props: GuStackProps) {\n * super(scope, id, props)\n * }\n *\n * // add resources here\n * }\n * ```\n */\nexport class GuStack extends Stack implements StackStageIdentity {\n private readonly _stack: string;\n private readonly _stage: string;\n private readonly _app?: string;\n private readonly _repositoryName?: string;\n\n get stage(): string {\n return this._stage;\n }\n\n get stack(): string {\n return this._stack;\n }\n\n get app(): string | undefined {\n return this._app;\n }\n\n /**\n * The repository name, if it can be determined from the context or the git remote origin url.\n * If it cannot be determined from either of these sources, it will be `undefined`.\n */\n get repositoryName(): string | undefined {\n return this._repositoryName;\n }\n\n /**\n * A helper function to add a tag to all resources in a stack.\n *\n * Note: tags will be listed in alphabetical order during synthesis.\n *\n * @param key the tag name\n * @param value the value of the tag\n * @param applyToLaunchedInstances whether or not to apply the tag to instances launched in an ASG.\n * @protected\n */\n protected addTag(key: string, value: string, applyToLaunchedInstances: boolean = true): void {\n // TODO add validation for `key` and `value`\n // see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resource-tags.html\n Tags.of(this).add(key, value, { applyToLaunchedInstances });\n }\n\n /**\n * Returns all the parameters on this stack.\n *\n * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html\n */\n get parameters(): Record<string, CfnParameter> {\n return this.node\n .findAll()\n .filter((construct) => construct instanceof CfnParameter)\n .reduce((acc, param) => ({ ...acc, [param.node.id]: param as CfnParameter }), {});\n }\n\n // eslint-disable-next-line custom-rules/valid-constructors -- GuStack is the exception as it must take an App\n constructor(scope: App, id: string, props: GuStackProps) {\n const { cloudFormationStackName = process.env.GU_CFN_STACK_NAME, stack, stage, withoutTags } = props;\n\n super(scope, id, {\n ...props,\n stackName: cloudFormationStackName,\n\n // TODO Use `DefaultStackSynthesizer` or create own synthesizer?\n // see https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html#bootstrapping-custom-synth\n synthesizer: new LegacyStackSynthesizer(),\n });\n\n this._stack = stack;\n this._stage = stage.toUpperCase();\n this._repositoryName = this.tryGetRepositoryTag();\n\n if (!withoutTags) {\n this.addTag(TrackingTag.Key, TrackingTag.Value);\n\n this.addTag(\"Stack\", this.stack);\n this.addTag(\"Stage\", this.stage);\n if (this.app) {\n this.addTag(\"App\", this.app);\n }\n\n if (this.repositoryName) {\n this.addTag(MetadataKeys.REPOSITORY_NAME, this.repositoryName);\n }\n }\n\n if (!props.withoutMetadata) {\n Aspects.of(this).add(new Metadata(this));\n }\n\n Aspects.of(this).add(new CfnIncludeReporter());\n Aspects.of(this).add(new CfnParameterReporter());\n }\n\n /**\n * Returns the repository name.\n * The value is retrieved in the following order:\n * 1. From the context\n * 2. From git config\n *\n * @private\n */\n private tryGetRepositoryTag(): string | undefined {\n try {\n const urlFromContext = this.node.tryGetContext(ContextKeys.REPOSITORY_URL) as string | undefined;\n const repositoryUrl: string = urlFromContext ?? gitRemoteOriginUrl();\n return gitUrlParse(repositoryUrl).full_name;\n } catch {\n console.info(\n `Unable to find git repository name. Set the ${ContextKeys.REPOSITORY_URL} context value or configure a git remote`\n );\n return undefined;\n }\n }\n\n /**\n * Override the auto-generated logical ID for a resource, in the generated CloudFormation template, with a static one.\n *\n * Of particular use when migrating a JSON/YAML CloudFormation template into GuCDK.\n * It's generally advised to retain the logical ID for stateful resources, such as databases or buckets.\n *\n * Let's say we have a YAML template:\n *\n * ```yaml\n * AWSTemplateFormatVersion: '2010-09-09'\n * Resources:\n * UsesTable:\n * Type: AWS::DynamoDB::Table\n * Properties:\n * TableName: !Sub 'users-${stage}'\n * ```\n *\n * When moving to GuCDK we'll have this:\n *\n * class MyStack extends GuStack {\n * constructor(app: App, id: string, props: GuStackProps) {\n * super(app, id, props);\n *\n * const { stage } = this;\n *\n * new Table(this, \"UsersTable\", {\n * name: `users-${stage}`\n * });\n * }\n * }\n *\n * During synthesis, CDK auto-generates logical IDs, so we'll have a stack with a DynamoDB table named 'UsersTable<SOME GUID>', NOT `UsersTable`.\n * That is, the `UsersTable` table will be deleted.\n *\n * In order to retain the original ID from the YAML template, we will do:\n *\n * class MyStack extends GuStack {\n * constructor(app: App, id: string, props: GuStackProps) {\n * super(app, id, props);\n *\n * const { stage } = this;\n *\n * const table = new Table(this, \"UsersTable\", {\n * name: `users-${stage}`\n * });\n *\n * this.overrideLogicalId(table, { logicalId: \"UsersTable\", reason: \"Retaining a stateful resource from the YAML template\" });\n * }\n * }\n *\n * @param construct The (stateful) resource to retain the logical ID of.\n * @param logicalId The logical ID of the resource (as defined in the JSON/YAML template.\n * @param reason A small explanation to keep the logical ID. Mainly used to help future developers.\n */\n public overrideLogicalId(construct: IConstruct, { logicalId, reason }: GuStaticLogicalId): void {\n const {\n node: { id, defaultChild },\n } = construct;\n\n (defaultChild as CfnElement).overrideLogicalId(logicalId);\n Annotations.of(construct).addInfo(`Setting logical ID for ${id} to ${logicalId}. Reason: ${reason}`);\n }\n}\n\n/**\n * A GuStack but designed for Stack Set instances.\n *\n * In a stack set application, `GuStackForStackSetInstance` is used to represent the infrastructure to provision in target AWS accounts.\n */\nexport class GuStackForStackSetInstance extends GuStack {\n // eslint-disable-next-line custom-rules/valid-constructors -- GuStackForStackSet should have a unique `App`\n constructor(id: string, props: GuStackProps) {\n super(new App(), id, props);\n }\n\n get cfnJson(): string {\n return JSON.stringify(Template.fromStack(this).toJSON(), null, 2);\n }\n}\n"]}
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/constructs/core/stack.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CfnElement, StackProps } from \"aws-cdk-lib\";\nimport { Annotations, App, Aspects, CfnParameter, LegacyStackSynthesizer, Stack, Tags } from \"aws-cdk-lib\";\nimport { Template } from \"aws-cdk-lib/assertions\";\nimport type { IConstruct } from \"constructs\";\nimport gitUrlParse from \"git-url-parse\";\nimport { CfnIncludeReporter } from \"../../aspects/cfn-include-reporter\";\nimport { CfnParameterReporter } from \"../../aspects/cfn-parameter-reporter\";\nimport { Metadata } from \"../../aspects/metadata\";\nimport { ContextKeys, MetadataKeys, TrackingTag } from \"../../constants\";\nimport { gitRemoteOriginUrl } from \"../../utils/git\";\nimport type { StackStageIdentity } from \"./identity\";\nimport type { GuStaticLogicalId } from \"./migrating\";\n\nexport interface GuStackProps extends Omit<StackProps, \"stackName\"> {\n /**\n * The Guardian stack being used (as defined in your riff-raff.yaml).\n * This will be applied as a tag to all of your resources.\n */\n stack: string;\n\n stage: string;\n\n /**\n * Optional name of the app. If defined, all resources will have an App tag.\n */\n app?: string;\n\n /**\n * The AWS CloudFormation stack name (as shown in the AWS CloudFormation UI).\n * @defaultValue the `GU_CFN_STACK_NAME` environment variable\n */\n cloudFormationStackName?: string;\n /**\n * Set this to true to stop the GuStack from tagging all of your AWS resources.\n * This should only be turned on as part of an initial migration from CloudFormation.\n */\n withoutTags?: boolean;\n\n /**\n * Set to disable CDK metadata. Only for internal use (for disabling for some\n * snapshot tests). We rely on tracking data to prioritise future work so\n * please do not override this.\n */\n withoutMetadata?: boolean;\n}\n\n/**\n * GuStack provides the `stack` and `stage` parameters to a template.\n * It also takes the `app` in the constructor.\n *\n * GuStack will add the Stack, Stage and App tags to all resources.\n *\n * GuStack also adds the tag `X-Gu-CDK-Version`.\n * This tag allows us to measure adoption of this library.\n * It's value is the version of guardian/cdk being used, as defined in `package.json`.\n * As a result, the change sets between version numbers will be fairly noisy,\n * as all resources receive a tag update.\n * It is recommended to upgrade the version of @guardian/cdk being used in two steps:\n * 1. Bump the library, apply the tag updates\n * 2. Make any other stack changes\n *\n * Typical usage is to extend GuStack:\n *\n * ```typescript\n * class MyStack extends GuStack {\n * constructor(scope: App, id: string, props: GuStackProps) {\n * super(scope, id, props)\n * }\n *\n * // add resources here\n * }\n * ```\n */\nexport class GuStack extends Stack implements StackStageIdentity {\n private readonly _stack: string;\n private readonly _stage: string;\n private readonly _app?: string;\n private readonly _repositoryName?: string;\n\n get stage(): string {\n return this._stage;\n }\n\n get stack(): string {\n return this._stack;\n }\n\n get app(): string | undefined {\n return this._app;\n }\n\n /**\n * The repository name, if it can be determined from the context or the git remote origin url.\n * If it cannot be determined from either of these sources, it will be `undefined`.\n */\n get repositoryName(): string | undefined {\n return this._repositoryName;\n }\n\n /**\n * A helper function to add a tag to all resources in a stack.\n *\n * Note: tags will be listed in alphabetical order during synthesis.\n *\n * @param key the tag name\n * @param value the value of the tag\n * @param applyToLaunchedInstances whether or not to apply the tag to instances launched in an ASG.\n * @protected\n */\n protected addTag(key: string, value: string, applyToLaunchedInstances: boolean = true): void {\n // TODO add validation for `key` and `value`\n // see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resource-tags.html\n Tags.of(this).add(key, value, { applyToLaunchedInstances });\n }\n\n /**\n * Returns all the parameters on this stack.\n *\n * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html\n */\n get parameters(): Record<string, CfnParameter> {\n return this.node\n .findAll()\n .filter((construct) => construct instanceof CfnParameter)\n .reduce((acc, param) => ({ ...acc, [param.node.id]: param as CfnParameter }), {});\n }\n\n // eslint-disable-next-line custom-rules/valid-constructors -- GuStack is the exception as it must take an App\n constructor(scope: App, id: string, props: GuStackProps) {\n const { cloudFormationStackName = process.env.GU_CFN_STACK_NAME, stack, stage, withoutTags } = props;\n\n super(scope, id, {\n ...props,\n stackName: cloudFormationStackName,\n\n // TODO Use `DefaultStackSynthesizer` or create own synthesizer?\n // see https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html#bootstrapping-custom-synth\n synthesizer: new LegacyStackSynthesizer(),\n });\n\n this._stack = stack;\n this._stage = stage.toUpperCase();\n this._repositoryName = this.tryGetRepositoryTag();\n\n if (!withoutTags) {\n this.addTag(TrackingTag.Key, TrackingTag.Value);\n\n this.addTag(\"Stack\", this.stack);\n this.addTag(\"Stage\", this.stage);\n if (this.app) {\n this.addTag(\"App\", this.app);\n }\n\n if (this.repositoryName) {\n this.addTag(MetadataKeys.REPOSITORY_NAME, this.repositoryName);\n }\n }\n\n if (!props.withoutMetadata) {\n Aspects.of(this).add(new Metadata(this));\n }\n\n Aspects.of(this).add(new CfnIncludeReporter());\n Aspects.of(this).add(new CfnParameterReporter());\n }\n\n /**\n * Returns the repository name.\n * The value is retrieved in the following order:\n * 1. From the context\n * 2. From git config\n *\n * @private\n */\n private tryGetRepositoryTag(): string | undefined {\n try {\n const urlFromContext = this.node.tryGetContext(ContextKeys.REPOSITORY_URL) as string | undefined;\n const repositoryUrl: string = urlFromContext ?? gitRemoteOriginUrl();\n return gitUrlParse(repositoryUrl).full_name;\n } catch {\n console.info(\n `Unable to find git repository name. Set the ${ContextKeys.REPOSITORY_URL} context value or configure a git remote`,\n );\n return undefined;\n }\n }\n\n /**\n * Override the auto-generated logical ID for a resource, in the generated CloudFormation template, with a static one.\n *\n * Of particular use when migrating a JSON/YAML CloudFormation template into GuCDK.\n * It's generally advised to retain the logical ID for stateful resources, such as databases or buckets.\n *\n * Let's say we have a YAML template:\n *\n * ```yaml\n * AWSTemplateFormatVersion: '2010-09-09'\n * Resources:\n * UsesTable:\n * Type: AWS::DynamoDB::Table\n * Properties:\n * TableName: !Sub 'users-${stage}'\n * ```\n *\n * When moving to GuCDK we'll have this:\n *\n * class MyStack extends GuStack {\n * constructor(app: App, id: string, props: GuStackProps) {\n * super(app, id, props);\n *\n * const { stage } = this;\n *\n * new Table(this, \"UsersTable\", {\n * name: `users-${stage}`\n * });\n * }\n * }\n *\n * During synthesis, CDK auto-generates logical IDs, so we'll have a stack with a DynamoDB table named 'UsersTable<SOME GUID>', NOT `UsersTable`.\n * That is, the `UsersTable` table will be deleted.\n *\n * In order to retain the original ID from the YAML template, we will do:\n *\n * class MyStack extends GuStack {\n * constructor(app: App, id: string, props: GuStackProps) {\n * super(app, id, props);\n *\n * const { stage } = this;\n *\n * const table = new Table(this, \"UsersTable\", {\n * name: `users-${stage}`\n * });\n *\n * this.overrideLogicalId(table, { logicalId: \"UsersTable\", reason: \"Retaining a stateful resource from the YAML template\" });\n * }\n * }\n *\n * @param construct The (stateful) resource to retain the logical ID of.\n * @param logicalId The logical ID of the resource (as defined in the JSON/YAML template.\n * @param reason A small explanation to keep the logical ID. Mainly used to help future developers.\n */\n public overrideLogicalId(construct: IConstruct, { logicalId, reason }: GuStaticLogicalId): void {\n const {\n node: { id, defaultChild },\n } = construct;\n\n (defaultChild as CfnElement).overrideLogicalId(logicalId);\n Annotations.of(construct).addInfo(`Setting logical ID for ${id} to ${logicalId}. Reason: ${reason}`);\n }\n}\n\n/**\n * A GuStack but designed for Stack Set instances.\n *\n * In a stack set application, `GuStackForStackSetInstance` is used to represent the infrastructure to provision in target AWS accounts.\n */\nexport class GuStackForStackSetInstance extends GuStack {\n // eslint-disable-next-line custom-rules/valid-constructors -- GuStackForStackSet should have a unique `App`\n constructor(id: string, props: GuStackProps) {\n super(new App(), id, props);\n }\n\n get cfnJson(): string {\n return JSON.stringify(Template.fromStack(this).toJSON(), null, 2);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dns-records.js","sourceRoot":"","sources":["../../../src/constructs/dns/dns-records.ts"],"names":[],"mappings":";;;AACA,6CAA0C;AAC1C,2CAAuC;AAIvC,IAAY,UAEX;AAFD,WAAY,UAAU;IACpB,6BAAe,CAAA;AACjB,CAAC,EAFW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAErB;AASD;;;;;GAKG;AACH,MAAa,cAAe,SAAQ,sBAAS;IAC3C,YAAY,KAAc,EAAE,EAAU,EAAE,KAA0B;QAChE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACzD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAExB;;;;WAIG;QACH,MAAM,iBAAiB,GAAG,GAAG,IAAI,eAAe,CAAC;QACjD,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAE7B,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAEhC,iHAAiH;QACjH,IAAI,UAAU,KAAK,UAAU,CAAC,KAAK,EAAE;YACnC;;;;;;;;eAQG;YACH,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;gBAChC,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAC;aACH;SACF;QAED,6DAA6D;QAC7D,gHAAgH;QAChH,IAAI,yBAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE;YACxC,IAAI,EAAE,0BAA0B;YAChC,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI;gBACV,eAAe,EAAE,eAAe;gBAChC,UAAU,EAAE,UAAU;gBACtB,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE;gBACpB,KAAK,EAAE,KAAK;aACb;SACF,CAAC,CAAC;IACL,CAAC;CACF;AA9CD,wCA8CC;AASD;;;;GAIG;AACH,MAAa,OAAQ,SAAQ,cAAc;IACzC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmB;QACzD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAExD,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,IAAI;YACJ,UAAU,EAAE,UAAU,CAAC,KAAK;YAC5B,eAAe,EAAE,CAAC,cAAc,CAAC;YACjC,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AAXD,0BAWC","sourcesContent":["import type { Duration } from \"aws-cdk-lib\";\nimport { CfnResource } from \"aws-cdk-lib\";\nimport { Construct } from \"constructs\";\nimport type { GuDomainName } from \"../../types\";\nimport type { AppIdentity, GuStack } from \"../core\";\n\nexport enum RecordType {\n CNAME = \"CNAME\",\n}\n\nexport interface GuDnsRecordSetProps {\n name: string;\n recordType: RecordType;\n resourceRecords: string[];\n ttl: Duration;\n}\n\n/**\n * This construct can be used to create DNS records in NS1.\n *\n * Prefer to use [[`GuCname`]] when creating a CNAME for a load balancer,\n * as this requires less boilerplate.\n */\nexport class GuDnsRecordSet extends Construct {\n constructor(scope: GuStack, id: string, props: GuDnsRecordSetProps) {\n const { name, recordType, resourceRecords, ttl } = props;\n const { stage } = scope;\n\n /*\n Nodes in the CDK tree must have a unique ID. This class adds two nodes to the tree, so we have two IDs.\n `id`, by definition, must be unique. `name` represents a fully qualified domain name, which must also be unique.\n `id` being given to the level 1 construct means it also becomes the logicalId in the template.\n */\n const level2ConstructId = `${name}-DnsRecordSet`;\n const level1ConstructId = id;\n\n super(scope, level2ConstructId);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- more `RecordType`s will be added soon!\n if (recordType === RecordType.CNAME) {\n /*\n If you try to create a CNAME with multiple records within NS1, you are greeted with:\n\n According to RFC, a CNAME record should not return multiple answers.\n Doing so may cause problems during resolution.\n If you want to use multiple answers, you should ensure you have the correct filters in place (such as SELECT_FIRST_N 1) to limit them to a single answer at resolution time.\n\n `Guardian::DNS::RecordSet` does not implement \"correct filters\", so fail fast by throwing.\n */\n if (resourceRecords.length !== 1) {\n throw new Error(\n \"According to RFC, a CNAME record should not return multiple answers. Doing so may cause problems during resolution.\"\n );\n }\n }\n\n // The spec for this private resource type can be found here:\n // https://github.com/guardian/cfn-private-resource-types/tree/main/dns/guardian-dns-record-set-type/docs#syntax\n new CfnResource(scope, level1ConstructId, {\n type: \"Guardian::DNS::RecordSet\",\n properties: {\n Name: name,\n ResourceRecords: resourceRecords,\n RecordType: recordType,\n TTL: ttl.toSeconds(),\n Stage: stage,\n },\n });\n }\n}\n\nexport interface GuCnameProps extends GuDomainName, AppIdentity {\n /** The record your CNAME should point to, for example your Load Balancer DNS name */\n resourceRecord: string;\n /** The time to live for the DNS record */\n ttl: Duration;\n}\n\n/**\n * Construct for creating CNAME records in NS1.\n *\n * See [[`GuCnameProps`]] for configuration options.\n */\nexport class GuCname extends GuDnsRecordSet {\n constructor(scope: GuStack, id: string, props: GuCnameProps) {\n const { domainName: name, resourceRecord, ttl } = props;\n\n super(scope, id, {\n name,\n recordType: RecordType.CNAME,\n resourceRecords: [resourceRecord],\n ttl,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"dns-records.js","sourceRoot":"","sources":["../../../src/constructs/dns/dns-records.ts"],"names":[],"mappings":";;;AACA,6CAA0C;AAC1C,2CAAuC;AAIvC,IAAY,UAEX;AAFD,WAAY,UAAU;IACpB,6BAAe,CAAA;AACjB,CAAC,EAFW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAErB;AASD;;;;;GAKG;AACH,MAAa,cAAe,SAAQ,sBAAS;IAC3C,YAAY,KAAc,EAAE,EAAU,EAAE,KAA0B;QAChE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACzD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAExB;;;;WAIG;QACH,MAAM,iBAAiB,GAAG,GAAG,IAAI,eAAe,CAAC;QACjD,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAE7B,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAEhC,iHAAiH;QACjH,IAAI,UAAU,KAAK,UAAU,CAAC,KAAK,EAAE;YACnC;;;;;;;;eAQG;YACH,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;gBAChC,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAC;aACH;SACF;QAED,6DAA6D;QAC7D,gHAAgH;QAChH,IAAI,yBAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE;YACxC,IAAI,EAAE,0BAA0B;YAChC,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI;gBACV,eAAe,EAAE,eAAe;gBAChC,UAAU,EAAE,UAAU;gBACtB,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE;gBACpB,KAAK,EAAE,KAAK;aACb;SACF,CAAC,CAAC;IACL,CAAC;CACF;AA9CD,wCA8CC;AASD;;;;GAIG;AACH,MAAa,OAAQ,SAAQ,cAAc;IACzC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmB;QACzD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAExD,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,IAAI;YACJ,UAAU,EAAE,UAAU,CAAC,KAAK;YAC5B,eAAe,EAAE,CAAC,cAAc,CAAC;YACjC,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AAXD,0BAWC","sourcesContent":["import type { Duration } from \"aws-cdk-lib\";\nimport { CfnResource } from \"aws-cdk-lib\";\nimport { Construct } from \"constructs\";\nimport type { GuDomainName } from \"../../types\";\nimport type { AppIdentity, GuStack } from \"../core\";\n\nexport enum RecordType {\n CNAME = \"CNAME\",\n}\n\nexport interface GuDnsRecordSetProps {\n name: string;\n recordType: RecordType;\n resourceRecords: string[];\n ttl: Duration;\n}\n\n/**\n * This construct can be used to create DNS records in NS1.\n *\n * Prefer to use [[`GuCname`]] when creating a CNAME for a load balancer,\n * as this requires less boilerplate.\n */\nexport class GuDnsRecordSet extends Construct {\n constructor(scope: GuStack, id: string, props: GuDnsRecordSetProps) {\n const { name, recordType, resourceRecords, ttl } = props;\n const { stage } = scope;\n\n /*\n Nodes in the CDK tree must have a unique ID. This class adds two nodes to the tree, so we have two IDs.\n `id`, by definition, must be unique. `name` represents a fully qualified domain name, which must also be unique.\n `id` being given to the level 1 construct means it also becomes the logicalId in the template.\n */\n const level2ConstructId = `${name}-DnsRecordSet`;\n const level1ConstructId = id;\n\n super(scope, level2ConstructId);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- more `RecordType`s will be added soon!\n if (recordType === RecordType.CNAME) {\n /*\n If you try to create a CNAME with multiple records within NS1, you are greeted with:\n\n According to RFC, a CNAME record should not return multiple answers.\n Doing so may cause problems during resolution.\n If you want to use multiple answers, you should ensure you have the correct filters in place (such as SELECT_FIRST_N 1) to limit them to a single answer at resolution time.\n\n `Guardian::DNS::RecordSet` does not implement \"correct filters\", so fail fast by throwing.\n */\n if (resourceRecords.length !== 1) {\n throw new Error(\n \"According to RFC, a CNAME record should not return multiple answers. Doing so may cause problems during resolution.\",\n );\n }\n }\n\n // The spec for this private resource type can be found here:\n // https://github.com/guardian/cfn-private-resource-types/tree/main/dns/guardian-dns-record-set-type/docs#syntax\n new CfnResource(scope, level1ConstructId, {\n type: \"Guardian::DNS::RecordSet\",\n properties: {\n Name: name,\n ResourceRecords: resourceRecords,\n RecordType: recordType,\n TTL: ttl.toSeconds(),\n Stage: stage,\n },\n });\n }\n}\n\nexport interface GuCnameProps extends GuDomainName, AppIdentity {\n /** The record your CNAME should point to, for example your Load Balancer DNS name */\n resourceRecord: string;\n /** The time to live for the DNS record */\n ttl: Duration;\n}\n\n/**\n * Construct for creating CNAME records in NS1.\n *\n * See [[`GuCnameProps`]] for configuration options.\n */\nexport class GuCname extends GuDnsRecordSet {\n constructor(scope: GuStack, id: string, props: GuCnameProps) {\n const { domainName: name, resourceRecord, ttl } = props;\n\n super(scope, id, {\n name,\n recordType: RecordType.CNAME,\n resourceRecords: [resourceRecord],\n ttl,\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"vpc.js","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":";;;AAAA,iDAAkD;AAElD,kCAAgE;AAShE,0BAA0B;AAC1B,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,+BAAiB,CAAA;IACjB,iCAAmB,CAAA;AACrB,CAAC,EAHW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAGrB;AAQD;;;GAGG;AACI,MAAM,QAAQ,GAAG,CAAC,KAAwB,EAAU,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC;AAAlE,QAAA,QAAQ,YAA0D;AAE/E,MAAa,KAAK;IAChB,MAAM,CAAC,OAAO,CAAC,KAAc,EAAE,OAAiB;QAC9C;;;;;;;;;;;WAWG;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9B,gBAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,UAAU,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,KAAc,EAAE,KAAqB;QAC/D,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC;QAE/C,MAAM,OAAO,GAAG,IAAI,4BAAqB,CAAC,KAAK,EAAE,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,GAAG,IAAI,SAAS,EAAE;YACnF,WAAW,EAAE,aAAa,IAAI,CAAC,WAAW,EAAE,UAAU;YAEtD,uHAAuH;YACvH,OAAO,EAAE,gCAAgC,IAAI,CAAC,WAAW,EAAE,EAAE;YAC7D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,KAAc,EAAE,EAAU,EAAE,KAAqB;QAC7D,OAAO,aAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,EAAE,EAAE;YACtC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,GAAG,KAAK;SACT,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,KAAc,EAAE,EAAU,EAAE,KAA+B;QAChF,MAAM,GAAG,GAAG,qBAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;IACzE,CAAC;CACF;AA5CD,sBA4CC","sourcesContent":["import { Subnet, Vpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { ISubnet, IVpc, VpcAttributes } from \"aws-cdk-lib/aws-ec2\";\nimport { GuSubnetListParameter, GuVpcParameter } from \"../core\";\nimport type { GuStack } from \"../core\";\n\ninterface VpcFromIdProps extends Omit<VpcAttributes, \"availabilityZones\"> {\n availabilityZones?: string[];\n}\n\ntype VpcFromIdParameterProps = Omit<VpcFromIdProps, \"vpcId\">;\n\n// TODO convert to boolean\nexport enum SubnetType {\n PUBLIC = \"Public\",\n PRIVATE = \"Private\",\n}\n\n// TODO: Migrate this to use `AppIdentity`\nexport interface GuSubnetProps {\n type?: SubnetType;\n app?: string;\n}\n\n/*\n * Some stacks maybe have multiple patterns (such as `GuEc2App`), therefore creating multiple VPC and subnet resources.\n * This function ensures that, where desired, we can have unique IDs for each VPC and subnet declaration\n */\nexport const maybeApp = (props?: { app?: string }): string => props?.app ?? \"\";\n\nexport class GuVpc {\n static subnets(scope: GuStack, subnets: string[]): ISubnet[] {\n /**\n * As of ~1.77.0 of the aws/cdk, this line\n * [ previously Subnet.fromSubnetId(scope, `subnet-${subnetId}`, subnetId)) ]\n * resulted in the following error\n * \"Found an encoded list token string in a scalar string context. Use 'Fn.select(0, list)' (not 'list[0]') to extract elements from token lists.\"\n * See https://github.com/aws/aws-cdk/issues/11945 for more information\n *\n * As a hacky workaround, we have moved to using the fromSubnetAttributes method and hardcoded an empty value\n * for the routeTableId prop. This prevents the error and, when tested on existing stacks, results in no change to the CFN output\n *\n * TODO: Understand VPCs and Subnets better and develop a better solution to this problem\n */\n return subnets.map((subnetId) =>\n Subnet.fromSubnetAttributes(scope, `subnet-${subnetId}`, { subnetId, routeTableId: \" \" })\n );\n }\n\n static subnetsFromParameter(scope: GuStack, props?: GuSubnetProps): ISubnet[] {\n const type = props?.type ?? SubnetType.PRIVATE;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n\n // TODO use `NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets` or `NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets`\n default: `/account/vpc/primary/subnets/${type.toLowerCase()}`,\n fromSSM: true,\n });\n\n return GuVpc.subnets(scope, subnets.valueAsList);\n }\n\n static fromId(scope: GuStack, id: string, props: VpcFromIdProps): IVpc {\n return Vpc.fromVpcAttributes(scope, id, {\n availabilityZones: scope.availabilityZones,\n ...props,\n });\n }\n\n static fromIdParameter(scope: GuStack, id: string, props?: VpcFromIdParameterProps): IVpc {\n const vpc = GuVpcParameter.getInstance(scope);\n return GuVpc.fromId(scope, id, { ...props, vpcId: vpc.valueAsString });\n }\n}\n"]}
1
+ {"version":3,"file":"vpc.js","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":";;;AAAA,iDAAkD;AAElD,kCAAgE;AAShE,0BAA0B;AAC1B,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,+BAAiB,CAAA;IACjB,iCAAmB,CAAA;AACrB,CAAC,EAHW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAGrB;AAQD;;;GAGG;AACI,MAAM,QAAQ,GAAG,CAAC,KAAwB,EAAU,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC;AAAlE,QAAA,QAAQ,YAA0D;AAE/E,MAAa,KAAK;IAChB,MAAM,CAAC,OAAO,CAAC,KAAc,EAAE,OAAiB;QAC9C;;;;;;;;;;;WAWG;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9B,gBAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,UAAU,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,KAAc,EAAE,KAAqB;QAC/D,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC;QAE/C,MAAM,OAAO,GAAG,IAAI,4BAAqB,CAAC,KAAK,EAAE,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,GAAG,IAAI,SAAS,EAAE;YACnF,WAAW,EAAE,aAAa,IAAI,CAAC,WAAW,EAAE,UAAU;YAEtD,uHAAuH;YACvH,OAAO,EAAE,gCAAgC,IAAI,CAAC,WAAW,EAAE,EAAE;YAC7D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,KAAc,EAAE,EAAU,EAAE,KAAqB;QAC7D,OAAO,aAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,EAAE,EAAE;YACtC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,GAAG,KAAK;SACT,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,KAAc,EAAE,EAAU,EAAE,KAA+B;QAChF,MAAM,GAAG,GAAG,qBAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;IACzE,CAAC;CACF;AA5CD,sBA4CC","sourcesContent":["import { Subnet, Vpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { ISubnet, IVpc, VpcAttributes } from \"aws-cdk-lib/aws-ec2\";\nimport { GuSubnetListParameter, GuVpcParameter } from \"../core\";\nimport type { GuStack } from \"../core\";\n\ninterface VpcFromIdProps extends Omit<VpcAttributes, \"availabilityZones\"> {\n availabilityZones?: string[];\n}\n\ntype VpcFromIdParameterProps = Omit<VpcFromIdProps, \"vpcId\">;\n\n// TODO convert to boolean\nexport enum SubnetType {\n PUBLIC = \"Public\",\n PRIVATE = \"Private\",\n}\n\n// TODO: Migrate this to use `AppIdentity`\nexport interface GuSubnetProps {\n type?: SubnetType;\n app?: string;\n}\n\n/*\n * Some stacks maybe have multiple patterns (such as `GuEc2App`), therefore creating multiple VPC and subnet resources.\n * This function ensures that, where desired, we can have unique IDs for each VPC and subnet declaration\n */\nexport const maybeApp = (props?: { app?: string }): string => props?.app ?? \"\";\n\nexport class GuVpc {\n static subnets(scope: GuStack, subnets: string[]): ISubnet[] {\n /**\n * As of ~1.77.0 of the aws/cdk, this line\n * [ previously Subnet.fromSubnetId(scope, `subnet-${subnetId}`, subnetId)) ]\n * resulted in the following error\n * \"Found an encoded list token string in a scalar string context. Use 'Fn.select(0, list)' (not 'list[0]') to extract elements from token lists.\"\n * See https://github.com/aws/aws-cdk/issues/11945 for more information\n *\n * As a hacky workaround, we have moved to using the fromSubnetAttributes method and hardcoded an empty value\n * for the routeTableId prop. This prevents the error and, when tested on existing stacks, results in no change to the CFN output\n *\n * TODO: Understand VPCs and Subnets better and develop a better solution to this problem\n */\n return subnets.map((subnetId) =>\n Subnet.fromSubnetAttributes(scope, `subnet-${subnetId}`, { subnetId, routeTableId: \" \" }),\n );\n }\n\n static subnetsFromParameter(scope: GuStack, props?: GuSubnetProps): ISubnet[] {\n const type = props?.type ?? SubnetType.PRIVATE;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n\n // TODO use `NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets` or `NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets`\n default: `/account/vpc/primary/subnets/${type.toLowerCase()}`,\n fromSSM: true,\n });\n\n return GuVpc.subnets(scope, subnets.valueAsList);\n }\n\n static fromId(scope: GuStack, id: string, props: VpcFromIdProps): IVpc {\n return Vpc.fromVpcAttributes(scope, id, {\n availabilityZones: scope.availabilityZones,\n ...props,\n });\n }\n\n static fromIdParameter(scope: GuStack, id: string, props?: VpcFromIdParameterProps): IVpc {\n const vpc = GuVpcParameter.getInstance(scope);\n return GuVpc.fromId(scope, id, { ...props, vpcId: vpc.valueAsString });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ecs-task.js","sourceRoot":"","sources":["../../../src/constructs/ecs/ecs-task.ts"],"names":[],"mappings":"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","sourcesContent":["import { CfnOutput, Duration } from \"aws-cdk-lib\";\nimport { Alarm, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { SnsAction } from \"aws-cdk-lib/aws-cloudwatch-actions\";\nimport type { ISecurityGroup, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { IRepository } from \"aws-cdk-lib/aws-ecr\";\nimport type { RepositoryImageProps } from \"aws-cdk-lib/aws-ecs\";\nimport {\n Cluster,\n Compatibility,\n ContainerImage,\n FargatePlatformVersion,\n LogDrivers,\n TaskDefinition,\n} from \"aws-cdk-lib/aws-ecs\";\nimport type { PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport { IntegrationPattern, JsonPath, StateMachine, Timeout } from \"aws-cdk-lib/aws-stepfunctions\";\nimport type { TaskEnvironmentVariable } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { EcsFargateLaunchTarget, EcsRunTask } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { Construct } from \"constructs\";\nimport type { NoMonitoring } from \"../cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport { GuGetDistributablePolicyStatement } from \"../iam\";\n\n/**\n * Configuration to determine what container to use for the task\n * For example, to run the task in the latest node container:\n *\n * ```typescript\n * const containerConfiguration = {\n * id: 'node:latest'\n * }\n * ```\n *\n * Alternatively you can specify a repository and version, for example for an ECR repository:\n * ```typescript\n * import { Repository } from \"aws-cdk-lib/aws-ecr\";\n * const repository = new Repository(scope, `${app}-repository`, {\n repositoryName: app,\n });\n * const containerConfiguration = {\n * repository: Repository.fromRepositoryArn(\"<repository arn>\"),\n * version: '1'\n * }\n * ```\n */\n\nexport type RepositoryContainer = {\n repository: IRepository;\n version: string;\n type: \"repository\";\n};\n\nexport type RegistryContainer = {\n id?: string;\n imageProps?: RepositoryImageProps;\n type: \"registry\";\n};\n\nexport type ContainerConfiguration = RepositoryContainer | RegistryContainer;\n\nexport type GuEcsTaskMonitoringProps = { snsTopicArn: string; noMonitoring: false };\n\n/**\n * Configuration options for the [[`GuEcsTask`]] pattern.\n *\n * See [[`ContainerConfiguration`]] for details of how to configure the container used to run the task.\n *\n * `taskTimeoutInMinutes` does what is says on the tin. The default timeout is 15 minutes.\n *\n * The `taskCommand` prop allows you to specify a command to run when the task starts (this can also be done via a CMD statement in\n * your Dockerfile). For example:\n *\n * const props = {\n * //other props\n * taskCommand: `aws s3 cp s3://${distbucket}/${stack}/${stage}/${app}/task.sh . && ./task.sh\n }\n *\n * It is advisable to configure alarms for when the job fails/times out. To do this specify the alarmSnsTopicArn prop.\n *\n * `customTaskPolicies` allows your task to interact with other AWS services. By default a task\n * will have read access to the distribution bucket for your account.\n *\n * You can specify security groups to apply to task using the `securityGroups` prop.\n *\n * You can also set the memory and cpu units for your task. See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size\n * for further details.\n *\n * If you want to pass input from the step function into your EcsTask you can do so via the `environmentOverrides` prop, which allows you to wire up\n * step function input JSON to environment variables set on the container. For example,\n * const props = {\n * ...otherProps\n * environmentOverrides: [\n {\n name: \"VERSION\",\n value: JsonPath.stringAt(\"$.version\"),\n },\n }\n * With the above override, your task will attempt to find a `version` property in the JSON input passed to the step function, and apply it to the\n * VERSION environment variable. Alternatively, you could hard code a value for the variable in CDK.\n * See https://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html for further detail and other override options - this construct currently\n * only supports environment variables.\n */\nexport interface GuEcsTaskProps extends AppIdentity {\n vpc: IVpc;\n containerConfiguration: ContainerConfiguration;\n taskTimeoutInMinutes?: number;\n cpu?: number;\n memory?: number;\n taskCommand?: string;\n monitoringConfiguration: NoMonitoring | GuEcsTaskMonitoringProps;\n securityGroups?: ISecurityGroup[];\n customTaskPolicies?: PolicyStatement[];\n environmentOverrides?: TaskEnvironmentVariable[];\n storage?: number;\n}\n\n/**\n * Containers can be specified either via a repository and version or by container id (in which case it will\n * be fetched from docker hub).\n */\nconst getContainer = (config: ContainerConfiguration) => {\n if (config.type == \"repository\") {\n return ContainerImage.fromEcrRepository(config.repository, config.version);\n } else {\n return ContainerImage.fromRegistry(config.id ?? \"ubuntu:jammy\", config.imageProps);\n }\n};\n\n/**\n * Pattern which creates all of the resources needed for a fargate task\n *\n * The task will be wrapped in a step function to allow for easier triggering and alarming on failure.\n *\n * For all configuration options, see [[`GuEcsTaskProps`]].\n *\n * Note that if your task reliably completes in less than 15 minutes then you should probably use a [[`GuLambda`]] instead. This\n * pattern was mainly created to work around the 15 minute lambda timeout.\n *\n */\nexport class GuEcsTask extends Construct {\n stateMachine: StateMachine;\n\n constructor(scope: GuStack, id: string, props: GuEcsTaskProps) {\n super(scope, id);\n\n const {\n app,\n\n // see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-cpu for details\n cpu = 2048, // 2 cores and from 4-16GB memory\n memory = 4096, // 4GB\n storage, // default is 20 GB when not provided in props\n containerConfiguration,\n taskCommand,\n taskTimeoutInMinutes = 15,\n customTaskPolicies,\n vpc,\n monitoringConfiguration,\n securityGroups = [],\n environmentOverrides,\n } = props;\n\n if (storage && storage < 21) {\n throw new Error(\n \"Storage must be at least 21. See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html\"\n );\n }\n\n const { stack, stage } = scope;\n\n const cluster = new Cluster(scope, `${id}-Cluster`, {\n clusterName: `${app}-cluster-${stage}`,\n enableFargateCapacityProviders: true,\n vpc,\n });\n\n const taskDefinition = new TaskDefinition(scope, `${id}-TaskDefinition`, {\n compatibility: Compatibility.FARGATE,\n cpu: cpu.toString(),\n memoryMiB: memory.toString(),\n family: `${stack}-${stage}-${app}`,\n ephemeralStorageGiB: storage,\n });\n\n const containerDefinition = taskDefinition.addContainer(`${id}-TaskContainer`, {\n image: getContainer(containerConfiguration),\n entryPoint: taskCommand ? [\"/bin/sh\"] : undefined,\n command: taskCommand ? [\"-c\", taskCommand] : undefined, // if unset, falls back to CMD in docker file, or no command will be run\n cpu,\n memoryLimitMiB: memory,\n logging: LogDrivers.awsLogs({\n streamPrefix: app,\n logRetention: 14,\n }),\n });\n\n const distPolicy = new GuGetDistributablePolicyStatement(scope, { app });\n\n taskDefinition.addToTaskRolePolicy(distPolicy);\n (customTaskPolicies ?? []).forEach((p) => taskDefinition.addToTaskRolePolicy(p));\n\n const task = new EcsRunTask(scope, `${id}-task`, {\n cluster,\n launchTarget: new EcsFargateLaunchTarget({\n platformVersion: FargatePlatformVersion.LATEST,\n }),\n taskDefinition,\n integrationPattern: IntegrationPattern.RUN_JOB,\n resultPath: JsonPath.DISCARD,\n taskTimeout: Timeout.duration(Duration.minutes(taskTimeoutInMinutes)),\n securityGroups,\n containerOverrides: [\n {\n containerDefinition: containerDefinition,\n environment: environmentOverrides,\n },\n ],\n });\n\n this.stateMachine = new StateMachine(scope, `${id}-StateMachine`, {\n definition: task,\n stateMachineName: `${app}-${stage}`,\n });\n\n if (!monitoringConfiguration.noMonitoring) {\n const alarmTopic = Topic.fromTopicArn(\n scope,\n AppIdentity.suffixText(props, \"AlarmTopic\"),\n monitoringConfiguration.snsTopicArn\n );\n const alarms = [\n {\n name: `${app}-execution-failed`,\n description: `${app}-${stage} job failed `,\n metric: this.stateMachine.metricFailed({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n {\n name: `${app}-timeout`,\n description: `${app}-${stage} job timed out `,\n metric: this.stateMachine.metricTimedOut({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n ];\n\n alarms.forEach(({ name, description, metric }) => {\n const alarm = new Alarm(scope, name, {\n alarmDescription: description,\n actionsEnabled: true,\n metric: metric,\n // default for comparisonOperator is GreaterThanOrEqualToThreshold\n threshold: 1,\n evaluationPeriods: 1,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n });\n alarm.addAlarmAction(new SnsAction(alarmTopic));\n AppIdentity.taggedConstruct({ app }, alarm);\n });\n }\n\n // Tag all constructs with correct app tag\n [cluster, task, taskDefinition, this.stateMachine].forEach((c) => AppIdentity.taggedConstruct({ app }, c));\n\n new CfnOutput(scope, `${id}-StateMachineArnOutput`, {\n value: this.stateMachine.stateMachineArn,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ecs-task.js","sourceRoot":"","sources":["../../../src/constructs/ecs/ecs-task.ts"],"names":[],"mappings":";;;AAAA,6CAAkD;AAClD,+DAAqE;AACrE,+EAA+D;AAI/D,iDAO6B;AAE7B,iDAA4C;AAC5C,qEAAoG;AAEpG,iFAAyF;AACzF,2CAAuC;AAGvC,kCAAsC;AACtC,gCAA2D;AA+F3D;;;GAGG;AACH,MAAM,YAAY,GAAG,CAAC,MAA8B,EAAE,EAAE;IACtD,IAAI,MAAM,CAAC,IAAI,IAAI,YAAY,EAAE;QAC/B,OAAO,wBAAc,CAAC,iBAAiB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;KAC5E;SAAM;QACL,OAAO,wBAAc,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;KACpF;AACH,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAa,SAAU,SAAQ,sBAAS;IAGtC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAqB;QAC3D,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEjB,MAAM,EACJ,GAAG;QAEH,iJAAiJ;QACjJ,GAAG,GAAG,IAAI,EAAE,iCAAiC;QAC7C,MAAM,GAAG,IAAI,EAAE,MAAM;QACrB,OAAO,EAAE,8CAA8C;QACvD,sBAAsB,EACtB,WAAW,EACX,oBAAoB,GAAG,EAAE,EACzB,kBAAkB,EAClB,GAAG,EACH,uBAAuB,EACvB,cAAc,GAAG,EAAE,EACnB,oBAAoB,GACrB,GAAG,KAAK,CAAC;QAEV,IAAI,OAAO,IAAI,OAAO,GAAG,EAAE,EAAE;YAC3B,MAAM,IAAI,KAAK,CACb,yJAAyJ,CAC1J,CAAC;SACH;QAED,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAE/B,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE;YAClD,WAAW,EAAE,GAAG,GAAG,YAAY,KAAK,EAAE;YACtC,8BAA8B,EAAE,IAAI;YACpC,GAAG;SACJ,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,IAAI,wBAAc,CAAC,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE;YACvE,aAAa,EAAE,uBAAa,CAAC,OAAO;YACpC,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;YACnB,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE;YAC5B,MAAM,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,EAAE;YAClC,mBAAmB,EAAE,OAAO;SAC7B,CAAC,CAAC;QAEH,MAAM,mBAAmB,GAAG,cAAc,CAAC,YAAY,CAAC,GAAG,EAAE,gBAAgB,EAAE;YAC7E,KAAK,EAAE,YAAY,CAAC,sBAAsB,CAAC;YAC3C,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;YACjD,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;YACtD,GAAG;YACH,cAAc,EAAE,MAAM;YACtB,OAAO,EAAE,oBAAU,CAAC,OAAO,CAAC;gBAC1B,YAAY,EAAE,GAAG;gBACjB,YAAY,EAAE,EAAE;aACjB,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,IAAI,uCAAiC,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAEzE,cAAc,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC/C,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,MAAM,IAAI,GAAG,IAAI,oCAAU,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE;YAC/C,OAAO;YACP,YAAY,EAAE,IAAI,gDAAsB,CAAC;gBACvC,eAAe,EAAE,gCAAsB,CAAC,MAAM;aAC/C,CAAC;YACF,cAAc;YACd,kBAAkB,EAAE,sCAAkB,CAAC,OAAO;YAC9C,UAAU,EAAE,4BAAQ,CAAC,OAAO;YAC5B,WAAW,EAAE,2BAAO,CAAC,QAAQ,CAAC,sBAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;YACrE,cAAc;YACd,kBAAkB,EAAE;gBAClB;oBACE,mBAAmB,EAAE,mBAAmB;oBACxC,WAAW,EAAE,oBAAoB;iBAClC;aACF;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,GAAG,IAAI,gCAAY,CAAC,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE;YAChE,UAAU,EAAE,IAAI;YAChB,gBAAgB,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE;YACzC,MAAM,UAAU,GAAG,eAAK,CAAC,YAAY,CACnC,KAAK,EACL,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,YAAY,CAAC,EAC3C,uBAAuB,CAAC,WAAW,CACpC,CAAC;YACF,MAAM,MAAM,GAAG;gBACb;oBACE,IAAI,EAAE,GAAG,GAAG,mBAAmB;oBAC/B,WAAW,EAAE,GAAG,GAAG,IAAI,KAAK,cAAc;oBAC1C,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;wBACrC,MAAM,EAAE,sBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;wBACzB,SAAS,EAAE,KAAK;qBACjB,CAAC;iBACH;gBACD;oBACE,IAAI,EAAE,GAAG,GAAG,UAAU;oBACtB,WAAW,EAAE,GAAG,GAAG,IAAI,KAAK,iBAAiB;oBAC7C,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;wBACvC,MAAM,EAAE,sBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;wBACzB,SAAS,EAAE,KAAK;qBACjB,CAAC;iBACH;aACF,CAAC;YAEF,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC/C,MAAM,KAAK,GAAG,IAAI,sBAAK,CAAC,KAAK,EAAE,IAAI,EAAE;oBACnC,gBAAgB,EAAE,WAAW;oBAC7B,cAAc,EAAE,IAAI;oBACpB,MAAM,EAAE,MAAM;oBACd,kEAAkE;oBAClE,SAAS,EAAE,CAAC;oBACZ,iBAAiB,EAAE,CAAC;oBACpB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;iBACjD,CAAC,CAAC;gBACH,KAAK,CAAC,cAAc,CAAC,IAAI,kCAAS,CAAC,UAAU,CAAC,CAAC,CAAC;gBAChD,kBAAW,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;SACJ;QAED,0CAA0C;QAC1C,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAW,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAE3G,IAAI,uBAAS,CAAC,KAAK,EAAE,GAAG,EAAE,wBAAwB,EAAE;YAClD,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,eAAe;SACzC,CAAC,CAAC;IACL,CAAC;CACF;AApID,8BAoIC","sourcesContent":["import { CfnOutput, Duration } from \"aws-cdk-lib\";\nimport { Alarm, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { SnsAction } from \"aws-cdk-lib/aws-cloudwatch-actions\";\nimport type { ISecurityGroup, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { IRepository } from \"aws-cdk-lib/aws-ecr\";\nimport type { RepositoryImageProps } from \"aws-cdk-lib/aws-ecs\";\nimport {\n Cluster,\n Compatibility,\n ContainerImage,\n FargatePlatformVersion,\n LogDrivers,\n TaskDefinition,\n} from \"aws-cdk-lib/aws-ecs\";\nimport type { PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport { IntegrationPattern, JsonPath, StateMachine, Timeout } from \"aws-cdk-lib/aws-stepfunctions\";\nimport type { TaskEnvironmentVariable } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { EcsFargateLaunchTarget, EcsRunTask } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { Construct } from \"constructs\";\nimport type { NoMonitoring } from \"../cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport { GuGetDistributablePolicyStatement } from \"../iam\";\n\n/**\n * Configuration to determine what container to use for the task\n * For example, to run the task in the latest node container:\n *\n * ```typescript\n * const containerConfiguration = {\n * id: 'node:latest'\n * }\n * ```\n *\n * Alternatively you can specify a repository and version, for example for an ECR repository:\n * ```typescript\n * import { Repository } from \"aws-cdk-lib/aws-ecr\";\n * const repository = new Repository(scope, `${app}-repository`, {\n repositoryName: app,\n });\n * const containerConfiguration = {\n * repository: Repository.fromRepositoryArn(\"<repository arn>\"),\n * version: '1'\n * }\n * ```\n */\n\nexport type RepositoryContainer = {\n repository: IRepository;\n version: string;\n type: \"repository\";\n};\n\nexport type RegistryContainer = {\n id?: string;\n imageProps?: RepositoryImageProps;\n type: \"registry\";\n};\n\nexport type ContainerConfiguration = RepositoryContainer | RegistryContainer;\n\nexport type GuEcsTaskMonitoringProps = { snsTopicArn: string; noMonitoring: false };\n\n/**\n * Configuration options for the [[`GuEcsTask`]] pattern.\n *\n * See [[`ContainerConfiguration`]] for details of how to configure the container used to run the task.\n *\n * `taskTimeoutInMinutes` does what is says on the tin. The default timeout is 15 minutes.\n *\n * The `taskCommand` prop allows you to specify a command to run when the task starts (this can also be done via a CMD statement in\n * your Dockerfile). For example:\n *\n * const props = {\n * //other props\n * taskCommand: `aws s3 cp s3://${distbucket}/${stack}/${stage}/${app}/task.sh . && ./task.sh\n }\n *\n * It is advisable to configure alarms for when the job fails/times out. To do this specify the alarmSnsTopicArn prop.\n *\n * `customTaskPolicies` allows your task to interact with other AWS services. By default a task\n * will have read access to the distribution bucket for your account.\n *\n * You can specify security groups to apply to task using the `securityGroups` prop.\n *\n * You can also set the memory and cpu units for your task. See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size\n * for further details.\n *\n * If you want to pass input from the step function into your EcsTask you can do so via the `environmentOverrides` prop, which allows you to wire up\n * step function input JSON to environment variables set on the container. For example,\n * const props = {\n * ...otherProps\n * environmentOverrides: [\n {\n name: \"VERSION\",\n value: JsonPath.stringAt(\"$.version\"),\n },\n }\n * With the above override, your task will attempt to find a `version` property in the JSON input passed to the step function, and apply it to the\n * VERSION environment variable. Alternatively, you could hard code a value for the variable in CDK.\n * See https://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html for further detail and other override options - this construct currently\n * only supports environment variables.\n */\nexport interface GuEcsTaskProps extends AppIdentity {\n vpc: IVpc;\n containerConfiguration: ContainerConfiguration;\n taskTimeoutInMinutes?: number;\n cpu?: number;\n memory?: number;\n taskCommand?: string;\n monitoringConfiguration: NoMonitoring | GuEcsTaskMonitoringProps;\n securityGroups?: ISecurityGroup[];\n customTaskPolicies?: PolicyStatement[];\n environmentOverrides?: TaskEnvironmentVariable[];\n storage?: number;\n}\n\n/**\n * Containers can be specified either via a repository and version or by container id (in which case it will\n * be fetched from docker hub).\n */\nconst getContainer = (config: ContainerConfiguration) => {\n if (config.type == \"repository\") {\n return ContainerImage.fromEcrRepository(config.repository, config.version);\n } else {\n return ContainerImage.fromRegistry(config.id ?? \"ubuntu:jammy\", config.imageProps);\n }\n};\n\n/**\n * Pattern which creates all of the resources needed for a fargate task\n *\n * The task will be wrapped in a step function to allow for easier triggering and alarming on failure.\n *\n * For all configuration options, see [[`GuEcsTaskProps`]].\n *\n * Note that if your task reliably completes in less than 15 minutes then you should probably use a [[`GuLambda`]] instead. This\n * pattern was mainly created to work around the 15 minute lambda timeout.\n *\n */\nexport class GuEcsTask extends Construct {\n stateMachine: StateMachine;\n\n constructor(scope: GuStack, id: string, props: GuEcsTaskProps) {\n super(scope, id);\n\n const {\n app,\n\n // see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-cpu for details\n cpu = 2048, // 2 cores and from 4-16GB memory\n memory = 4096, // 4GB\n storage, // default is 20 GB when not provided in props\n containerConfiguration,\n taskCommand,\n taskTimeoutInMinutes = 15,\n customTaskPolicies,\n vpc,\n monitoringConfiguration,\n securityGroups = [],\n environmentOverrides,\n } = props;\n\n if (storage && storage < 21) {\n throw new Error(\n \"Storage must be at least 21. See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html\",\n );\n }\n\n const { stack, stage } = scope;\n\n const cluster = new Cluster(scope, `${id}-Cluster`, {\n clusterName: `${app}-cluster-${stage}`,\n enableFargateCapacityProviders: true,\n vpc,\n });\n\n const taskDefinition = new TaskDefinition(scope, `${id}-TaskDefinition`, {\n compatibility: Compatibility.FARGATE,\n cpu: cpu.toString(),\n memoryMiB: memory.toString(),\n family: `${stack}-${stage}-${app}`,\n ephemeralStorageGiB: storage,\n });\n\n const containerDefinition = taskDefinition.addContainer(`${id}-TaskContainer`, {\n image: getContainer(containerConfiguration),\n entryPoint: taskCommand ? [\"/bin/sh\"] : undefined,\n command: taskCommand ? [\"-c\", taskCommand] : undefined, // if unset, falls back to CMD in docker file, or no command will be run\n cpu,\n memoryLimitMiB: memory,\n logging: LogDrivers.awsLogs({\n streamPrefix: app,\n logRetention: 14,\n }),\n });\n\n const distPolicy = new GuGetDistributablePolicyStatement(scope, { app });\n\n taskDefinition.addToTaskRolePolicy(distPolicy);\n (customTaskPolicies ?? []).forEach((p) => taskDefinition.addToTaskRolePolicy(p));\n\n const task = new EcsRunTask(scope, `${id}-task`, {\n cluster,\n launchTarget: new EcsFargateLaunchTarget({\n platformVersion: FargatePlatformVersion.LATEST,\n }),\n taskDefinition,\n integrationPattern: IntegrationPattern.RUN_JOB,\n resultPath: JsonPath.DISCARD,\n taskTimeout: Timeout.duration(Duration.minutes(taskTimeoutInMinutes)),\n securityGroups,\n containerOverrides: [\n {\n containerDefinition: containerDefinition,\n environment: environmentOverrides,\n },\n ],\n });\n\n this.stateMachine = new StateMachine(scope, `${id}-StateMachine`, {\n definition: task,\n stateMachineName: `${app}-${stage}`,\n });\n\n if (!monitoringConfiguration.noMonitoring) {\n const alarmTopic = Topic.fromTopicArn(\n scope,\n AppIdentity.suffixText(props, \"AlarmTopic\"),\n monitoringConfiguration.snsTopicArn,\n );\n const alarms = [\n {\n name: `${app}-execution-failed`,\n description: `${app}-${stage} job failed `,\n metric: this.stateMachine.metricFailed({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n {\n name: `${app}-timeout`,\n description: `${app}-${stage} job timed out `,\n metric: this.stateMachine.metricTimedOut({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n ];\n\n alarms.forEach(({ name, description, metric }) => {\n const alarm = new Alarm(scope, name, {\n alarmDescription: description,\n actionsEnabled: true,\n metric: metric,\n // default for comparisonOperator is GreaterThanOrEqualToThreshold\n threshold: 1,\n evaluationPeriods: 1,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n });\n alarm.addAlarmAction(new SnsAction(alarmTopic));\n AppIdentity.taggedConstruct({ app }, alarm);\n });\n }\n\n // Tag all constructs with correct app tag\n [cluster, task, taskDefinition, this.stateMachine].forEach((c) => AppIdentity.taggedConstruct({ app }, c));\n\n new CfnOutput(scope, `${id}-StateMachineArnOutput`, {\n value: this.stateMachine.stateMachineArn,\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"base-policy.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/base-policy.ts"],"names":[],"mappings":";;;AAAA,iDAAsE;AAQtE,MAAa,QAAS,SAAQ,gBAAM;IAClC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAoB;QAC1D,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,4BAIC;AAQD,MAAa,aAAc,SAAQ,QAAQ;IACzC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAyB;QAC/D,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAExB,IAAI,CAAC,aAAa,CAChB,IAAI,yBAAe,CAAC;YAClB,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAZD,sCAYC;AAED,MAAa,YAAa,SAAQ,QAAQ;IACxC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAwB;QAC9D,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAExB,IAAI,CAAC,aAAa,CAChB,IAAI,yBAAe,CAAC;YAClB,MAAM,EAAE,gBAAM,CAAC,IAAI;YACnB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAZD,oCAYC","sourcesContent":["import { Effect, Policy, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport type { PolicyProps } from \"aws-cdk-lib/aws-iam\";\nimport type { GuStack } from \"../../core\";\n\nexport type GuPolicyProps = PolicyProps;\n\nexport type GuNoStatementsPolicyProps = Omit<GuPolicyProps, \"statements\">;\n\nexport class GuPolicy extends Policy {\n constructor(scope: GuStack, id: string, props: GuPolicyProps) {\n super(scope, id, props);\n }\n}\n\nexport interface GuAllowPolicyProps extends GuNoStatementsPolicyProps {\n actions: string[];\n resources: string[];\n}\nexport type GuDenyPolicyProps = GuAllowPolicyProps;\n\nexport class GuAllowPolicy extends GuPolicy {\n constructor(scope: GuStack, id: string, props: GuAllowPolicyProps) {\n super(scope, id, props);\n\n this.addStatements(\n new PolicyStatement({\n effect: Effect.ALLOW,\n resources: props.resources,\n actions: props.actions,\n })\n );\n }\n}\n\nexport class GuDenyPolicy extends GuPolicy {\n constructor(scope: GuStack, id: string, props: GuDenyPolicyProps) {\n super(scope, id, props);\n\n this.addStatements(\n new PolicyStatement({\n effect: Effect.DENY,\n resources: props.resources,\n actions: props.actions,\n })\n );\n }\n}\n"]}
1
+ {"version":3,"file":"base-policy.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/base-policy.ts"],"names":[],"mappings":";;;AAAA,iDAAsE;AAQtE,MAAa,QAAS,SAAQ,gBAAM;IAClC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAoB;QAC1D,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,4BAIC;AAQD,MAAa,aAAc,SAAQ,QAAQ;IACzC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAyB;QAC/D,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAExB,IAAI,CAAC,aAAa,CAChB,IAAI,yBAAe,CAAC;YAClB,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAZD,sCAYC;AAED,MAAa,YAAa,SAAQ,QAAQ;IACxC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAwB;QAC9D,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAExB,IAAI,CAAC,aAAa,CAChB,IAAI,yBAAe,CAAC;YAClB,MAAM,EAAE,gBAAM,CAAC,IAAI;YACnB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAZD,oCAYC","sourcesContent":["import { Effect, Policy, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport type { PolicyProps } from \"aws-cdk-lib/aws-iam\";\nimport type { GuStack } from \"../../core\";\n\nexport type GuPolicyProps = PolicyProps;\n\nexport type GuNoStatementsPolicyProps = Omit<GuPolicyProps, \"statements\">;\n\nexport class GuPolicy extends Policy {\n constructor(scope: GuStack, id: string, props: GuPolicyProps) {\n super(scope, id, props);\n }\n}\n\nexport interface GuAllowPolicyProps extends GuNoStatementsPolicyProps {\n actions: string[];\n resources: string[];\n}\nexport type GuDenyPolicyProps = GuAllowPolicyProps;\n\nexport class GuAllowPolicy extends GuPolicy {\n constructor(scope: GuStack, id: string, props: GuAllowPolicyProps) {\n super(scope, id, props);\n\n this.addStatements(\n new PolicyStatement({\n effect: Effect.ALLOW,\n resources: props.resources,\n actions: props.actions,\n }),\n );\n }\n}\n\nexport class GuDenyPolicy extends GuPolicy {\n constructor(scope: GuStack, id: string, props: GuDenyPolicyProps) {\n super(scope, id, props);\n\n this.addStatements(\n new PolicyStatement({\n effect: Effect.DENY,\n resources: props.resources,\n actions: props.actions,\n }),\n );\n }\n}\n"]}