From 5c1ac510b8aa8e160642eb847c84701840e77b3b Mon Sep 17 00:00:00 2001 From: Akash Askoolum Date: Fri, 19 Mar 2021 15:42:58 +0000 Subject: [PATCH] feat: make GuDistributionBucketParameter a singleton --- src/constructs/core/parameters/s3.ts | 19 ++++++++++++++++--- .../iam/policies/s3-get-object.test.ts | 2 +- src/constructs/iam/policies/s3-get-object.ts | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/constructs/core/parameters/s3.ts b/src/constructs/core/parameters/s3.ts index c313e16dc4..4f31896ee1 100644 --- a/src/constructs/core/parameters/s3.ts +++ b/src/constructs/core/parameters/s3.ts @@ -2,15 +2,28 @@ import type { GuStack } from "../stack"; import { GuStringParameter } from "./base"; export class GuDistributionBucketParameter extends GuStringParameter { - public static parameterName = "DistributionBucketName"; + private static instance: GuDistributionBucketParameter | undefined; - constructor(scope: GuStack, id: string = GuDistributionBucketParameter.parameterName) { - super(scope, id, { + // eslint-disable-next-line custom-rules/valid-constructors -- TODO be better + private constructor(scope: GuStack) { + super(scope, "DistributionBucketName", { description: "SSM parameter containing the S3 bucket name holding distribution artifacts", default: "/account/services/artifact.bucket", fromSSM: true, }); } + + public static getInstance(stack: GuStack): GuDistributionBucketParameter { + // Resources can only live in the same App so return a new instance where necessary. + // See https://github.com/aws/aws-cdk/blob/0ea4b19afd639541e5f1d7c1783032ee480c307e/packages/%40aws-cdk/core/lib/private/refs.ts#L47-L50 + const isSameStack = this.instance?.node.root === stack.node.root; + + if (!this.instance || !isSameStack) { + this.instance = new GuDistributionBucketParameter(stack); + } + + return this.instance; + } } export class GuPrivateConfigBucketParameter extends GuStringParameter { diff --git a/src/constructs/iam/policies/s3-get-object.test.ts b/src/constructs/iam/policies/s3-get-object.test.ts index 8c1a749c59..60be3bac52 100644 --- a/src/constructs/iam/policies/s3-get-object.test.ts +++ b/src/constructs/iam/policies/s3-get-object.test.ts @@ -82,7 +82,7 @@ describe("The GuGetDistributablePolicy construct", () => { const json = SynthUtils.toCloudFormation(stack) as SynthedStack; const parameterKeys = Object.keys(json.Parameters); - const expectedKeys = ["Stage", GuDistributionBucketParameter.parameterName]; + const expectedKeys = ["Stage", GuDistributionBucketParameter.getInstance(stack).id]; expect(parameterKeys).toEqual(expectedKeys); expect(json.Parameters.DistributionBucketName).toEqual({ diff --git a/src/constructs/iam/policies/s3-get-object.ts b/src/constructs/iam/policies/s3-get-object.ts index f5d70c5769..ec6a4f17ee 100644 --- a/src/constructs/iam/policies/s3-get-object.ts +++ b/src/constructs/iam/policies/s3-get-object.ts @@ -24,7 +24,7 @@ export class GuGetDistributablePolicy extends GuGetS3ObjectsPolicy { const path = [scope.stack, scope.stage, props.app, "*"].join("/"); super(scope, AppIdentity.suffixText(props, "GetDistributablePolicy"), { ...props, - bucketName: new GuDistributionBucketParameter(scope).valueAsString, + bucketName: GuDistributionBucketParameter.getInstance(scope).valueAsString, paths: [path], }); AppIdentity.taggedConstruct(props, this);