@guardian/cdk 64.0.0 → 64.1.0

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 (102) 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/aspects/metadata.js.map +1 -1
  4. package/lib/bin/aws-credential-provider.d.ts.map +1 -1
  5. package/lib/bin/commands/account-readiness/index.d.ts.map +1 -1
  6. package/lib/bin/commands/account-readiness/index.js.map +1 -1
  7. package/lib/bin/commands/account-readiness/ssm.d.ts.map +1 -1
  8. package/lib/bin/commands/account-readiness/ssm.js.map +1 -1
  9. package/lib/bin/commands/aws-cdk-version.d.ts.map +1 -1
  10. package/lib/bin/commands/new-project/index.d.ts.map +1 -1
  11. package/lib/bin/commands/new-project/index.js.map +1 -1
  12. package/lib/bin/commands/new-project/utils/app.d.ts.map +1 -1
  13. package/lib/bin/commands/new-project/utils/app.js.map +1 -1
  14. package/lib/bin/commands/new-project/utils/imports.js.map +1 -1
  15. package/lib/bin/commands/new-project/utils/init.d.ts.map +1 -1
  16. package/lib/bin/commands/new-project/utils/init.js.map +1 -1
  17. package/lib/bin/commands/new-project/utils/snapshot.d.ts.map +1 -1
  18. package/lib/bin/commands/new-project/utils/snapshot.js.map +1 -1
  19. package/lib/bin/commands/new-project/utils/stack.d.ts.map +1 -1
  20. package/lib/bin/commands/new-project/utils/stack.js.map +1 -1
  21. package/lib/bin/commands/new-project/utils/utils.js +1 -2
  22. package/lib/bin/commands/new-project/utils/utils.js.map +1 -1
  23. package/lib/bin/index.js.map +1 -1
  24. package/lib/constants/library-info.js +3 -3
  25. package/lib/constants/library-info.js.map +1 -1
  26. package/lib/constructs/autoscaling/asg.js.map +1 -1
  27. package/lib/constructs/autoscaling/user-data.js.map +1 -1
  28. package/lib/constructs/cloudwatch/alarm.js.map +1 -1
  29. package/lib/constructs/core/identity.d.ts.map +1 -1
  30. package/lib/constructs/core/parameters/anghammarad.js.map +1 -1
  31. package/lib/constructs/core/parameters/fastly.js.map +1 -1
  32. package/lib/constructs/core/parameters/log-shipping.js.map +1 -1
  33. package/lib/constructs/core/parameters/s3.js.map +1 -1
  34. package/lib/constructs/core/parameters/vpc.js.map +1 -1
  35. package/lib/constructs/core/stack.js.map +1 -1
  36. package/lib/constructs/dns/dns-records.js.map +1 -1
  37. package/lib/constructs/ec2/security-groups/base.js.map +1 -1
  38. package/lib/constructs/ec2/vpc.d.ts.map +1 -1
  39. package/lib/constructs/ec2/vpc.js.map +1 -1
  40. package/lib/constructs/ecs/ecs-task.js +1 -1
  41. package/lib/constructs/ecs/ecs-task.js.map +1 -1
  42. package/lib/constructs/iam/policies/anghammarad.js.map +1 -1
  43. package/lib/constructs/iam/policies/describe-ec2.js.map +1 -1
  44. package/lib/constructs/iam/policies/kcl.js +1 -1
  45. package/lib/constructs/iam/policies/kcl.js.map +1 -1
  46. package/lib/constructs/iam/policies/log-shipping.js.map +1 -1
  47. package/lib/constructs/iam/policies/parameter-store-read.js.map +1 -1
  48. package/lib/constructs/iam/policies/ssm-ssh.js.map +1 -1
  49. package/lib/constructs/lambda/lambda.js.map +1 -1
  50. package/lib/constructs/loadbalancing/alb/application-load-balancer.js.map +1 -1
  51. package/lib/constructs/loadbalancing/alb/application-target-group.js +1 -1
  52. package/lib/constructs/loadbalancing/alb/application-target-group.js.map +1 -1
  53. package/lib/constructs/ses/index.js.map +1 -1
  54. package/lib/constructs/vpc/vpc.js.map +1 -1
  55. package/lib/experimental/constructs/iam/policies/developer-policy.js.map +1 -1
  56. package/lib/experimental/constructs/riff-raff-deployment-id.js.map +1 -1
  57. package/lib/experimental/patterns/ec2-app.js.map +1 -1
  58. package/lib/experimental/patterns/gu-load-balanced-app.d.ts.map +1 -1
  59. package/lib/experimental/patterns/gu-load-balanced-app.js +21 -4
  60. package/lib/experimental/patterns/gu-load-balanced-app.js.map +1 -1
  61. package/lib/patterns/api-lambda.js.map +1 -1
  62. package/lib/patterns/api-multiple-lambdas.js.map +1 -1
  63. package/lib/patterns/ec2-app/base.js +2 -2
  64. package/lib/patterns/ec2-app/base.js.map +1 -1
  65. package/lib/riff-raff-yaml-file/deployments/autoscaling.js +2 -3
  66. package/lib/riff-raff-yaml-file/deployments/autoscaling.js.map +1 -1
  67. package/lib/riff-raff-yaml-file/deployments/cloudformation.js +3 -4
  68. package/lib/riff-raff-yaml-file/deployments/cloudformation.js.map +1 -1
  69. package/lib/riff-raff-yaml-file/deployments/lambda.js +2 -3
  70. package/lib/riff-raff-yaml-file/deployments/lambda.js.map +1 -1
  71. package/lib/riff-raff-yaml-file/deployments/update-parameters.js +1 -2
  72. package/lib/riff-raff-yaml-file/deployments/update-parameters.js.map +1 -1
  73. package/lib/riff-raff-yaml-file/group-by.js +5 -6
  74. package/lib/riff-raff-yaml-file/group-by.js.map +1 -1
  75. package/lib/riff-raff-yaml-file/index.js +2 -2
  76. package/lib/riff-raff-yaml-file/index.js.map +1 -1
  77. package/lib/types/access.js.map +1 -1
  78. package/lib/utils/array.js +1 -2
  79. package/lib/utils/array.js.map +1 -1
  80. package/lib/utils/cli/vpc.d.ts.map +1 -1
  81. package/lib/utils/cli/vpc.js.map +1 -1
  82. package/lib/utils/cognito/cognito.d.ts.map +1 -1
  83. package/lib/utils/exec.js +2 -3
  84. package/lib/utils/exec.js.map +1 -1
  85. package/lib/utils/git.js +2 -3
  86. package/lib/utils/git.js.map +1 -1
  87. package/lib/utils/lambda/event-source.js +2 -2
  88. package/lib/utils/lambda/event-source.js.map +1 -1
  89. package/lib/utils/math.d.ts.map +1 -1
  90. package/lib/utils/mixin/app-aware-construct.js +1 -2
  91. package/lib/utils/mixin/app-aware-construct.js.map +1 -1
  92. package/lib/utils/security-groups/helpers.d.ts.map +1 -1
  93. package/lib/utils/singleton.d.ts +1 -1
  94. package/lib/utils/singleton.d.ts.map +1 -1
  95. package/lib/utils/string.d.ts.map +1 -1
  96. package/lib/utils/test/assertions.js.map +1 -1
  97. package/lib/utils/test/attach-policy-to-test-role.d.ts.map +1 -1
  98. package/lib/utils/test/simple-gu-stack.js +1 -2
  99. package/lib/utils/test/simple-gu-stack.js.map +1 -1
  100. package/lib/utils/test/template.js +1 -2
  101. package/lib/utils/test/template.js.map +1 -1
  102. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"anghammarad.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/anghammarad.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C;;;;;GAKG;AACH,MAAa,2BAA4B,SAAQ,wBAAiB;IAGhE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,qCAAyB,CAAC,WAAW,CAAC,IAAI;YACnD,WAAW,EAAE,qCAAyB,CAAC,WAAW,CAAC,WAAW;SAC/D,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,2BAA2B,CAAC,KAAK,CAAC,CAAC;SACxD;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAxBD,kEAwBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\n/**\n * Creates a CloudFormation parameter to a SSM Parameter Store item that holds the ARN of the Anghammarad SNS topic.\n * This parameter is implemented as a singleton, meaning only one can ever be added to a stack and will be reused if necessary.\n *\n * @see https://github.com/guardian/anghammarad\n */\nexport class GuAnghammaradTopicParameter extends GuStringParameter {\n private static instance: GuAnghammaradTopicParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"AnghammaradSnsArn\", {\n fromSSM: true,\n default: NAMED_SSM_PARAMETER_PATHS.Anghammarad.path,\n description: NAMED_SSM_PARAMETER_PATHS.Anghammarad.description,\n });\n }\n\n /**\n * Returns a pre-existing parameter in the stack.\n * If no parameter exists, creates a new parameter.\n *\n * @param stack the stack to operate on\n */\n public static getInstance(stack: GuStack): GuAnghammaradTopicParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuAnghammaradTopicParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"anghammarad.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/anghammarad.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C;;;;;GAKG;AACH,MAAa,2BAA4B,SAAQ,wBAAiB;IAGhE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,qCAAyB,CAAC,WAAW,CAAC,IAAI;YACnD,WAAW,EAAE,qCAAyB,CAAC,WAAW,CAAC,WAAW;SAC/D,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAxBD,kEAwBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\n/**\n * Creates a CloudFormation parameter to a SSM Parameter Store item that holds the ARN of the Anghammarad SNS topic.\n * This parameter is implemented as a singleton, meaning only one can ever be added to a stack and will be reused if necessary.\n *\n * @see https://github.com/guardian/anghammarad\n */\nexport class GuAnghammaradTopicParameter extends GuStringParameter {\n private static instance: GuAnghammaradTopicParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"AnghammaradSnsArn\", {\n fromSSM: true,\n default: NAMED_SSM_PARAMETER_PATHS.Anghammarad.path,\n description: NAMED_SSM_PARAMETER_PATHS.Anghammarad.description,\n });\n }\n\n /**\n * Returns a pre-existing parameter in the stack.\n * If no parameter exists, creates a new parameter.\n *\n * @param stack the stack to operate on\n */\n public static getInstance(stack: GuStack): GuAnghammaradTopicParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuAnghammaradTopicParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fastly.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/fastly.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C;;;;GAIG;AACH,MAAa,2BAA4B,SAAQ,wBAAiB;IAGhE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,kBAAkB,EAAE;YAC/B,WAAW,EAAE,qCAAyB,CAAC,gBAAgB,CAAC,WAAW;YACnE,OAAO,EAAE,qCAAyB,CAAC,gBAAgB,CAAC,IAAI;YACxD,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,2BAA2B,CAAC,KAAK,CAAC,CAAC;SACxD;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,kEAkBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\n/**\n * Creates a CloudFormation parameter which contains the Fastly customer ID to use in\n * setting up a Fastly logging role. By default, the customer ID is stored in an SSM\n * Parameter called `/account/external/fastly/customer.id`.\n */\nexport class GuFastlyCustomerIdParameter extends GuStringParameter {\n private static instance: GuFastlyCustomerIdParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"FastlyCustomerId\", {\n description: NAMED_SSM_PARAMETER_PATHS.FastlyCustomerId.description,\n default: NAMED_SSM_PARAMETER_PATHS.FastlyCustomerId.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuFastlyCustomerIdParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuFastlyCustomerIdParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"fastly.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/fastly.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C;;;;GAIG;AACH,MAAa,2BAA4B,SAAQ,wBAAiB;IAGhE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,kBAAkB,EAAE;YAC/B,WAAW,EAAE,qCAAyB,CAAC,gBAAgB,CAAC,WAAW;YACnE,OAAO,EAAE,qCAAyB,CAAC,gBAAgB,CAAC,IAAI;YACxD,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,kEAkBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\n/**\n * Creates a CloudFormation parameter which contains the Fastly customer ID to use in\n * setting up a Fastly logging role. By default, the customer ID is stored in an SSM\n * Parameter called `/account/external/fastly/customer.id`.\n */\nexport class GuFastlyCustomerIdParameter extends GuStringParameter {\n private static instance: GuFastlyCustomerIdParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"FastlyCustomerId\", {\n description: NAMED_SSM_PARAMETER_PATHS.FastlyCustomerId.description,\n default: NAMED_SSM_PARAMETER_PATHS.FastlyCustomerId.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuFastlyCustomerIdParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuFastlyCustomerIdParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"log-shipping.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/log-shipping.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C,MAAa,4BAA6B,SAAQ,wBAAiB;IAGjE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,WAAW,EAAE,qCAAyB,CAAC,iBAAiB,CAAC,WAAW;YACpE,OAAO,EAAE,qCAAyB,CAAC,iBAAiB,CAAC,IAAI;YACzD,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;SACzD;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,oEAkBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\nexport class GuLoggingStreamNameParameter extends GuStringParameter {\n private static instance: GuStringParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"LoggingStreamName\", {\n description: NAMED_SSM_PARAMETER_PATHS.LoggingStreamName.description,\n default: NAMED_SSM_PARAMETER_PATHS.LoggingStreamName.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuLoggingStreamNameParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuLoggingStreamNameParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"log-shipping.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/log-shipping.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C,MAAa,4BAA6B,SAAQ,wBAAiB;IAGjE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,WAAW,EAAE,qCAAyB,CAAC,iBAAiB,CAAC,WAAW;YACpE,OAAO,EAAE,qCAAyB,CAAC,iBAAiB,CAAC,IAAI;YACzD,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,oEAkBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\nexport class GuLoggingStreamNameParameter extends GuStringParameter {\n private static instance: GuStringParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"LoggingStreamName\", {\n description: NAMED_SSM_PARAMETER_PATHS.LoggingStreamName.description,\n default: NAMED_SSM_PARAMETER_PATHS.LoggingStreamName.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuLoggingStreamNameParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuLoggingStreamNameParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/s3.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C;;;GAGG;AACH,MAAa,6BAA8B,SAAQ,wBAAiB;IAGlE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,wBAAwB,EAAE;YACrC,WAAW,EAAE,qCAAyB,CAAC,kBAAkB,CAAC,WAAW;YACrE,OAAO,EAAE,qCAAyB,CAAC,kBAAkB,CAAC,IAAI;YAC1D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,6BAA6B,CAAC,KAAK,CAAC,CAAC;SAC1D;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,sEAkBC;AAED,MAAa,8BAA+B,SAAQ,wBAAiB;IAGnE,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,EAAE,8BAA8B,CAAC,aAAa,EAAE;YACzD,WAAW,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,WAAW;YACtE,OAAO,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,IAAI;YAC3D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;;AATH,wEAUC;AATe,4CAAa,GAAG,yBAAyB,CAAC;AAW1D;;;GAGG;AACH,MAAa,8BAA+B,SAAQ,wBAAiB;IAGnE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE;YAClC,WAAW,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,WAAW;YACtE,OAAO,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,IAAI;YAC3D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,8BAA8B,CAAC,KAAK,CAAC,CAAC;SAC3D;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,wEAkBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\n/**\n * Creates a CloudFormation parameter which references the bucket used to store code artifacts.\n * By default, the bucket name is stored in an SSM Parameter called `/account/services/artifact.bucket`.\n */\nexport class GuDistributionBucketParameter extends GuStringParameter {\n private static instance: GuDistributionBucketParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"DistributionBucketName\", {\n description: NAMED_SSM_PARAMETER_PATHS.DistributionBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.DistributionBucket.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuDistributionBucketParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuDistributionBucketParameter(stack);\n }\n\n return this.instance;\n }\n}\n\nexport class GuPrivateConfigBucketParameter extends GuStringParameter {\n public static parameterName = \"PrivateConfigBucketName\";\n\n constructor(scope: GuStack) {\n super(scope, GuPrivateConfigBucketParameter.parameterName, {\n description: NAMED_SSM_PARAMETER_PATHS.ConfigurationBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.ConfigurationBucket.path,\n fromSSM: true,\n });\n }\n}\n\n/**\n * Creates a CloudFormation parameter which references the bucket used to store load balancer access logs.\n * By default, the bucket name is stored in an SSM Parameter called `/account/services/access-logging/bucket`.\n */\nexport class GuAccessLoggingBucketParameter extends GuStringParameter {\n private static instance: GuAccessLoggingBucketParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"AccessLoggingBucket\", {\n description: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuAccessLoggingBucketParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuAccessLoggingBucketParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/s3.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAA2C;AAE3C;;;GAGG;AACH,MAAa,6BAA8B,SAAQ,wBAAiB;IAGlE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,wBAAwB,EAAE;YACrC,WAAW,EAAE,qCAAyB,CAAC,kBAAkB,CAAC,WAAW;YACrE,OAAO,EAAE,qCAAyB,CAAC,kBAAkB,CAAC,IAAI;YAC1D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,6BAA6B,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,sEAkBC;AAED,MAAa,8BAA+B,SAAQ,wBAAiB;IAGnE,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,EAAE,8BAA8B,CAAC,aAAa,EAAE;YACzD,WAAW,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,WAAW;YACtE,OAAO,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,IAAI;YAC3D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;;AATH,wEAUC;AATe,4CAAa,GAAG,yBAAyB,CAAC;AAW1D;;;GAGG;AACH,MAAa,8BAA+B,SAAQ,wBAAiB;IAGnE,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE;YAClC,WAAW,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,WAAW;YACtE,OAAO,EAAE,qCAAyB,CAAC,mBAAmB,CAAC,IAAI;YAC3D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,8BAA8B,CAAC,KAAK,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAlBD,wEAkBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\n/**\n * Creates a CloudFormation parameter which references the bucket used to store code artifacts.\n * By default, the bucket name is stored in an SSM Parameter called `/account/services/artifact.bucket`.\n */\nexport class GuDistributionBucketParameter extends GuStringParameter {\n private static instance: GuDistributionBucketParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"DistributionBucketName\", {\n description: NAMED_SSM_PARAMETER_PATHS.DistributionBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.DistributionBucket.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuDistributionBucketParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuDistributionBucketParameter(stack);\n }\n\n return this.instance;\n }\n}\n\nexport class GuPrivateConfigBucketParameter extends GuStringParameter {\n public static parameterName = \"PrivateConfigBucketName\";\n\n constructor(scope: GuStack) {\n super(scope, GuPrivateConfigBucketParameter.parameterName, {\n description: NAMED_SSM_PARAMETER_PATHS.ConfigurationBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.ConfigurationBucket.path,\n fromSSM: true,\n });\n }\n}\n\n/**\n * Creates a CloudFormation parameter which references the bucket used to store load balancer access logs.\n * By default, the bucket name is stored in an SSM Parameter called `/account/services/access-logging/bucket`.\n */\nexport class GuAccessLoggingBucketParameter extends GuStringParameter {\n private static instance: GuAccessLoggingBucketParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"AccessLoggingBucket\", {\n description: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.path,\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuAccessLoggingBucketParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuAccessLoggingBucketParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"vpc.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/vpc.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAAqC;AAGrC,MAAa,qBAAsB,SAAQ,kBAAW;IACpD,YAAY,KAAc,EAAE,EAAU,EAAE,KAA6B;QACnE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC,CAAC;IACrE,CAAC;CACF;AAJD,sDAIC;AAED;;;;GAIG;AACH,MAAa,cAAe,SAAQ,kBAAW;IAG7C,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE;YACpB,WAAW,EAAE,qCAAyB,CAAC,YAAY,CAAC,WAAW;YAC/D,OAAO,EAAE,qCAAyB,CAAC,YAAY,CAAC,IAAI;YACpD,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;SAC3C;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAnBD,wCAmBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuParameter } from \"./base\";\nimport type { GuNoTypeParameterProps } from \"./base\";\n\nexport class GuSubnetListParameter extends GuParameter {\n constructor(scope: GuStack, id: string, props: GuNoTypeParameterProps) {\n super(scope, id, { ...props, type: \"List<AWS::EC2::Subnet::Id>\" });\n }\n}\n\n/**\n * Adds a \"VpcId\" parameter to a stack.\n * This parameter will read from Parameter Store.\n * By default it will read from `/account/vpc/primary/id`, this can be changed at runtime if needed.\n */\nexport class GuVpcParameter extends GuParameter {\n private static instance: GuVpcParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"VpcId\", {\n description: NAMED_SSM_PARAMETER_PATHS.PrimaryVpcId.description,\n default: NAMED_SSM_PARAMETER_PATHS.PrimaryVpcId.path,\n type: \"AWS::EC2::VPC::Id\",\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuVpcParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuVpcParameter(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"vpc.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/vpc.ts"],"names":[],"mappings":";;;AAAA,kDAA+D;AAC/D,wDAAqE;AAErE,iCAAqC;AAGrC,MAAa,qBAAsB,SAAQ,kBAAW;IACpD,YAAY,KAAc,EAAE,EAAU,EAAE,KAA6B;QACnE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC,CAAC;IACrE,CAAC;CACF;AAJD,sDAIC;AAED;;;;GAIG;AACH,MAAa,cAAe,SAAQ,kBAAW;IAG7C,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE;YACpB,WAAW,EAAE,qCAAyB,CAAC,YAAY,CAAC,WAAW;YAC/D,OAAO,EAAE,qCAAyB,CAAC,YAAY,CAAC,IAAI;YACpD,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAnBD,wCAmBC","sourcesContent":["import { NAMED_SSM_PARAMETER_PATHS } from \"../../../constants\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../stack\";\nimport { GuParameter } from \"./base\";\nimport type { GuNoTypeParameterProps } from \"./base\";\n\nexport class GuSubnetListParameter extends GuParameter {\n constructor(scope: GuStack, id: string, props: GuNoTypeParameterProps) {\n super(scope, id, { ...props, type: \"List<AWS::EC2::Subnet::Id>\" });\n }\n}\n\n/**\n * Adds a \"VpcId\" parameter to a stack.\n * This parameter will read from Parameter Store.\n * By default it will read from `/account/vpc/primary/id`, this can be changed at runtime if needed.\n */\nexport class GuVpcParameter extends GuParameter {\n private static instance: GuVpcParameter | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"VpcId\", {\n description: NAMED_SSM_PARAMETER_PATHS.PrimaryVpcId.description,\n default: NAMED_SSM_PARAMETER_PATHS.PrimaryVpcId.path,\n type: \"AWS::EC2::VPC::Id\",\n fromSSM: true,\n });\n }\n\n public static getInstance(stack: GuStack): GuVpcParameter {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuVpcParameter(stack);\n }\n\n return this.instance;\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 { App, CfnElement, StackProps } from \"aws-cdk-lib\";\nimport { Annotations, Aspects, CfnParameter, LegacyStackSynthesizer, Stack, Tags } from \"aws-cdk-lib\";\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 /**\n * The stage being used (as defined in your riff-raff.yaml).\n * This will be applied as a tag to all of your resources.\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 name of the Riff-Raff project used to deploy these resources.\n * Used as the value of the `gu:riff-raff-project` tag on all resources.\n * If using {@link GuRoot} or {@link RiffRaffYamlFile}, this value is also used in the location of the generated `riff-raff.yaml`.\n *\n * @see https://github.com/guardian/riffraff-platform\n */\n riffRaffProjectName?: 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 public readonly stack: string;\n public readonly stage: string;\n public readonly app: string | undefined;\n public readonly riffRaffProjectName: string | undefined;\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 public readonly repositoryName: string | undefined;\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 {\n cloudFormationStackName = process.env.GU_CFN_STACK_NAME,\n stack,\n stage,\n app,\n riffRaffProjectName,\n withoutTags,\n } = 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.app = app;\n this.riffRaffProjectName = riffRaffProjectName;\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.riffRaffProjectName) {\n this.addTag(\"gu:riff-raff:project\", this.riffRaffProjectName);\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"]}
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/constructs/core/stack.ts"],"names":[],"mappings":"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","sourcesContent":["import type { App, CfnElement, StackProps } from \"aws-cdk-lib\";\nimport { Annotations, Aspects, CfnParameter, LegacyStackSynthesizer, Stack, Tags } from \"aws-cdk-lib\";\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 /**\n * The stage being used (as defined in your riff-raff.yaml).\n * This will be applied as a tag to all of your resources.\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 name of the Riff-Raff project used to deploy these resources.\n * Used as the value of the `gu:riff-raff-project` tag on all resources.\n * If using {@link GuRoot} or {@link RiffRaffYamlFile}, this value is also used in the location of the generated `riff-raff.yaml`.\n *\n * @see https://github.com/guardian/riffraff-platform\n */\n riffRaffProjectName?: 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 public readonly stack: string;\n public readonly stage: string;\n public readonly app: string | undefined;\n public readonly riffRaffProjectName: string | undefined;\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 public readonly repositoryName: string | undefined;\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 }), {});\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 {\n cloudFormationStackName = process.env.GU_CFN_STACK_NAME,\n stack,\n stage,\n app,\n riffRaffProjectName,\n withoutTags,\n } = 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.app = app;\n this.riffRaffProjectName = riffRaffProjectName;\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.riffRaffProjectName) {\n this.addTag(\"gu:riff-raff:project\", this.riffRaffProjectName);\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"]}
@@ -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,0BAAV,UAAU,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,0BAAV,UAAU,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,CAAC;YACpC;;;;;;;;eAQG;YACH,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAC;YACJ,CAAC;QACH,CAAC;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":"base.js","sourceRoot":"","sources":["../../../../src/constructs/ec2/security-groups/base.ts"],"names":[],"mappings":";;;AAAA,iDAAgE;AAEhE,kFAA+E;AAmC/E;;;;;;;;GAQG;AACH,MAAa,mBAAoB,SAAQ,uBAAa;IACpD,YAAY,KAAc,EAAE,EAAU,EAAE,KAA+B;QACrE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAExB,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;YACxD,MAAM,UAAU,GAAS,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAE1E,IAAI,UAAU,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;gBAClC,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;aAC5F;YAED,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;YACvD,MAAM,UAAU,GAAS,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1E,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAnBD,kDAmBC;AAED,MAAa,eAAgB,SAAQ,IAAA,yCAAmB,EAAC,mBAAmB,CAAC;IAC3E,YAAY,KAAc,EAAE,EAAU,EAAE,KAA2B;QACjE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,0CAIC;AAED;;GAEG;AACH,mCAAmC;AACnC,MAAa,0BAA2B,SAAQ,eAAe;IAC7D,YAAY,KAAc,EAAE,EAAU,EAAE,KAA2B;QACjE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,GAAG,KAAK;YACR,gBAAgB,EAAE,KAAK;YACvB,WAAW,EAAE,kCAAkC;YAC/C,SAAS,EAAE,EAAE;YACb,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,cAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;SAClG,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,KAAc,EAAE,KAA2B;QAC9D,OAAO,IAAI,0BAA0B,CAAC,KAAK,EAAE,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACpF,CAAC;CACF;AAdD,gEAcC","sourcesContent":["import { Peer, Port, SecurityGroup } from \"aws-cdk-lib/aws-ec2\";\nimport type { IPeer, SecurityGroupProps } from \"aws-cdk-lib/aws-ec2\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { AppIdentity, GuStack } from \"../../core\";\n\n/**\n * A way to describe an ingress or egress rule for a security group.\n *\n * See [[transformToSecurityGroupAccessRule]] for a handy helper function.\n */\nexport interface SecurityGroupAccessRule {\n /**\n * The CIDR address for this rule.\n * Use `Peer.anyIpv4()` for global access.\n */\n range: IPeer;\n\n /**\n * The port to open in a security group.\n * The default protocol is TCP.\n * Use `Port.udp(port)` for the UDP protocol.\n */\n port: number | Port;\n\n /**\n * A short explanation for this rule.\n */\n description: string;\n}\n\nexport interface GuBaseSecurityGroupProps extends SecurityGroupProps {\n ingresses?: SecurityGroupAccessRule[];\n egresses?: SecurityGroupAccessRule[];\n}\n\nexport interface GuSecurityGroupProps extends GuBaseSecurityGroupProps, AppIdentity {}\n\n/**\n * Defining an AWS Security Group with ingress and egress rules.\n *\n * An ingress rule on port 22 is strictly forbidden as SSH via SSM is preferred.\n *\n * Prefer to use a concrete implementation where possible. See:\n * - [[GuPublicInternetAccessSecurityGroup]]\n * - [[GuHttpsEgressSecurityGroup]]\n */\nexport class GuBaseSecurityGroup extends SecurityGroup {\n constructor(scope: GuStack, id: string, props: GuBaseSecurityGroupProps) {\n super(scope, id, props);\n\n props.ingresses?.forEach(({ range, port, description }) => {\n const connection: Port = typeof port === \"number\" ? Port.tcp(port) : port;\n\n if (connection.toString() === \"22\") {\n throw new Error(\"An ingress rule on port 22 is not allowed. Prefer to setup SSH via SSM.\");\n }\n\n this.addIngressRule(range, connection, description);\n });\n\n props.egresses?.forEach(({ range, port, description }) => {\n const connection: Port = typeof port === \"number\" ? Port.tcp(port) : port;\n this.addEgressRule(range, connection, description);\n });\n }\n}\n\nexport class GuSecurityGroup extends GuAppAwareConstruct(GuBaseSecurityGroup) {\n constructor(scope: GuStack, id: string, props: GuSecurityGroupProps) {\n super(scope, id, props);\n }\n}\n\n/**\n * Creates a security group which allows all outbound HTTPS traffic.\n */\n// TODO should this be a singleton?\nexport class GuHttpsEgressSecurityGroup extends GuSecurityGroup {\n constructor(scope: GuStack, id: string, props: GuSecurityGroupProps) {\n super(scope, id, {\n ...props,\n allowAllOutbound: false,\n description: \"Allow all outbound HTTPS traffic\",\n ingresses: [],\n egresses: [{ range: Peer.anyIpv4(), port: 443, description: \"Allow all outbound HTTPS traffic\" }],\n });\n }\n\n public static forVpc(scope: GuStack, props: GuSecurityGroupProps): GuHttpsEgressSecurityGroup {\n return new GuHttpsEgressSecurityGroup(scope, \"GuHttpsEgressSecurityGroup\", props);\n }\n}\n"]}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/constructs/ec2/security-groups/base.ts"],"names":[],"mappings":";;;AAAA,iDAAgE;AAEhE,kFAA+E;AAmC/E;;;;;;;;GAQG;AACH,MAAa,mBAAoB,SAAQ,uBAAa;IACpD,YAAY,KAAc,EAAE,EAAU,EAAE,KAA+B;QACrE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAExB,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;YACxD,MAAM,UAAU,GAAS,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAE1E,IAAI,UAAU,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;YAC7F,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;YACvD,MAAM,UAAU,GAAS,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1E,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAnBD,kDAmBC;AAED,MAAa,eAAgB,SAAQ,IAAA,yCAAmB,EAAC,mBAAmB,CAAC;IAC3E,YAAY,KAAc,EAAE,EAAU,EAAE,KAA2B;QACjE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,0CAIC;AAED;;GAEG;AACH,mCAAmC;AACnC,MAAa,0BAA2B,SAAQ,eAAe;IAC7D,YAAY,KAAc,EAAE,EAAU,EAAE,KAA2B;QACjE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,GAAG,KAAK;YACR,gBAAgB,EAAE,KAAK;YACvB,WAAW,EAAE,kCAAkC;YAC/C,SAAS,EAAE,EAAE;YACb,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,cAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;SAClG,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,KAAc,EAAE,KAA2B;QAC9D,OAAO,IAAI,0BAA0B,CAAC,KAAK,EAAE,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACpF,CAAC;CACF;AAdD,gEAcC","sourcesContent":["import { Peer, Port, SecurityGroup } from \"aws-cdk-lib/aws-ec2\";\nimport type { IPeer, SecurityGroupProps } from \"aws-cdk-lib/aws-ec2\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { AppIdentity, GuStack } from \"../../core\";\n\n/**\n * A way to describe an ingress or egress rule for a security group.\n *\n * See [[transformToSecurityGroupAccessRule]] for a handy helper function.\n */\nexport interface SecurityGroupAccessRule {\n /**\n * The CIDR address for this rule.\n * Use `Peer.anyIpv4()` for global access.\n */\n range: IPeer;\n\n /**\n * The port to open in a security group.\n * The default protocol is TCP.\n * Use `Port.udp(port)` for the UDP protocol.\n */\n port: number | Port;\n\n /**\n * A short explanation for this rule.\n */\n description: string;\n}\n\nexport interface GuBaseSecurityGroupProps extends SecurityGroupProps {\n ingresses?: SecurityGroupAccessRule[];\n egresses?: SecurityGroupAccessRule[];\n}\n\nexport interface GuSecurityGroupProps extends GuBaseSecurityGroupProps, AppIdentity {}\n\n/**\n * Defining an AWS Security Group with ingress and egress rules.\n *\n * An ingress rule on port 22 is strictly forbidden as SSH via SSM is preferred.\n *\n * Prefer to use a concrete implementation where possible. See:\n * - [[GuPublicInternetAccessSecurityGroup]]\n * - [[GuHttpsEgressSecurityGroup]]\n */\nexport class GuBaseSecurityGroup extends SecurityGroup {\n constructor(scope: GuStack, id: string, props: GuBaseSecurityGroupProps) {\n super(scope, id, props);\n\n props.ingresses?.forEach(({ range, port, description }) => {\n const connection: Port = typeof port === \"number\" ? Port.tcp(port) : port;\n\n if (connection.toString() === \"22\") {\n throw new Error(\"An ingress rule on port 22 is not allowed. Prefer to setup SSH via SSM.\");\n }\n\n this.addIngressRule(range, connection, description);\n });\n\n props.egresses?.forEach(({ range, port, description }) => {\n const connection: Port = typeof port === \"number\" ? Port.tcp(port) : port;\n this.addEgressRule(range, connection, description);\n });\n }\n}\n\nexport class GuSecurityGroup extends GuAppAwareConstruct(GuBaseSecurityGroup) {\n constructor(scope: GuStack, id: string, props: GuSecurityGroupProps) {\n super(scope, id, props);\n }\n}\n\n/**\n * Creates a security group which allows all outbound HTTPS traffic.\n */\n// TODO should this be a singleton?\nexport class GuHttpsEgressSecurityGroup extends GuSecurityGroup {\n constructor(scope: GuStack, id: string, props: GuSecurityGroupProps) {\n super(scope, id, {\n ...props,\n allowAllOutbound: false,\n description: \"Allow all outbound HTTPS traffic\",\n ingresses: [],\n egresses: [{ range: Peer.anyIpv4(), port: 443, description: \"Allow all outbound HTTPS traffic\" }],\n });\n }\n\n public static forVpc(scope: GuStack, props: GuSecurityGroupProps): GuHttpsEgressSecurityGroup {\n return new GuHttpsEgressSecurityGroup(scope, \"GuHttpsEgressSecurityGroup\", props);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"vpc.d.ts","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,UAAU,cAAe,SAAQ,IAAI,CAAC,aAAa,EAAE,mBAAmB,CAAC;IACvE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,KAAK,uBAAuB,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AAG7D,oBAAY,UAAU;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;CACpB;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD,eAAO,MAAM,QAAQ,WAAY;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAA0B,CAAC;AAE/E,qBAAa,KAAK;IAChB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE;IAkB5D,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,EAAE;IAgB7E,MAAM,CAAC,+BAA+B,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,EAAE,UAAU,GAAE,MAAU,GAAG,OAAO,EAAE;IAoBhH,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAOtE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,uBAAuB,GAAG,IAAI;CAI1F"}
1
+ {"version":3,"file":"vpc.d.ts","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,UAAU,cAAe,SAAQ,IAAI,CAAC,aAAa,EAAE,mBAAmB,CAAC;IACvE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,KAAK,uBAAuB,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AAG7D,oBAAY,UAAU;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;CACpB;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD,eAAO,MAAM,QAAQ,GAAI,QAAQ;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAA0B,CAAC;AAE/E,qBAAa,KAAK;IAChB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE;IAkB5D,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,EAAE;IAgB7E,MAAM,CAAC,+BAA+B,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,EAAE,UAAU,GAAE,MAAU,GAAG,OAAO,EAAE;IAoBhH,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAOtE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,uBAAuB,GAAG,IAAI;CAI1F"}
@@ -1 +1 @@
1
- {"version":3,"file":"vpc.js","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":";;;AAAA,6CAAiC;AACjC,iDAAkD;AAElD,+CAA4D;AAC5D,kCAAgE;AAShE,0BAA0B;AAC1B,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,+BAAiB,CAAA;IACjB,iCAAmB,CAAA;AACrB,CAAC,EAHW,UAAU,0BAAV,UAAU,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;QAC/C,MAAM,gBAAgB,GACpB,IAAI,KAAK,UAAU,CAAC,OAAO;YACzB,CAAC,CAAC,qCAAyB,CAAC,wBAAwB;YACpD,CAAC,CAAC,qCAAyB,CAAC,uBAAuB,CAAC;QAExD,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;YACtD,OAAO,EAAE,gBAAgB,CAAC,IAAI;YAC9B,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,+BAA+B,CAAC,KAAc,EAAE,KAAqB,EAAE,aAAqB,CAAC;QAClG,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC;QAC/C,MAAM,gBAAgB,GACpB,IAAI,KAAK,UAAU,CAAC,OAAO;YACzB,CAAC,CAAC,qCAAyB,CAAC,wBAAwB;YACpD,CAAC,CAAC,qCAAyB,CAAC,uBAAuB,CAAC;QAExD,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;YACtD,OAAO,EAAE,gBAAgB,CAAC,IAAI;YAC9B,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;YACnC,SAAS,CAAC,IAAI,CAAC,gBAAE,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;SACnD;QACD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,gBAAM,CAAC,YAAY,CAAC,KAAK,EAAE,UAAU,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjG,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;AAlED,sBAkEC","sourcesContent":["import { Fn } from \"aws-cdk-lib\";\nimport { Subnet, Vpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { ISubnet, IVpc, VpcAttributes } from \"aws-cdk-lib/aws-ec2\";\nimport { NAMED_SSM_PARAMETER_PATHS } from \"../../constants\";\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 const parameterDefault =\n type === SubnetType.PRIVATE\n ? NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets\n : NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n default: parameterDefault.path,\n fromSSM: true,\n });\n\n return GuVpc.subnets(scope, subnets.valueAsList);\n }\n\n static subnetsFromParameterFixedNumber(scope: GuStack, props?: GuSubnetProps, numSubnets: number = 3): ISubnet[] {\n const type = props?.type ?? SubnetType.PRIVATE;\n const parameterDefault =\n type === SubnetType.PRIVATE\n ? NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets\n : NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n default: parameterDefault.path,\n fromSSM: true,\n });\n\n const subnetIds: string[] = [];\n for (let i = 0; i < numSubnets; i++) {\n subnetIds.push(Fn.select(i, subnets.valueAsList));\n }\n return subnetIds.map((subnetId) => Subnet.fromSubnetId(scope, `subnet-${subnetId}`, subnetId));\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":"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","sourcesContent":["import { Fn } from \"aws-cdk-lib\";\nimport { Subnet, Vpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { ISubnet, IVpc, VpcAttributes } from \"aws-cdk-lib/aws-ec2\";\nimport { NAMED_SSM_PARAMETER_PATHS } from \"../../constants\";\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 const parameterDefault =\n type === SubnetType.PRIVATE\n ? NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets\n : NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n default: parameterDefault.path,\n fromSSM: true,\n });\n\n return GuVpc.subnets(scope, subnets.valueAsList);\n }\n\n static subnetsFromParameterFixedNumber(scope: GuStack, props?: GuSubnetProps, numSubnets: number = 3): ISubnet[] {\n const type = props?.type ?? SubnetType.PRIVATE;\n const parameterDefault =\n type === SubnetType.PRIVATE\n ? NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets\n : NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n default: parameterDefault.path,\n fromSSM: true,\n });\n\n const subnetIds: string[] = [];\n for (let i = 0; i < numSubnets; i++) {\n subnetIds.push(Fn.select(i, subnets.valueAsList));\n }\n return subnetIds.map((subnetId) => Subnet.fromSubnetId(scope, `subnet-${subnetId}`, subnetId));\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"]}
@@ -69,7 +69,7 @@ class GuEcsTask extends constructs_1.Construct {
69
69
  const containerDefinition = taskDefinition.addContainer(`${id}-TaskContainer`, {
70
70
  image: getContainer(containerConfiguration),
71
71
  entryPoint: taskCommand ? ["/bin/sh"] : undefined,
72
- command: taskCommand ? ["-c", taskCommand] : undefined,
72
+ command: taskCommand ? ["-c", taskCommand] : undefined, // if unset, falls back to CMD in docker file, or no command will be run
73
73
  cpu,
74
74
  memoryLimitMiB: memory,
75
75
  logging: aws_ecs_1.LogDrivers.awsLogs({
@@ -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, ISubnet, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { IRepository } from \"aws-cdk-lib/aws-ecr\";\nimport {\n Cluster,\n Compatibility,\n ContainerImage,\n CpuArchitecture,\n FargatePlatformVersion,\n LogDrivers,\n OperatingSystemFamily,\n TaskDefinition,\n} from \"aws-cdk-lib/aws-ecs\";\nimport type { ContainerDefinition, ContainerInsights, RepositoryImageProps } from \"aws-cdk-lib/aws-ecs\";\nimport { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport { DefinitionBody, 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 * Note it is recommended to use GuVpc.subnetsFromParameterFixedNumber for the subnets prop rather than\n * GuVpc.subnetsFromParameter, as using the latter can result a custom resource being required\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 subnets: ISubnet[];\n assignPublicIp?: boolean;\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 * Whether to give the task IAM role access to the account's dist bucket.\n * This is enabled by default to avoid breaking changes, but consumers of this pattern\n * that pull a container image that doesn't need extra dependencies from S3\n * shoud set this value to `false`.\n */\n enableDistributablePolicy?: boolean;\n\n /**\n * The CloudWatch Container Insights setting\n *\n * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cloudwatch-container-insights.html\n */\n containerInsights: ContainerInsights;\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 public readonly stateMachine: StateMachine;\n public readonly taskDefinition: TaskDefinition;\n public readonly containerDefinition: ContainerDefinition;\n public readonly task: EcsRunTask;\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 subnets,\n monitoringConfiguration,\n securityGroups = [],\n environmentOverrides,\n enableDistributablePolicy = true,\n containerInsights,\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 containerInsightsV2: containerInsights,\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 runtimePlatform: {\n cpuArchitecture: CpuArchitecture.ARM64,\n operatingSystemFamily: OperatingSystemFamily.of(\"LINUX\"),\n },\n });\n this.taskDefinition = taskDefinition;\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 readonlyRootFilesystem: true,\n });\n this.containerDefinition = containerDefinition;\n\n if (enableDistributablePolicy) {\n const distPolicy = new GuGetDistributablePolicyStatement(scope, { app });\n taskDefinition.addToTaskRolePolicy(distPolicy);\n }\n\n // these policies are needed for guard duty runtime monitoring\n // See https://docs.aws.amazon.com/guardduty/latest/ug/prereq-runtime-monitoring-ecs-support.html#before-enable-runtime-monitoring-ecs\n const getAuthTokenPolicy = new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\"ecr:GetAuthorizationToken\"],\n resources: [\"*\"],\n });\n const guardDutyContainerPolicy = new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\"ecr:BatchCheckLayerAvailability\", \"ecr:GetDownloadUrlForLayer\", \"ecr:BatchGetImage\"],\n // See https://docs.aws.amazon.com/guardduty/latest/ug/runtime-monitoring-ecr-repository-gdu-agent.html\n // note that if you are using a region other than eu-west-1 you'll need to add extra repositories here\n resources: [\"arn:aws:ecr:eu-west-1:694911143906:repository/aws-guardduty-agent-fargate\"],\n });\n\n taskDefinition.addToExecutionRolePolicy(getAuthTokenPolicy);\n taskDefinition.addToExecutionRolePolicy(guardDutyContainerPolicy);\n\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 subnets: { subnets },\n assignPublicIp: false,\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 this.task = task;\n\n this.stateMachine = new StateMachine(scope, `${id}-StateMachine`, {\n definitionBody: DefinitionBody.fromChainable(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":"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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, ISubnet, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { IRepository } from \"aws-cdk-lib/aws-ecr\";\nimport {\n Cluster,\n Compatibility,\n ContainerImage,\n CpuArchitecture,\n FargatePlatformVersion,\n LogDrivers,\n OperatingSystemFamily,\n TaskDefinition,\n} from \"aws-cdk-lib/aws-ecs\";\nimport type { ContainerDefinition, ContainerInsights, RepositoryImageProps } from \"aws-cdk-lib/aws-ecs\";\nimport { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport { DefinitionBody, 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 * Note it is recommended to use GuVpc.subnetsFromParameterFixedNumber for the subnets prop rather than\n * GuVpc.subnetsFromParameter, as using the latter can result a custom resource being required\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 subnets: ISubnet[];\n assignPublicIp?: boolean;\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 * Whether to give the task IAM role access to the account's dist bucket.\n * This is enabled by default to avoid breaking changes, but consumers of this pattern\n * that pull a container image that doesn't need extra dependencies from S3\n * shoud set this value to `false`.\n */\n enableDistributablePolicy?: boolean;\n\n /**\n * The CloudWatch Container Insights setting\n *\n * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cloudwatch-container-insights.html\n */\n containerInsights: ContainerInsights;\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 public readonly stateMachine: StateMachine;\n public readonly taskDefinition: TaskDefinition;\n public readonly containerDefinition: ContainerDefinition;\n public readonly task: EcsRunTask;\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 subnets,\n monitoringConfiguration,\n securityGroups = [],\n environmentOverrides,\n enableDistributablePolicy = true,\n containerInsights,\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 containerInsightsV2: containerInsights,\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 runtimePlatform: {\n cpuArchitecture: CpuArchitecture.ARM64,\n operatingSystemFamily: OperatingSystemFamily.of(\"LINUX\"),\n },\n });\n this.taskDefinition = taskDefinition;\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 readonlyRootFilesystem: true,\n });\n this.containerDefinition = containerDefinition;\n\n if (enableDistributablePolicy) {\n const distPolicy = new GuGetDistributablePolicyStatement(scope, { app });\n taskDefinition.addToTaskRolePolicy(distPolicy);\n }\n\n // these policies are needed for guard duty runtime monitoring\n // See https://docs.aws.amazon.com/guardduty/latest/ug/prereq-runtime-monitoring-ecs-support.html#before-enable-runtime-monitoring-ecs\n const getAuthTokenPolicy = new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\"ecr:GetAuthorizationToken\"],\n resources: [\"*\"],\n });\n const guardDutyContainerPolicy = new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\"ecr:BatchCheckLayerAvailability\", \"ecr:GetDownloadUrlForLayer\", \"ecr:BatchGetImage\"],\n // See https://docs.aws.amazon.com/guardduty/latest/ug/runtime-monitoring-ecr-repository-gdu-agent.html\n // note that if you are using a region other than eu-west-1 you'll need to add extra repositories here\n resources: [\"arn:aws:ecr:eu-west-1:694911143906:repository/aws-guardduty-agent-fargate\"],\n });\n\n taskDefinition.addToExecutionRolePolicy(getAuthTokenPolicy);\n taskDefinition.addToExecutionRolePolicy(guardDutyContainerPolicy);\n\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 subnets: { subnets },\n assignPublicIp: false,\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 this.task = task;\n\n this.stateMachine = new StateMachine(scope, `${id}-StateMachine`, {\n definitionBody: DefinitionBody.fromChainable(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":"anghammarad.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/anghammarad.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,qCAAyD;AACzD,+CAA8C;AAE9C;;;;;;GAMG;AACH,MAAa,yBAA0B,SAAQ,2BAAa;IAG1D,YAAoB,KAAc;QAChC,MAAM,yBAAyB,GAAG,kCAA2B,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEjF,KAAK,CAAC,KAAK,EAAE,2BAA2B,EAAE;YACxC,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,CAAC,yBAAyB,CAAC,aAAa,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,yBAAyB,CAAC,KAAK,CAAC,CAAC;SACtD;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAnBD,8DAmBC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuAnghammaradTopicParameter } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\n/**\n * Creates an `AWS::IAM::Policy` to grant `sns:Publish` permission to the Anghammarad topic.\n * An `AnghammaradSnsArn` parameter will be automatically added to the stack when needed.\n *\n * @see GuAnghammaradTopicParameter\n * @see https://github.com/guardian/anghammarad\n */\nexport class GuAnghammaradSenderPolicy extends GuAllowPolicy {\n private static instance: GuAnghammaradSenderPolicy | undefined;\n\n private constructor(scope: GuStack) {\n const anghammaradTopicParameter = GuAnghammaradTopicParameter.getInstance(scope);\n\n super(scope, \"GuAnghammaradSenderPolicy\", {\n actions: [\"sns:Publish\"],\n resources: [anghammaradTopicParameter.valueAsString],\n });\n }\n\n public static getInstance(stack: GuStack): GuAnghammaradSenderPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuAnghammaradSenderPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"anghammarad.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/anghammarad.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,qCAAyD;AACzD,+CAA8C;AAE9C;;;;;;GAMG;AACH,MAAa,yBAA0B,SAAQ,2BAAa;IAG1D,YAAoB,KAAc;QAChC,MAAM,yBAAyB,GAAG,kCAA2B,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEjF,KAAK,CAAC,KAAK,EAAE,2BAA2B,EAAE;YACxC,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,CAAC,yBAAyB,CAAC,aAAa,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,yBAAyB,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAnBD,8DAmBC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuAnghammaradTopicParameter } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\n/**\n * Creates an `AWS::IAM::Policy` to grant `sns:Publish` permission to the Anghammarad topic.\n * An `AnghammaradSnsArn` parameter will be automatically added to the stack when needed.\n *\n * @see GuAnghammaradTopicParameter\n * @see https://github.com/guardian/anghammarad\n */\nexport class GuAnghammaradSenderPolicy extends GuAllowPolicy {\n private static instance: GuAnghammaradSenderPolicy | undefined;\n\n private constructor(scope: GuStack) {\n const anghammaradTopicParameter = GuAnghammaradTopicParameter.getInstance(scope);\n\n super(scope, \"GuAnghammaradSenderPolicy\", {\n actions: [\"sns:Publish\"],\n resources: [anghammaradTopicParameter.valueAsString],\n });\n }\n\n public static getInstance(stack: GuStack): GuAnghammaradSenderPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuAnghammaradSenderPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"describe-ec2.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/describe-ec2.ts"],"names":[],"mappings":";;;AAAA,iDAA8D;AAC9D,wDAAqE;AAErE,+CAAyC;AAEzC,MAAa,mBAAoB,SAAQ,sBAAQ;IAG/C,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,UAAU,EAAE,qBAAqB;YACjC,UAAU,EAAE;gBACV,IAAI,yBAAe,CAAC;oBAClB,MAAM,EAAE,gBAAM,CAAC,KAAK;oBACpB,OAAO,EAAE;wBACP,0CAA0C;wBAC1C,uCAAuC;wBACvC,kBAAkB;wBAClB,uBAAuB;qBACxB;oBACD,SAAS,EAAE,CAAC,GAAG,CAAC;iBACjB,CAAC;aACH;SACF,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;SAChD;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AA5BD,kDA4BC","sourcesContent":["import { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuPolicy } from \"./base-policy\";\n\nexport class GuDescribeEC2Policy extends GuPolicy {\n private static instance: GuPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"DescribeEC2Policy\", {\n policyName: \"describe-ec2-policy\",\n statements: [\n new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\n \"autoscaling:DescribeAutoScalingInstances\",\n \"autoscaling:DescribeAutoScalingGroups\",\n \"ec2:DescribeTags\",\n \"ec2:DescribeInstances\",\n ],\n resources: [\"*\"],\n }),\n ],\n });\n }\n\n public static getInstance(stack: GuStack): GuDescribeEC2Policy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuDescribeEC2Policy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"describe-ec2.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/describe-ec2.ts"],"names":[],"mappings":";;;AAAA,iDAA8D;AAC9D,wDAAqE;AAErE,+CAAyC;AAEzC,MAAa,mBAAoB,SAAQ,sBAAQ;IAG/C,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,UAAU,EAAE,qBAAqB;YACjC,UAAU,EAAE;gBACV,IAAI,yBAAe,CAAC;oBAClB,MAAM,EAAE,gBAAM,CAAC,KAAK;oBACpB,OAAO,EAAE;wBACP,0CAA0C;wBAC1C,uCAAuC;wBACvC,kBAAkB;wBAClB,uBAAuB;qBACxB;oBACD,SAAS,EAAE,CAAC,GAAG,CAAC;iBACjB,CAAC;aACH;SACF,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AA5BD,kDA4BC","sourcesContent":["import { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuPolicy } from \"./base-policy\";\n\nexport class GuDescribeEC2Policy extends GuPolicy {\n private static instance: GuPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"DescribeEC2Policy\", {\n policyName: \"describe-ec2-policy\",\n statements: [\n new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\n \"autoscaling:DescribeAutoScalingInstances\",\n \"autoscaling:DescribeAutoScalingGroups\",\n \"ec2:DescribeTags\",\n \"ec2:DescribeInstances\",\n ],\n resources: [\"*\"],\n }),\n ],\n });\n }\n\n public static getInstance(stack: GuStack): GuDescribeEC2Policy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuDescribeEC2Policy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -14,7 +14,7 @@ const kinesisActions = [
14
14
  const kinesisEnhancedFanOutActions = ["SubscribeToShard", "DescribeStreamConsumer"];
15
15
  const actionsOnAllTables = [
16
16
  "Scan",
17
- "CreateTable",
17
+ "CreateTable", // Allow KCL creating the lease, metrics, and coordinator tables - see https://github.com/guardian/cdk/pull/2578#discussion_r1954061397
18
18
  "DescribeTable",
19
19
  "GetItem",
20
20
  "PutItem",
@@ -1 +1 @@
1
- {"version":3,"file":"kcl.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/kcl.ts"],"names":[],"mappings":";;;AAAA,iDAA8D;AAE9D,+CAAyC;AAOzC,MAAM,cAAc,GAAa;IAC/B,gBAAgB;IAChB,uBAAuB;IACvB,wBAAwB;IACxB,YAAY;IACZ,kBAAkB;IAClB,YAAY;CACb,CAAC;AAEF,MAAM,4BAA4B,GAAa,CAAC,kBAAkB,EAAE,wBAAwB,CAAC,CAAC;AAE9F,MAAM,kBAAkB,GAAa;IACnC,MAAM;IACN,aAAa;IACb,eAAe;IACf,SAAS;IACT,SAAS;IACT,YAAY;IACZ,YAAY;CACb,CAAC;AAEF,MAAM,2BAA2B,GAAa,CAAC,aAAa,CAAC,CAAC;AAE9D;;;;;;GAMG;AACH,MAAa,WAAY,SAAQ,sBAAQ;IACvC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAqB;QAC3D,SAAS,KAAK,CAAC,UAAkB,EAAE,OAAiB,EAAE,SAAmB;YACvE,OAAO,IAAI,yBAAe,CAAC;gBACzB,MAAM,EAAE,gBAAM,CAAC,KAAK;gBACpB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,UAAU,IAAI,CAAC,EAAE,CAAC;gBACjD,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,UAAU,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;aAC/F,CAAC,CAAC;QACL,CAAC;QAED,SAAS,aAAa,CAAC,OAAiB,EAAE,iBAA2B;YACnE,OAAO,KAAK,CACV,UAAU,EACV,OAAO,EACP,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,CACjD,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,eAAe,CAAC;QACzC,MAAM,YAAY,GAAG,GAAG,KAAK,CAAC,eAAe,oBAAoB,CAAC;QAClE,MAAM,gBAAgB,GAAG,GAAG,KAAK,CAAC,eAAe,mBAAmB,CAAC;QAErE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,UAAU,EAAE;gBACV,KAAK,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,UAAU,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;gBAChE,KAAK,CAAC,SAAS,EAAE,4BAA4B,EAAE,CAAC,UAAU,KAAK,CAAC,UAAU,aAAa,CAAC,CAAC;gBACzF,aAAa,CAAC,kBAAkB,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;gBAC/E,aAAa,CAAC,2BAA2B,EAAE,CAAC,UAAU,CAAC,CAAC;gBACxD,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,UAAU,UAAU,CAAC,CAAC;gBACnD,KAAK,CAAC,YAAY,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;aAC9C;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAjCD,kCAiCC","sourcesContent":["import { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport type { GuStack } from \"../../core\";\nimport { GuPolicy } from \"./base-policy\";\n\nexport interface KCLApplication {\n streamName: string;\n applicationName: string;\n}\n\nconst kinesisActions: string[] = [\n \"DescribeStream\",\n \"DescribeStreamSummary\",\n \"RegisterStreamConsumer\",\n \"GetRecords\",\n \"GetShardIterator\",\n \"ListShards\",\n];\n\nconst kinesisEnhancedFanOutActions: string[] = [\"SubscribeToShard\", \"DescribeStreamConsumer\"];\n\nconst actionsOnAllTables: string[] = [\n \"Scan\",\n \"CreateTable\", // Allow KCL creating the lease, metrics, and coordinator tables - see https://github.com/guardian/cdk/pull/2578#discussion_r1954061397\n \"DescribeTable\",\n \"GetItem\",\n \"PutItem\",\n \"UpdateItem\",\n \"DeleteItem\",\n];\n\nconst additionalLeaseTableActions: string[] = [\"UpdateTable\"];\n\n/**\n * Creates an `AWS::IAM::Policy` to grant all the required permissions for the Kinesis Client Library\n * (https://github.com/awslabs/amazon-kinesis-client) - specifically for KCL v3, which requires many\n * additional permissions over KCL v2.\n *\n * @see https://docs.aws.amazon.com/streams/latest/dev/kcl-iam-permissions.html\n */\nexport class GuKCLPolicy extends GuPolicy {\n constructor(scope: GuStack, id: string, props: KCLApplication) {\n function allow(actionType: string, actions: string[], resources: string[]): PolicyStatement {\n return new PolicyStatement({\n effect: Effect.ALLOW,\n actions: actions.map((a) => `${actionType}:${a}`),\n resources: resources.map((r) => `arn:aws:${actionType}:${scope.region}:${scope.account}:${r}`),\n });\n }\n\n function allowDynamoDB(actions: string[], tableOrIndexNames: string[]): PolicyStatement {\n return allow(\n \"dynamodb\",\n actions,\n tableOrIndexNames.map((name) => `table/${name}`),\n );\n }\n\n const leaseTable = props.applicationName;\n const metricsTable = `${props.applicationName}-WorkerMetricStats`;\n const coordinatorTable = `${props.applicationName}-CoordinatorState`;\n\n super(scope, id, {\n statements: [\n allow(\"kinesis\", kinesisActions, [`stream/${props.streamName}`]),\n allow(\"kinesis\", kinesisEnhancedFanOutActions, [`stream/${props.streamName}/consumer/*`]),\n allowDynamoDB(actionsOnAllTables, [leaseTable, metricsTable, coordinatorTable]),\n allowDynamoDB(additionalLeaseTableActions, [leaseTable]),\n allowDynamoDB([\"Query\"], [`${leaseTable}/index/*`]),\n allow(\"cloudwatch\", [\"PutMetricData\"], [\"*\"]),\n ],\n });\n }\n}\n"]}
1
+ {"version":3,"file":"kcl.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/kcl.ts"],"names":[],"mappings":";;;AAAA,iDAA8D;AAE9D,+CAAyC;AAOzC,MAAM,cAAc,GAAa;IAC/B,gBAAgB;IAChB,uBAAuB;IACvB,wBAAwB;IACxB,YAAY;IACZ,kBAAkB;IAClB,YAAY;CACb,CAAC;AAEF,MAAM,4BAA4B,GAAa,CAAC,kBAAkB,EAAE,wBAAwB,CAAC,CAAC;AAE9F,MAAM,kBAAkB,GAAa;IACnC,MAAM;IACN,aAAa,EAAE,uIAAuI;IACtJ,eAAe;IACf,SAAS;IACT,SAAS;IACT,YAAY;IACZ,YAAY;CACb,CAAC;AAEF,MAAM,2BAA2B,GAAa,CAAC,aAAa,CAAC,CAAC;AAE9D;;;;;;GAMG;AACH,MAAa,WAAY,SAAQ,sBAAQ;IACvC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAqB;QAC3D,SAAS,KAAK,CAAC,UAAkB,EAAE,OAAiB,EAAE,SAAmB;YACvE,OAAO,IAAI,yBAAe,CAAC;gBACzB,MAAM,EAAE,gBAAM,CAAC,KAAK;gBACpB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,UAAU,IAAI,CAAC,EAAE,CAAC;gBACjD,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,UAAU,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;aAC/F,CAAC,CAAC;QACL,CAAC;QAED,SAAS,aAAa,CAAC,OAAiB,EAAE,iBAA2B;YACnE,OAAO,KAAK,CACV,UAAU,EACV,OAAO,EACP,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,CACjD,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,eAAe,CAAC;QACzC,MAAM,YAAY,GAAG,GAAG,KAAK,CAAC,eAAe,oBAAoB,CAAC;QAClE,MAAM,gBAAgB,GAAG,GAAG,KAAK,CAAC,eAAe,mBAAmB,CAAC;QAErE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,UAAU,EAAE;gBACV,KAAK,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,UAAU,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;gBAChE,KAAK,CAAC,SAAS,EAAE,4BAA4B,EAAE,CAAC,UAAU,KAAK,CAAC,UAAU,aAAa,CAAC,CAAC;gBACzF,aAAa,CAAC,kBAAkB,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;gBAC/E,aAAa,CAAC,2BAA2B,EAAE,CAAC,UAAU,CAAC,CAAC;gBACxD,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,UAAU,UAAU,CAAC,CAAC;gBACnD,KAAK,CAAC,YAAY,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;aAC9C;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAjCD,kCAiCC","sourcesContent":["import { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport type { GuStack } from \"../../core\";\nimport { GuPolicy } from \"./base-policy\";\n\nexport interface KCLApplication {\n streamName: string;\n applicationName: string;\n}\n\nconst kinesisActions: string[] = [\n \"DescribeStream\",\n \"DescribeStreamSummary\",\n \"RegisterStreamConsumer\",\n \"GetRecords\",\n \"GetShardIterator\",\n \"ListShards\",\n];\n\nconst kinesisEnhancedFanOutActions: string[] = [\"SubscribeToShard\", \"DescribeStreamConsumer\"];\n\nconst actionsOnAllTables: string[] = [\n \"Scan\",\n \"CreateTable\", // Allow KCL creating the lease, metrics, and coordinator tables - see https://github.com/guardian/cdk/pull/2578#discussion_r1954061397\n \"DescribeTable\",\n \"GetItem\",\n \"PutItem\",\n \"UpdateItem\",\n \"DeleteItem\",\n];\n\nconst additionalLeaseTableActions: string[] = [\"UpdateTable\"];\n\n/**\n * Creates an `AWS::IAM::Policy` to grant all the required permissions for the Kinesis Client Library\n * (https://github.com/awslabs/amazon-kinesis-client) - specifically for KCL v3, which requires many\n * additional permissions over KCL v2.\n *\n * @see https://docs.aws.amazon.com/streams/latest/dev/kcl-iam-permissions.html\n */\nexport class GuKCLPolicy extends GuPolicy {\n constructor(scope: GuStack, id: string, props: KCLApplication) {\n function allow(actionType: string, actions: string[], resources: string[]): PolicyStatement {\n return new PolicyStatement({\n effect: Effect.ALLOW,\n actions: actions.map((a) => `${actionType}:${a}`),\n resources: resources.map((r) => `arn:aws:${actionType}:${scope.region}:${scope.account}:${r}`),\n });\n }\n\n function allowDynamoDB(actions: string[], tableOrIndexNames: string[]): PolicyStatement {\n return allow(\n \"dynamodb\",\n actions,\n tableOrIndexNames.map((name) => `table/${name}`),\n );\n }\n\n const leaseTable = props.applicationName;\n const metricsTable = `${props.applicationName}-WorkerMetricStats`;\n const coordinatorTable = `${props.applicationName}-CoordinatorState`;\n\n super(scope, id, {\n statements: [\n allow(\"kinesis\", kinesisActions, [`stream/${props.streamName}`]),\n allow(\"kinesis\", kinesisEnhancedFanOutActions, [`stream/${props.streamName}/consumer/*`]),\n allowDynamoDB(actionsOnAllTables, [leaseTable, metricsTable, coordinatorTable]),\n allowDynamoDB(additionalLeaseTableActions, [leaseTable]),\n allowDynamoDB([\"Query\"], [`${leaseTable}/index/*`]),\n allow(\"cloudwatch\", [\"PutMetricData\"], [\"*\"]),\n ],\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"log-shipping.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/log-shipping.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,qCAA0D;AAC1D,+CAA8C;AAE9C,MAAa,mBAAoB,SAAQ,2BAAa;IAGpD,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE;YAClC,OAAO,EAAE,CAAC,mBAAmB,EAAE,cAAc,CAAC;YAC9C,SAAS,EAAE;gBACT,mBAAmB,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,WAC9C,mCAA4B,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,aAClD,EAAE;aACH;SACF,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;SAChD;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AArBD,kDAqBC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuLoggingStreamNameParameter } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\nexport class GuLogShippingPolicy extends GuAllowPolicy {\n private static instance: GuLogShippingPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"GuLogShippingPolicy\", {\n actions: [\"kinesis:Describe*\", \"kinesis:Put*\"],\n resources: [\n `arn:aws:kinesis:${scope.region}:${scope.account}:stream/${\n GuLoggingStreamNameParameter.getInstance(scope).valueAsString\n }`,\n ],\n });\n }\n\n public static getInstance(stack: GuStack): GuLogShippingPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuLogShippingPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"log-shipping.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/log-shipping.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,qCAA0D;AAC1D,+CAA8C;AAE9C,MAAa,mBAAoB,SAAQ,2BAAa;IAGpD,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE;YAClC,OAAO,EAAE,CAAC,mBAAmB,EAAE,cAAc,CAAC;YAC9C,SAAS,EAAE;gBACT,mBAAmB,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,WAC9C,mCAA4B,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,aAClD,EAAE;aACH;SACF,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AArBD,kDAqBC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuLoggingStreamNameParameter } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\nexport class GuLogShippingPolicy extends GuAllowPolicy {\n private static instance: GuLogShippingPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"GuLogShippingPolicy\", {\n actions: [\"kinesis:Describe*\", \"kinesis:Put*\"],\n resources: [\n `arn:aws:kinesis:${scope.region}:${scope.account}:stream/${\n GuLoggingStreamNameParameter.getInstance(scope).valueAsString\n }`,\n ],\n });\n }\n\n public static getInstance(stack: GuStack): GuLogShippingPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuLogShippingPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"parameter-store-read.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/parameter-store-read.ts"],"names":[],"mappings":";;;AAAA,iDAA8D;AAC9D,kFAA+E;AAE/E,+CAAyC;AAEzC;;;GAGG;AACH,MAAa,oBAAqB,SAAQ,yBAAe;IACvD,YAAY,KAAc,EAAE,KAAkB;QAC5C,KAAK,CAAC;YACJ,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC,yBAAyB,CAAC;YACpC,SAAS,EAAE,CAAC,eAAe,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,cAAc,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;SACjH,CAAC,CAAC;IACL,CAAC;CACF;AARD,oDAQC;AAED;;;;GAIG;AACH,MAAa,oBAAqB,SAAQ,yBAAe;IACvD,YAAY,KAAc,EAAE,KAAkB;QAC5C,KAAK,CAAC;YACJ,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;YAClD,SAAS,EAAE;gBACT,eAAe,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,cAAc,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI;aACtG;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAVD,oDAUC;AACD;;;GAGG;AACH,MAAa,0BAA2B,SAAQ,IAAA,yCAAmB,EAAC,sBAAQ,CAAC;IAQ3E,YAAoB,KAAc,EAAE,KAAkB;QACpD,KAAK,CAAC,KAAK,EAAE,oBAAoB,EAAE;YACjC,UAAU,EAAE,6BAA6B;YACzC,UAAU,EAAE,CAAC,IAAI,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC5F,GAAG,KAAK;SACT,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc,EAAE,KAAkB;QAC1D,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,mBAAmB,EAAE;YACxB,MAAM,QAAQ,GAAG,IAAI,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5D,OAAO,QAAQ,CAAC;SACjB;QAED,MAAM,aAAa,GAAG,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,QAAQ,GAAG,IAAI,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;YACxE,OAAO,QAAQ,CAAC;SACjB;QAED,OAAO,aAAa,CAAC;IACvB,CAAC;;AAhCH,gEAiCC;AAhCC;;;;GAIG;AACY,oCAAS,GAA0D,IAAI,GAAG,EAAE,CAAC","sourcesContent":["import { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { AppIdentity, GuStack } from \"../../core\";\nimport { GuPolicy } from \"./base-policy\";\n\n/**\n * This is helpful for reading all private configuration for a given app. For example, the\n * [simple-configuration](https://github.com/guardian/simple-configuration) library requires these permissions.\n */\nexport class ReadParametersByPath extends PolicyStatement {\n constructor(scope: GuStack, props: AppIdentity) {\n super({\n effect: Effect.ALLOW,\n actions: [\"ssm:GetParametersByPath\"],\n resources: [`arn:aws:ssm:${scope.region}:${scope.account}:parameter/${scope.stage}/${scope.stack}/${props.app}`],\n });\n }\n}\n\n/**\n * This is helpful for accessing specific pieces of private configuration. For example, the\n * [play-secret-rotation](https://github.com/guardian/play-secret-rotation) library requires `ssm:GetParameters`\n * permissions.\n */\nexport class ReadParametersByName extends PolicyStatement {\n constructor(scope: GuStack, props: AppIdentity) {\n super({\n effect: Effect.ALLOW,\n actions: [\"ssm:GetParameters\", \"ssm:GetParameter\"],\n resources: [\n `arn:aws:ssm:${scope.region}:${scope.account}:parameter/${scope.stage}/${scope.stack}/${props.app}/*`,\n ],\n });\n }\n}\n/**\n * Grants read-only permissions for Parameter Store. These permissions are typically used for accessing private\n * configuration. See [[`ReadParametersByPath`]] and [[`ReadParametersByName`]] for more details.\n */\nexport class GuParameterStoreReadPolicy extends GuAppAwareConstruct(GuPolicy) {\n /**\n * A record of existing instances of this construct, per {@link GuStack}.\n * This allows us to implement singleton like behaviour.\n * @private\n */\n private static instances: Map<GuStack, Map<string, GuParameterStoreReadPolicy>> = new Map();\n\n private constructor(scope: GuStack, props: AppIdentity) {\n super(scope, \"ParameterStoreRead\", {\n policyName: \"parameter-store-read-policy\",\n statements: [new ReadParametersByPath(scope, props), new ReadParametersByName(scope, props)],\n ...props,\n });\n }\n\n public static getInstance(stack: GuStack, props: AppIdentity): GuParameterStoreReadPolicy {\n const maybeStackInstances = this.instances.get(stack);\n if (!maybeStackInstances) {\n const instance = new GuParameterStoreReadPolicy(stack, props);\n this.instances.set(stack, new Map([[props.app, instance]]));\n return instance;\n }\n\n const maybeInstance = maybeStackInstances.get(props.app);\n if (!maybeInstance) {\n const instance = new GuParameterStoreReadPolicy(stack, props);\n this.instances.set(stack, maybeStackInstances.set(props.app, instance));\n return instance;\n }\n\n return maybeInstance;\n }\n}\n"]}
1
+ {"version":3,"file":"parameter-store-read.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/parameter-store-read.ts"],"names":[],"mappings":";;;AAAA,iDAA8D;AAC9D,kFAA+E;AAE/E,+CAAyC;AAEzC;;;GAGG;AACH,MAAa,oBAAqB,SAAQ,yBAAe;IACvD,YAAY,KAAc,EAAE,KAAkB;QAC5C,KAAK,CAAC;YACJ,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC,yBAAyB,CAAC;YACpC,SAAS,EAAE,CAAC,eAAe,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,cAAc,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;SACjH,CAAC,CAAC;IACL,CAAC;CACF;AARD,oDAQC;AAED;;;;GAIG;AACH,MAAa,oBAAqB,SAAQ,yBAAe;IACvD,YAAY,KAAc,EAAE,KAAkB;QAC5C,KAAK,CAAC;YACJ,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;YAClD,SAAS,EAAE;gBACT,eAAe,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,cAAc,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI;aACtG;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAVD,oDAUC;AACD;;;GAGG;AACH,MAAa,0BAA2B,SAAQ,IAAA,yCAAmB,EAAC,sBAAQ,CAAC;IAQ3E,YAAoB,KAAc,EAAE,KAAkB;QACpD,KAAK,CAAC,KAAK,EAAE,oBAAoB,EAAE;YACjC,UAAU,EAAE,6BAA6B;YACzC,UAAU,EAAE,CAAC,IAAI,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC5F,GAAG,KAAK;SACT,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc,EAAE,KAAkB;QAC1D,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5D,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,aAAa,GAAG,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,IAAI,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;YACxE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,OAAO,aAAa,CAAC;IACvB,CAAC;;AAhCH,gEAiCC;AAhCC;;;;GAIG;AACY,oCAAS,GAA0D,IAAI,GAAG,EAAE,CAAC","sourcesContent":["import { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { AppIdentity, GuStack } from \"../../core\";\nimport { GuPolicy } from \"./base-policy\";\n\n/**\n * This is helpful for reading all private configuration for a given app. For example, the\n * [simple-configuration](https://github.com/guardian/simple-configuration) library requires these permissions.\n */\nexport class ReadParametersByPath extends PolicyStatement {\n constructor(scope: GuStack, props: AppIdentity) {\n super({\n effect: Effect.ALLOW,\n actions: [\"ssm:GetParametersByPath\"],\n resources: [`arn:aws:ssm:${scope.region}:${scope.account}:parameter/${scope.stage}/${scope.stack}/${props.app}`],\n });\n }\n}\n\n/**\n * This is helpful for accessing specific pieces of private configuration. For example, the\n * [play-secret-rotation](https://github.com/guardian/play-secret-rotation) library requires `ssm:GetParameters`\n * permissions.\n */\nexport class ReadParametersByName extends PolicyStatement {\n constructor(scope: GuStack, props: AppIdentity) {\n super({\n effect: Effect.ALLOW,\n actions: [\"ssm:GetParameters\", \"ssm:GetParameter\"],\n resources: [\n `arn:aws:ssm:${scope.region}:${scope.account}:parameter/${scope.stage}/${scope.stack}/${props.app}/*`,\n ],\n });\n }\n}\n/**\n * Grants read-only permissions for Parameter Store. These permissions are typically used for accessing private\n * configuration. See [[`ReadParametersByPath`]] and [[`ReadParametersByName`]] for more details.\n */\nexport class GuParameterStoreReadPolicy extends GuAppAwareConstruct(GuPolicy) {\n /**\n * A record of existing instances of this construct, per {@link GuStack}.\n * This allows us to implement singleton like behaviour.\n * @private\n */\n private static instances: Map<GuStack, Map<string, GuParameterStoreReadPolicy>> = new Map();\n\n private constructor(scope: GuStack, props: AppIdentity) {\n super(scope, \"ParameterStoreRead\", {\n policyName: \"parameter-store-read-policy\",\n statements: [new ReadParametersByPath(scope, props), new ReadParametersByName(scope, props)],\n ...props,\n });\n }\n\n public static getInstance(stack: GuStack, props: AppIdentity): GuParameterStoreReadPolicy {\n const maybeStackInstances = this.instances.get(stack);\n if (!maybeStackInstances) {\n const instance = new GuParameterStoreReadPolicy(stack, props);\n this.instances.set(stack, new Map([[props.app, instance]]));\n return instance;\n }\n\n const maybeInstance = maybeStackInstances.get(props.app);\n if (!maybeInstance) {\n const instance = new GuParameterStoreReadPolicy(stack, props);\n this.instances.set(stack, maybeStackInstances.set(props.app, instance));\n return instance;\n }\n\n return maybeInstance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ssm-ssh.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ssm-ssh.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,+CAA8C;AAE9C;;;;;;;;;;GAUG;AACH,MAAa,cAAe,SAAQ,2BAAa;IAG/C,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE;YAC3B,UAAU,EAAE,gBAAgB;YAC5B,OAAO,EAAE;gBACP,gCAAgC;gBAChC,2BAA2B;gBAC3B,yBAAyB;gBACzB,yBAAyB;gBACzB,yBAAyB;gBACzB,uBAAuB;gBACvB,+BAA+B;gBAC/B,8BAA8B;gBAC9B,gCAAgC;gBAChC,gCAAgC;gBAChC,kCAAkC;gBAClC,+BAA+B;gBAC/B,gCAAgC;gBAChC,6BAA6B;aAC9B;YAED,8GAA8G;YAC9G,SAAS,EAAE,CAAC,GAAG,CAAC;SACjB,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;SAC3C;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAnCD,wCAmCC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\n/**\n * A minimal policy enabling SSM+SSH access to EC2 instances.\n *\n * This is favoured over the AWS Managed Policy `AmazonSSMManagedInstanceCore`,\n * `AmazonSSMManagedInstanceCore` provides read access to all SSM Parameters.\n * This is not required for SSM+SSH, and given our usage of SSM Parameters for configuration, is not following least privilege.\n * Access to SSM Parameters should be scoped to the Stack, Stage, and Application.\n *\n * @see https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html\n * @see https://github.com/guardian/ssm-scala\n */\nexport class GuSsmSshPolicy extends GuAllowPolicy {\n private static instance: GuSsmSshPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"SsmSshPolicy\", {\n policyName: \"ssm-ssh-policy\",\n actions: [\n \"ec2messages:AcknowledgeMessage\",\n \"ec2messages:DeleteMessage\",\n \"ec2messages:FailMessage\",\n \"ec2messages:GetEndpoint\",\n \"ec2messages:GetMessages\",\n \"ec2messages:SendReply\",\n \"ssm:UpdateInstanceInformation\",\n \"ssm:ListInstanceAssociations\",\n \"ssm:DescribeInstanceProperties\",\n \"ssm:DescribeDocumentParameters\",\n \"ssmmessages:CreateControlChannel\",\n \"ssmmessages:CreateDataChannel\",\n \"ssmmessages:OpenControlChannel\",\n \"ssmmessages:OpenDataChannel\",\n ],\n\n // TODO can this be scoped to the stack, stage, and application? If so, it won't make sense to be a singleton.\n resources: [\"*\"],\n });\n }\n\n public static getInstance(stack: GuStack): GuSsmSshPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuSsmSshPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
1
+ {"version":3,"file":"ssm-ssh.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ssm-ssh.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,+CAA8C;AAE9C;;;;;;;;;;GAUG;AACH,MAAa,cAAe,SAAQ,2BAAa;IAG/C,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE;YAC3B,UAAU,EAAE,gBAAgB;YAC5B,OAAO,EAAE;gBACP,gCAAgC;gBAChC,2BAA2B;gBAC3B,yBAAyB;gBACzB,yBAAyB;gBACzB,yBAAyB;gBACzB,uBAAuB;gBACvB,+BAA+B;gBAC/B,8BAA8B;gBAC9B,gCAAgC;gBAChC,gCAAgC;gBAChC,kCAAkC;gBAClC,+BAA+B;gBAC/B,gCAAgC;gBAChC,6BAA6B;aAC9B;YAED,8GAA8G;YAC9G,SAAS,EAAE,CAAC,GAAG,CAAC;SACjB,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAnCD,wCAmCC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\n/**\n * A minimal policy enabling SSM+SSH access to EC2 instances.\n *\n * This is favoured over the AWS Managed Policy `AmazonSSMManagedInstanceCore`,\n * `AmazonSSMManagedInstanceCore` provides read access to all SSM Parameters.\n * This is not required for SSM+SSH, and given our usage of SSM Parameters for configuration, is not following least privilege.\n * Access to SSM Parameters should be scoped to the Stack, Stage, and Application.\n *\n * @see https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html\n * @see https://github.com/guardian/ssm-scala\n */\nexport class GuSsmSshPolicy extends GuAllowPolicy {\n private static instance: GuSsmSshPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"SsmSshPolicy\", {\n policyName: \"ssm-ssh-policy\",\n actions: [\n \"ec2messages:AcknowledgeMessage\",\n \"ec2messages:DeleteMessage\",\n \"ec2messages:FailMessage\",\n \"ec2messages:GetEndpoint\",\n \"ec2messages:GetMessages\",\n \"ec2messages:SendReply\",\n \"ssm:UpdateInstanceInformation\",\n \"ssm:ListInstanceAssociations\",\n \"ssm:DescribeInstanceProperties\",\n \"ssm:DescribeDocumentParameters\",\n \"ssmmessages:CreateControlChannel\",\n \"ssmmessages:CreateDataChannel\",\n \"ssmmessages:OpenControlChannel\",\n \"ssmmessages:OpenDataChannel\",\n ],\n\n // TODO can this be scoped to the stack, stage, and application? If so, it won't make sense to be a singleton.\n resources: [\"*\"],\n });\n }\n\n public static getInstance(stack: GuStack): GuSsmSshPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuSsmSshPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"lambda.js","sourceRoot":"","sources":["../../../src/constructs/lambda/lambda.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint \"@guardian/tsdoc-required/tsdoc-required\": 2 -- to begin rolling this out for public APIs. */\nimport { Duration } from \"aws-cdk-lib\";\nimport type { PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport type { FunctionProps, Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { Alias, Code, Function, LoggingFormat, RuntimeFamily } from \"aws-cdk-lib/aws-lambda\";\nimport { Bucket } from \"aws-cdk-lib/aws-s3\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { GuDistributable } from \"../../types\";\nimport type { GuLambdaErrorPercentageMonitoringProps, GuLambdaThrottlingMonitoringProps } from \"../cloudwatch\";\nimport { GuLambdaErrorPercentageAlarm, GuLambdaThrottlingAlarm } from \"../cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity, GuDistributionBucketParameter } from \"../core\";\nimport { ReadParametersByName, ReadParametersByPath } from \"../iam\";\n\nexport interface GuFunctionProps extends GuDistributable, Omit<FunctionProps, \"code\">, AppIdentity {\n /**\n * Create a new Lambda version and alias. This is only necessary if you want to use features which rely\n * on versioning (e.g. SnapStart or Provisioned Concurrency).\n *\n * If you enable versioning you must ensure that your Lambda function is updated whenever a new build is deployed via\n * CloudFormation. The simplest way to do this is to include the build number in the `fileName` prop.\n */\n enableVersioning?: boolean;\n\n /**\n * Alarm if error percentage exceeds a threshold.\n */\n errorPercentageMonitoring?: GuLambdaErrorPercentageMonitoringProps;\n /**\n * Alarm if throttling occurs. Note, it is also worth considering a\n * concurrency limit (the `reservedConcurrentExecutions` prop) if you are\n * concerned about throttling.\n *\n * @see https://docs.aws.amazon.com/lambda/latest/dg/concurrent-executions.html\n */\n throttlingMonitoring?: GuLambdaThrottlingMonitoringProps;\n /**\n * SSM parameter for the S3 bucket that contains your lambda file.\n *\n * Typically you should not override this but you may need to if, for example,\n * you are referencing a file that is shared across many apps and/or AWS\n * accounts.\n *\n * @defaultValue [[`GuDistributionBucketParameter`]]\n */\n bucketNamePath?: string;\n /**\n * Set to `true` to use the filename *without* the stage/stack/app prefix.\n *\n * Typically you should not override this but you may need to if, for example,\n * you are referencing a file that is shared across many apps and/or AWS\n * accounts.\n */\n withoutFilePrefix?: boolean;\n /**\n * Set to `true` this informs consumers of this function that upload is\n * managed elsewhere by DevX.\n *\n * This is used by RiffRaffYamlFileExperimental to skip generating\n * an uploadLambda step.\n */\n withoutArtifactUpload?: boolean;\n}\n\nfunction defaultMemorySize(runtime: Runtime, memorySize?: number): number {\n if (memorySize) {\n return memorySize;\n } else {\n switch (runtime.family) {\n case RuntimeFamily.JAVA:\n return 1024;\n default:\n return 512;\n }\n }\n}\n\n/**\n * Construct which creates a Lambda function.\n *\n * This Lambda relies on the code artifact residing in a standard location in\n * S3. For more details on the bucket used, see\n * [[`GuDistributionBucketParameter`]]. By default, the path used will be\n * `<stack>/<stage>/<app</<fileName>`. If required, e.g. if you are sharing\n * lambda code across apps or accounts, override the source bucket using the\n * `bucketNamePath` prop.\n *\n * The default memory size of this Lambda will vary depending on the runtime\n * chosen. For Java runtimes (i.e. resource hungry Scala Lambdas!), 1024MB will\n * be used. For all other runtimes, the memory size defaults to 512MB. This can\n * be overridden via the `memorySize` prop.\n *\n * By default, the timeout for this Lambda is 30 seconds. This can be overridden\n * via the `timeout` prop.\n *\n * By default the Lambda is granted permission to read from the SSM parameter\n * store subtree specific to this Lambda (i.e. it can read all keys under\n * `/<stage>/<stack>/<app>/`). If you need to add additional permissions, you\n * can use\n * [`addToRolePolicy`](`https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda.FunctionBase.html#addwbrtowbrrolewbrpolicystatement`).\n *\n * The Lambda has `STACK`, `STAGE` and `APP` environment variables which can be\n * used to determine its identity.\n *\n * Note that this construct creates a Lambda without an event source. Depending\n * on your use-case, you may wish to consider using a pattern which instantiates\n * a Lambda with an event source e.g. [[`GuScheduledLambda`]].\n */\nexport class GuLambdaFunction extends Function {\n public readonly app: string;\n public readonly fileName: string;\n public readonly bucketNamePath: string | undefined;\n public readonly withoutArtifactUpload: boolean;\n public readonly withoutFilePrefix: boolean;\n public readonly alias?: Alias;\n\n constructor(scope: GuStack, id: string, props: GuFunctionProps) {\n const {\n app,\n fileName,\n runtime,\n memorySize,\n timeout,\n bucketNamePath,\n withoutFilePrefix = false,\n withoutArtifactUpload = false,\n loggingFormat = LoggingFormat.JSON,\n } = props;\n\n const bucketName = bucketNamePath\n ? StringParameter.fromStringParameterName(scope, \"bucketoverride\", bucketNamePath).stringValue\n : GuDistributionBucketParameter.getInstance(scope).valueAsString;\n\n const defaultEnvironmentVariables = {\n STACK: scope.stack,\n STAGE: scope.stage,\n APP: app,\n };\n\n const bucket = Bucket.fromBucketName(scope, `${id}-bucket`, bucketName);\n const objectKey = withoutFilePrefix ? fileName : GuDistributable.getObjectKey(scope, { app }, { fileName });\n const code = Code.fromBucket(bucket, objectKey);\n super(scope, id, {\n ...props,\n loggingFormat,\n environment: {\n ...props.environment,\n ...defaultEnvironmentVariables,\n },\n memorySize: defaultMemorySize(runtime, memorySize),\n timeout: timeout ?? Duration.seconds(30),\n code,\n });\n\n this.app = app;\n this.fileName = fileName;\n this.bucketNamePath = bucketNamePath;\n this.withoutArtifactUpload = withoutArtifactUpload;\n this.withoutFilePrefix = withoutFilePrefix;\n\n if (props.enableVersioning) {\n this.alias = new Alias(scope, `${id}-AliasForLambda`, {\n aliasName: scope.stage,\n version: this.currentVersion,\n });\n }\n\n if (props.errorPercentageMonitoring) {\n new GuLambdaErrorPercentageAlarm(scope, `${id}-ErrorPercentageAlarmForLambda`, {\n ...props.errorPercentageMonitoring,\n lambda: this,\n });\n }\n\n if (props.throttlingMonitoring) {\n new GuLambdaThrottlingAlarm(scope, `${id}-ThrottlingAlarmForLambda`, {\n ...props.throttlingMonitoring,\n lambda: this,\n });\n }\n\n bucket.grantRead(this, objectKey);\n\n const ssmParamReadPolicies: PolicyStatement[] = [\n new ReadParametersByPath(scope, props),\n new ReadParametersByName(scope, props),\n ];\n\n ssmParamReadPolicies.map((policy) => this.addToRolePolicy(policy));\n\n AppIdentity.taggedConstruct(props, this);\n }\n}\n"]}
1
+ {"version":3,"file":"lambda.js","sourceRoot":"","sources":["../../../src/constructs/lambda/lambda.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint \"@guardian/tsdoc-required/tsdoc-required\": 2 -- to begin rolling this out for public APIs. */\nimport { Duration } from \"aws-cdk-lib\";\nimport type { PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport type { FunctionProps, Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { Alias, Code, Function, LoggingFormat, RuntimeFamily } from \"aws-cdk-lib/aws-lambda\";\nimport { Bucket } from \"aws-cdk-lib/aws-s3\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { GuDistributable } from \"../../types\";\nimport type { GuLambdaErrorPercentageMonitoringProps, GuLambdaThrottlingMonitoringProps } from \"../cloudwatch\";\nimport { GuLambdaErrorPercentageAlarm, GuLambdaThrottlingAlarm } from \"../cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity, GuDistributionBucketParameter } from \"../core\";\nimport { ReadParametersByName, ReadParametersByPath } from \"../iam\";\n\nexport interface GuFunctionProps extends GuDistributable, Omit<FunctionProps, \"code\">, AppIdentity {\n /**\n * Create a new Lambda version and alias. This is only necessary if you want to use features which rely\n * on versioning (e.g. SnapStart or Provisioned Concurrency).\n *\n * If you enable versioning you must ensure that your Lambda function is updated whenever a new build is deployed via\n * CloudFormation. The simplest way to do this is to include the build number in the `fileName` prop.\n */\n enableVersioning?: boolean;\n\n /**\n * Alarm if error percentage exceeds a threshold.\n */\n errorPercentageMonitoring?: GuLambdaErrorPercentageMonitoringProps;\n /**\n * Alarm if throttling occurs. Note, it is also worth considering a\n * concurrency limit (the `reservedConcurrentExecutions` prop) if you are\n * concerned about throttling.\n *\n * @see https://docs.aws.amazon.com/lambda/latest/dg/concurrent-executions.html\n */\n throttlingMonitoring?: GuLambdaThrottlingMonitoringProps;\n /**\n * SSM parameter for the S3 bucket that contains your lambda file.\n *\n * Typically you should not override this but you may need to if, for example,\n * you are referencing a file that is shared across many apps and/or AWS\n * accounts.\n *\n * @defaultValue [[`GuDistributionBucketParameter`]]\n */\n bucketNamePath?: string;\n /**\n * Set to `true` to use the filename *without* the stage/stack/app prefix.\n *\n * Typically you should not override this but you may need to if, for example,\n * you are referencing a file that is shared across many apps and/or AWS\n * accounts.\n */\n withoutFilePrefix?: boolean;\n /**\n * Set to `true` this informs consumers of this function that upload is\n * managed elsewhere by DevX.\n *\n * This is used by RiffRaffYamlFileExperimental to skip generating\n * an uploadLambda step.\n */\n withoutArtifactUpload?: boolean;\n}\n\nfunction defaultMemorySize(runtime: Runtime, memorySize?: number): number {\n if (memorySize) {\n return memorySize;\n } else {\n switch (runtime.family) {\n case RuntimeFamily.JAVA:\n return 1024;\n default:\n return 512;\n }\n }\n}\n\n/**\n * Construct which creates a Lambda function.\n *\n * This Lambda relies on the code artifact residing in a standard location in\n * S3. For more details on the bucket used, see\n * [[`GuDistributionBucketParameter`]]. By default, the path used will be\n * `<stack>/<stage>/<app</<fileName>`. If required, e.g. if you are sharing\n * lambda code across apps or accounts, override the source bucket using the\n * `bucketNamePath` prop.\n *\n * The default memory size of this Lambda will vary depending on the runtime\n * chosen. For Java runtimes (i.e. resource hungry Scala Lambdas!), 1024MB will\n * be used. For all other runtimes, the memory size defaults to 512MB. This can\n * be overridden via the `memorySize` prop.\n *\n * By default, the timeout for this Lambda is 30 seconds. This can be overridden\n * via the `timeout` prop.\n *\n * By default the Lambda is granted permission to read from the SSM parameter\n * store subtree specific to this Lambda (i.e. it can read all keys under\n * `/<stage>/<stack>/<app>/`). If you need to add additional permissions, you\n * can use\n * [`addToRolePolicy`](`https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda.FunctionBase.html#addwbrtowbrrolewbrpolicystatement`).\n *\n * The Lambda has `STACK`, `STAGE` and `APP` environment variables which can be\n * used to determine its identity.\n *\n * Note that this construct creates a Lambda without an event source. Depending\n * on your use-case, you may wish to consider using a pattern which instantiates\n * a Lambda with an event source e.g. [[`GuScheduledLambda`]].\n */\nexport class GuLambdaFunction extends Function {\n public readonly app: string;\n public readonly fileName: string;\n public readonly bucketNamePath: string | undefined;\n public readonly withoutArtifactUpload: boolean;\n public readonly withoutFilePrefix: boolean;\n public readonly alias?: Alias;\n\n constructor(scope: GuStack, id: string, props: GuFunctionProps) {\n const {\n app,\n fileName,\n runtime,\n memorySize,\n timeout,\n bucketNamePath,\n withoutFilePrefix = false,\n withoutArtifactUpload = false,\n loggingFormat = LoggingFormat.JSON,\n } = props;\n\n const bucketName = bucketNamePath\n ? StringParameter.fromStringParameterName(scope, \"bucketoverride\", bucketNamePath).stringValue\n : GuDistributionBucketParameter.getInstance(scope).valueAsString;\n\n const defaultEnvironmentVariables = {\n STACK: scope.stack,\n STAGE: scope.stage,\n APP: app,\n };\n\n const bucket = Bucket.fromBucketName(scope, `${id}-bucket`, bucketName);\n const objectKey = withoutFilePrefix ? fileName : GuDistributable.getObjectKey(scope, { app }, { fileName });\n const code = Code.fromBucket(bucket, objectKey);\n super(scope, id, {\n ...props,\n loggingFormat,\n environment: {\n ...props.environment,\n ...defaultEnvironmentVariables,\n },\n memorySize: defaultMemorySize(runtime, memorySize),\n timeout: timeout ?? Duration.seconds(30),\n code,\n });\n\n this.app = app;\n this.fileName = fileName;\n this.bucketNamePath = bucketNamePath;\n this.withoutArtifactUpload = withoutArtifactUpload;\n this.withoutFilePrefix = withoutFilePrefix;\n\n if (props.enableVersioning) {\n this.alias = new Alias(scope, `${id}-AliasForLambda`, {\n aliasName: scope.stage,\n version: this.currentVersion,\n });\n }\n\n if (props.errorPercentageMonitoring) {\n new GuLambdaErrorPercentageAlarm(scope, `${id}-ErrorPercentageAlarmForLambda`, {\n ...props.errorPercentageMonitoring,\n lambda: this,\n });\n }\n\n if (props.throttlingMonitoring) {\n new GuLambdaThrottlingAlarm(scope, `${id}-ThrottlingAlarmForLambda`, {\n ...props.throttlingMonitoring,\n lambda: this,\n });\n }\n\n bucket.grantRead(this, objectKey);\n\n const ssmParamReadPolicies: PolicyStatement[] = [\n new ReadParametersByPath(scope, props),\n new ReadParametersByName(scope, props),\n ];\n\n ssmParamReadPolicies.map((policy) => this.addToRolePolicy(policy));\n\n AppIdentity.taggedConstruct(props, this);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"application-load-balancer.js","sourceRoot":"","sources":["../../../../src/constructs/loadbalancing/alb/application-load-balancer.ts"],"names":[],"mappings":";;;AAAA,6CAAqD;AACrD,uFAAiF;AAEjF,+CAA4C;AAC5C,iDAAwF;AACxF,kFAA+E;AAE/E,qCAAyE;AAEzE;;;;;;GAMG;AACU,QAAA,4CAA4C,GAAG,0DAA0D,CAAC;AAEvH;;;GAGG;AACU,QAAA,kCAAkC,GAAG,iDAAiD,CAAC;AA0BpG;;;;;;;;;GASG;AACH,MAAa,yBAA0B,SAAQ,IAAA,yCAAmB,EAAC,oDAAuB,CAAC;IAGzF,YAAY,KAAc,EAAE,EAAU,EAAE,KAAqC;QAC3E,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,iBAAiB,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;QACjE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAE/B,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QAEzD,IAAI,CAAC,YAAY,CAAC,oDAA4C,EAAE,MAAM,CAAC,CAAC;QACxE,IAAI,CAAC,YAAY,CAAC,0CAAkC,EAAE,MAAM,CAAC,CAAC;QAE9D,IAAI,UAAU,EAAE;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,YAA+B,CAAC;YACxD,KAAK,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;SAC3C;QAED,IAAI,iBAAiB,EAAE;YACrB,MAAM,MAAM,GAAG,eAAM,CAAC,cAAc,CAClC,KAAK,EACL,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,qBAAqB,CAAC,EACpD,qCAA8B,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,aAAa,CAChE,CAAC;YACF,MAAM,MAAM,GAAG,6BAA6B,KAAK,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACpE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACpC;aAAM;YACL,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;YACrD,yBAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;SACxE;QAED,IAAI,uBAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,UAAU,EAAE;YAC/C,WAAW,EAAE,iBAAiB,IAAI,CAAC,SAAS,EAAE;YAC9C,KAAK,EAAE,IAAI,CAAC,mBAAmB;SAChC,CAAC,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,SAAS,SAAS,CAAC,CAAC;QAEjD,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE;YACxB,IAAI,CAAC,GAAG,GAAG,IAAI,yBAAe,CAAC,IAAI,EAAE,aAAa,EAAE;gBAClD,aAAa,EAAE,yBAAyB,KAAK,IAAI,GAAG,UAAU;gBAC9D,WAAW,EAAE,0BAA0B,KAAK,IAAI,GAAG,GAAG;gBACtD,UAAU,EAAE,KAAK;gBACjB,WAAW,EAAE,IAAI,CAAC,eAAe;gBACjC,IAAI,EAAE,uBAAa,CAAC,QAAQ;gBAC5B,QAAQ,EAAE,2BAAiB,CAAC,IAAI;aACjC,CAAC,CAAC;SACJ;IACH,CAAC;CACF;AA9CD,8DA8CC","sourcesContent":["import { Annotations, CfnOutput } from \"aws-cdk-lib\";\nimport { ApplicationLoadBalancer } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { ApplicationLoadBalancerProps, CfnLoadBalancer } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport { Bucket } from \"aws-cdk-lib/aws-s3\";\nimport { ParameterDataType, ParameterTier, StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { GuStack } from \"../../core\";\nimport { AppIdentity, GuAccessLoggingBucketParameter } from \"../../core\";\n\n/**\n * Adds the following headers to each request before forwarding it to the target:\n * - `x-amzn-tls-version`, which has information about the TLS protocol version negotiated with the client\n * - `x-amzn-tls-cipher-suite`, which has information about the cipher suite negotiated with the client\n *\n * Both headers are in OpenSSL format.\n */\nexport const TLS_VERSION_AND_CIPHER_SUITE_HEADERS_ENABLED = \"routing.http.x_amzn_tls_version_and_cipher_suite.enabled\";\n\n/**\n * Indicates whether HTTP headers with invalid header fields are removed by the load balancer.\n * Invalid headers are described as HTTP header names that do not conform to the regular expression [-A-Za-z0-9]+\n */\nexport const DROP_INVALID_HEADER_FIELDS_ENABLED = \"routing.http.drop_invalid_header_fields.enabled\";\n\ninterface GuApplicationLoadBalancerProps extends ApplicationLoadBalancerProps, AppIdentity {\n /**\n * If your CloudFormation does not define the Type of your Load Balancer, you must set this boolean to true to avoid\n * resource [replacement](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-loadbalancer.html#cfn-elasticloadbalancingv2-loadbalancer-type).\n * If a Load Balancer is replaced it is likely to lead to downtime.\n */\n removeType?: boolean;\n\n /**\n * Enable access logging for this load balancer.\n * Access logs are written to an S3 bucket within your AWS account.\n * The bucket is created by {@link https://github.com/guardian/aws-account-setup}.\n * The logs are queryable via the `gucdk_access_logs` Athena database.\n *\n * @default true\n */\n withAccessLogging?: boolean;\n\n /**\n * Configuration for WAF protection, if desired\n */\n waf?: WafProps;\n}\n\n/**\n * Construct which creates an Application Load Balancer.\n *\n * This construct should be used in conjunction with [[`GuApplicationListener`]] and [[`GuApplicationTargetGroup`]]\n * to route traffic to your application. For more details on these three components, see the\n * [AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html#application-load-balancer-components).\n *\n * This resource is stateful.\n * @see https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md\n */\nexport class GuApplicationLoadBalancer extends GuAppAwareConstruct(ApplicationLoadBalancer) {\n public readonly waf?: StringParameter;\n\n constructor(scope: GuStack, id: string, props: GuApplicationLoadBalancerProps) {\n const { app, removeType, waf, withAccessLogging = true } = props;\n const { stack, stage } = scope;\n\n super(scope, id, { deletionProtection: true, ...props });\n\n this.setAttribute(TLS_VERSION_AND_CIPHER_SUITE_HEADERS_ENABLED, \"true\");\n this.setAttribute(DROP_INVALID_HEADER_FIELDS_ENABLED, \"true\");\n\n if (removeType) {\n const cfnLb = this.node.defaultChild as CfnLoadBalancer;\n cfnLb.addPropertyDeletionOverride(\"Type\");\n }\n\n if (withAccessLogging) {\n const bucket = Bucket.fromBucketName(\n scope,\n AppIdentity.suffixText(props, \"AccessLoggingBucket\"),\n GuAccessLoggingBucketParameter.getInstance(scope).valueAsString,\n );\n const prefix = `application-load-balancer/${stage}/${stack}/${app}`;\n this.logAccessLogs(bucket, prefix);\n } else {\n this.setAttribute(\"access_logs.s3.enabled\", \"false\");\n Annotations.of(this).addInfo(`Access logs disabled for load balancer`);\n }\n\n new CfnOutput(this, `${this.idWithApp}-DnsName`, {\n description: `DNS entry for ${this.idWithApp}`,\n value: this.loadBalancerDnsName,\n }).overrideLogicalId(`${this.idWithApp}DnsName`);\n\n if (!!waf && waf.enabled) {\n this.waf = new StringParameter(this, \"AlbSsmParam\", {\n parameterName: `/infosec/waf/services/${stage}/${app}-alb-arn`,\n description: `The ARN of the ALB for ${stage}-${app}.`,\n simpleName: false,\n stringValue: this.loadBalancerArn,\n tier: ParameterTier.STANDARD,\n dataType: ParameterDataType.TEXT,\n });\n }\n }\n}\n\nexport interface WafProps {\n enabled: boolean;\n}\n"]}
1
+ {"version":3,"file":"application-load-balancer.js","sourceRoot":"","sources":["../../../../src/constructs/loadbalancing/alb/application-load-balancer.ts"],"names":[],"mappings":";;;AAAA,6CAAqD;AACrD,uFAAiF;AAEjF,+CAA4C;AAC5C,iDAAwF;AACxF,kFAA+E;AAE/E,qCAAyE;AAEzE;;;;;;GAMG;AACU,QAAA,4CAA4C,GAAG,0DAA0D,CAAC;AAEvH;;;GAGG;AACU,QAAA,kCAAkC,GAAG,iDAAiD,CAAC;AA0BpG;;;;;;;;;GASG;AACH,MAAa,yBAA0B,SAAQ,IAAA,yCAAmB,EAAC,oDAAuB,CAAC;IAGzF,YAAY,KAAc,EAAE,EAAU,EAAE,KAAqC;QAC3E,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,iBAAiB,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;QACjE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAE/B,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QAEzD,IAAI,CAAC,YAAY,CAAC,oDAA4C,EAAE,MAAM,CAAC,CAAC;QACxE,IAAI,CAAC,YAAY,CAAC,0CAAkC,EAAE,MAAM,CAAC,CAAC;QAE9D,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,YAA+B,CAAC;YACxD,KAAK,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,iBAAiB,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,eAAM,CAAC,cAAc,CAClC,KAAK,EACL,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,qBAAqB,CAAC,EACpD,qCAA8B,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,aAAa,CAChE,CAAC;YACF,MAAM,MAAM,GAAG,6BAA6B,KAAK,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACpE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;YACrD,yBAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,uBAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,UAAU,EAAE;YAC/C,WAAW,EAAE,iBAAiB,IAAI,CAAC,SAAS,EAAE;YAC9C,KAAK,EAAE,IAAI,CAAC,mBAAmB;SAChC,CAAC,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,SAAS,SAAS,CAAC,CAAC;QAEjD,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,GAAG,IAAI,yBAAe,CAAC,IAAI,EAAE,aAAa,EAAE;gBAClD,aAAa,EAAE,yBAAyB,KAAK,IAAI,GAAG,UAAU;gBAC9D,WAAW,EAAE,0BAA0B,KAAK,IAAI,GAAG,GAAG;gBACtD,UAAU,EAAE,KAAK;gBACjB,WAAW,EAAE,IAAI,CAAC,eAAe;gBACjC,IAAI,EAAE,uBAAa,CAAC,QAAQ;gBAC5B,QAAQ,EAAE,2BAAiB,CAAC,IAAI;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF;AA9CD,8DA8CC","sourcesContent":["import { Annotations, CfnOutput } from \"aws-cdk-lib\";\nimport { ApplicationLoadBalancer } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { ApplicationLoadBalancerProps, CfnLoadBalancer } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport { Bucket } from \"aws-cdk-lib/aws-s3\";\nimport { ParameterDataType, ParameterTier, StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { GuStack } from \"../../core\";\nimport { AppIdentity, GuAccessLoggingBucketParameter } from \"../../core\";\n\n/**\n * Adds the following headers to each request before forwarding it to the target:\n * - `x-amzn-tls-version`, which has information about the TLS protocol version negotiated with the client\n * - `x-amzn-tls-cipher-suite`, which has information about the cipher suite negotiated with the client\n *\n * Both headers are in OpenSSL format.\n */\nexport const TLS_VERSION_AND_CIPHER_SUITE_HEADERS_ENABLED = \"routing.http.x_amzn_tls_version_and_cipher_suite.enabled\";\n\n/**\n * Indicates whether HTTP headers with invalid header fields are removed by the load balancer.\n * Invalid headers are described as HTTP header names that do not conform to the regular expression [-A-Za-z0-9]+\n */\nexport const DROP_INVALID_HEADER_FIELDS_ENABLED = \"routing.http.drop_invalid_header_fields.enabled\";\n\ninterface GuApplicationLoadBalancerProps extends ApplicationLoadBalancerProps, AppIdentity {\n /**\n * If your CloudFormation does not define the Type of your Load Balancer, you must set this boolean to true to avoid\n * resource [replacement](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-loadbalancer.html#cfn-elasticloadbalancingv2-loadbalancer-type).\n * If a Load Balancer is replaced it is likely to lead to downtime.\n */\n removeType?: boolean;\n\n /**\n * Enable access logging for this load balancer.\n * Access logs are written to an S3 bucket within your AWS account.\n * The bucket is created by {@link https://github.com/guardian/aws-account-setup}.\n * The logs are queryable via the `gucdk_access_logs` Athena database.\n *\n * @default true\n */\n withAccessLogging?: boolean;\n\n /**\n * Configuration for WAF protection, if desired\n */\n waf?: WafProps;\n}\n\n/**\n * Construct which creates an Application Load Balancer.\n *\n * This construct should be used in conjunction with [[`GuApplicationListener`]] and [[`GuApplicationTargetGroup`]]\n * to route traffic to your application. For more details on these three components, see the\n * [AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html#application-load-balancer-components).\n *\n * This resource is stateful.\n * @see https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md\n */\nexport class GuApplicationLoadBalancer extends GuAppAwareConstruct(ApplicationLoadBalancer) {\n public readonly waf?: StringParameter;\n\n constructor(scope: GuStack, id: string, props: GuApplicationLoadBalancerProps) {\n const { app, removeType, waf, withAccessLogging = true } = props;\n const { stack, stage } = scope;\n\n super(scope, id, { deletionProtection: true, ...props });\n\n this.setAttribute(TLS_VERSION_AND_CIPHER_SUITE_HEADERS_ENABLED, \"true\");\n this.setAttribute(DROP_INVALID_HEADER_FIELDS_ENABLED, \"true\");\n\n if (removeType) {\n const cfnLb = this.node.defaultChild as CfnLoadBalancer;\n cfnLb.addPropertyDeletionOverride(\"Type\");\n }\n\n if (withAccessLogging) {\n const bucket = Bucket.fromBucketName(\n scope,\n AppIdentity.suffixText(props, \"AccessLoggingBucket\"),\n GuAccessLoggingBucketParameter.getInstance(scope).valueAsString,\n );\n const prefix = `application-load-balancer/${stage}/${stack}/${app}`;\n this.logAccessLogs(bucket, prefix);\n } else {\n this.setAttribute(\"access_logs.s3.enabled\", \"false\");\n Annotations.of(this).addInfo(`Access logs disabled for load balancer`);\n }\n\n new CfnOutput(this, `${this.idWithApp}-DnsName`, {\n description: `DNS entry for ${this.idWithApp}`,\n value: this.loadBalancerDnsName,\n }).overrideLogicalId(`${this.idWithApp}DnsName`);\n\n if (!!waf && waf.enabled) {\n this.waf = new StringParameter(this, \"AlbSsmParam\", {\n parameterName: `/infosec/waf/services/${stage}/${app}-alb-arn`,\n description: `The ARN of the ALB for ${stage}-${app}.`,\n simpleName: false,\n stringValue: this.loadBalancerArn,\n tier: ParameterTier.STANDARD,\n dataType: ParameterDataType.TEXT,\n });\n }\n }\n}\n\nexport interface WafProps {\n enabled: boolean;\n}\n"]}
@@ -31,7 +31,7 @@ const app_aware_construct_1 = require("../../../utils/mixin/app-aware-construct"
31
31
  class GuApplicationTargetGroup extends (0, app_aware_construct_1.GuAppAwareConstruct)(aws_elasticloadbalancingv2_1.ApplicationTargetGroup) {
32
32
  constructor(scope, id, props) {
33
33
  const mergedProps = {
34
- protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP,
34
+ protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP, // We terminate HTTPS at the load balancer level, so load balancer to ASG/EC2 traffic can be over HTTP
35
35
  deregistrationDelay: aws_cdk_lib_1.Duration.seconds(30),
36
36
  ...props,
37
37
  healthCheck: { ...GuApplicationTargetGroup.DefaultHealthCheck, ...props.healthCheck },