cdk-stacksets icon indicating copy to clipboard operation
cdk-stacksets copied to clipboard

Multiple StackSets in one Stack with assetBucket

Open boenhoff opened this issue 1 year ago • 2 comments

I want to create multiple StackSets in one Stack. I tried to deploy the following CDK Stack:

CDK Stack

import { Stack, StackProps } from 'aws-cdk-lib';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
import { Bucket } from 'aws-cdk-lib/aws-s3';
import { Capability, DeploymentType, StackSet, StackSetStack, StackSetTarget, StackSetTemplate } from 'cdk-stacksets';
import { Construct } from 'constructs';
import { config } from '../config';

export class TestStack extends Stack {

  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const assetBucket = Bucket.fromBucketName(this, 'SomeBucketForAssets', config.bucketName);

    const firstStackSet = new StackSetStack(this, 'FirstStackSet', {
      assetBucket: assetBucket,
    });
    new NodejsFunction(firstStackSet, 'FirstStackSetLambda', {
      logRetention: RetentionDays.THREE_DAYS,
      entry: './src/lambda/index.ts',
      depsLockFilePath: './src/lambda/package-lock.json',
    });
    new StackSet(this, 'FirstStackSetDeployment', {
      target: StackSetTarget.fromOrganizationalUnits({
        regions: config.stackSetRegions,
        organizationalUnits: config.stackSetOrganizationalUnits,
        excludeAccounts: [config.cloudformationAccountId],
      }),
      deploymentType: DeploymentType.serviceManaged(),
      capabilities: [Capability.IAM],
      template: StackSetTemplate.fromStackSetStack(firstStackSet),
    });

    const secondStackSet = new StackSetStack(this, 'SecondStackSet', {
      assetBucket: assetBucket,
    });
    new NodejsFunction(secondStackSet, 'SecondStackSetLambda', {
      logRetention: RetentionDays.THREE_DAYS,
      entry: './src/lambda/index.ts',
      depsLockFilePath: './src/lambda/package-lock.json',
    });
    new StackSet(this, 'SecondStackSetDeployment', {
      target: StackSetTarget.fromOrganizationalUnits({
        regions: config.stackSetRegions,
        organizationalUnits: config.stackSetOrganizationalUnits,
        excludeAccounts: [config.cloudformationAccountId],
      }),
      deploymentType: DeploymentType.serviceManaged(),
      capabilities: [Capability.IAM],
      template: StackSetTemplate.fromStackSetStack(secondStackSet),
    });
  }
}
Error

/redacted/app/node_modules/constructs/src/construct.ts:428
      throw new Error(`There is already a Construct with name '${childName}' in ${typeName}${name.length > 0 ? ' [' + name + ']' : ''}`);
            ^
Error: There is already a Construct with name 'StackSetAssetsBucketDeployment' in TestStack [TestStack]
    at Node.addChild (/redacted/app/node_modules/constructs/src/construct.ts:428:13)
    at new Node (/redacted/app/node_modules/constructs/src/construct.ts:71:17)
    at new Construct (/redacted/app/node_modules/constructs/src/construct.ts:480:17)
    at new BucketDeployment (/redacted/app/node_modules/aws-cdk-lib/aws-s3-deployment/lib/bucket-deployment.js:1:803)
    at StackSetStackSynthesizer.addFileAsset (/redacted/app/node_modules/cdk-stacksets/src/stackset-stack.ts:59:32)
    at new Asset (/redacted/app/node_modules/aws-cdk-lib/aws-s3-assets/lib/asset.js:1:1207)
    at AssetCode.bind (/redacted/app/node_modules/aws-cdk-lib/aws-lambda/lib/code.js:1:4628)
    at new Function (/redacted/app/node_modules/aws-cdk-lib/aws-lambda/lib/function.js:1:7510)
    at new NodejsFunction (/redacted/app/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:1215)
    at new TestStack (/redacted/app/src/Stacks/TestStack.ts:38:5)

If I use one parent stack per StackSet it works of course. I'm doing something wrong or is that at the moment a limitation from this construct?

boenhoff avatar Oct 09 '23 12:10 boenhoff