I have a Service Catalog portfolio that has a product deployed to it. The product is created from a basic AWS CDK Construct (S3 Bucket). I want to extend the product's usefulness by adding a parameter that a user can populate when consuming the product. This seems easy when I'm using a Construct in the ProductStack:
export class ScConstructDemoStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const portfolio = new Portfolio(this, 'myportfolio', {
displayName: 'Test Portfolio',
providerName: 'Acme Corp'
});
const bucketConstructCFProduct = new CloudFormationProduct(this, 'SCProduct_construct_bucket', {
productName: 'S3FromConstructWithParam',
owner: 'me',
productVersions: [{
cloudFormationTemplate: CloudFormationTemplate.fromProductStack(new myS3ConstructProduct(this, 'S3FromConstructWithParam')),
productVersionName: 'v1',
description: 'Quick S3 Bucket'
}]
});
portfolio.addProduct(bucketConstructCFProduct);
}
}
class myS3ConstructProduct extends ProductStack {
constructor(scope: Construct, id: string) {
super(scope, id);
const uploadBucketName = new CfnParameter(this, 'bucketNameParam', {
type: 'String',
description: 'Name of S3 Bucket',
});
const bucket = new Bucket(this, 'construct-bucket', {
bucketName: uploadBucketName.valueAsString
});
}
}
This works.
However, I also have a CDK Stack that I want to add to Service Catalog. This stack is defined with a CfnParameter that I would expect to be available when provisioning the Product.
export class ScCdkDemoStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const portfolio = new Portfolio(this, 'myportfolio', {
displayName: 'Test Portfolio',
providerName: 'Acme Corp'
});
const bucketCFProduct = new CloudFormationProduct(this, 'SCProduct_bucket', {
productName: 'S3WithParam',
owner: 'me',
productVersions: [{
cloudFormationTemplate: CloudFormationTemplate.fromProductStack(new myS3StackProduct(this, 'S3WithParam')),
productVersionName: 'v1',
description: 'Quick S3 Bucket'
}]
});
portfolio.addProduct(bucketCFProduct);
}
}
interface bucketProps extends StackProps {
readonly bucketName: string
}
class myS3Stack extends Stack {
constructor(scope: Construct, id: string, props: bucketProps) {
super(scope, id, props);
const bucket = new Bucket(this, 'mybucket', {
bucketName: props.bucketName
});
}
}
class myS3StackProduct extends ProductStack {
constructor(scope: Construct, id: string) {
super(scope, id);
const uploadBucketName = new CfnParameter(this, 'bucketNameParam', {
type: 'String',
description: 'Name of S3 Bucket',
});
const deployStack = new myS3Stack(this, 's3StackProduct', {
bucketName: uploadBucketName.valueAsString
})
}
}
When I synth this CDK code I get an exception which I read as something (probably the CfnParameter) is missing / undefined when the Stack is created.
Error: Artifact StackDemoStackS3WithParams3StackProduct88DBCA37 depends on non-existing artifact StackDemoStackS3WithParamDFB09CA4
at /Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/cx-api/lib/cloud-artifact.js:1:1310
at Array.map (<anonymous>)
at CloudFormationStackArtifact.get dependencies [as dependencies] (/Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/cx-api/lib/cloud-artifact.js:1:1244)
at CloudAssembly.validateDeps (/Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/cx-api/lib/cloud-assembly.js:1:3861)
at new CloudAssembly (/Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/cx-api/lib/cloud-assembly.js:1:1219)
at CloudAssemblyBuilder.buildAssembly (/Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/cx-api/lib/cloud-assembly.js:1:6098)
at Object.synthesize (/Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/core/lib/private/synthesis.js:1:800)
at App.synth (/Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/core/lib/stage.js:1:1866)
at process.<anonymous> (/Users/ben/code/sc_cdk_demo/node_modules/aws-cdk-lib/core/lib/app.js:1:1164)
at Object.onceWrapper (node:events:642:26)
Subprocess exited with error 1
Can anyone tell me why I can't pass a Parameter to a Stack like this or point out my daft mistake?
Many Thanks
nb. I'm new to TypeScript, the CDK repo this code lives in is here
The error looks like there is an issue with dependencies between stacks. Your
myS3StackProductstack doesn't really need to be dependent on themyS3Stack. Instead, you can define the S3 bucket and parameter in the product stack like this:This will remove
myS3StackProduct's dependency onmyS3Stack.