Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(aws_servicecatalog): nested stack in product stack failed in cdk synth #24317

Closed
kobe9286 opened this issue Feb 24, 2023 · 6 comments · Fixed by #26311
Closed

(aws_servicecatalog): nested stack in product stack failed in cdk synth #24317

kobe9286 opened this issue Feb 24, 2023 · 6 comments · Fixed by #26311
Assignees
Labels
@aws-cdk/aws-servicecatalog Related to AWS Service Catalog bug This issue is a bug. effort/medium Medium work item – several days of effort in-progress This issue is being actively worked on. p1

Comments

@kobe9286
Copy link

Describe the bug

When nested stack in product stack for AWS Service Catalog, Cannot find asset error for nested stack's template file occurs in cdk synth.

Expected Behavior

cdk synth should generate nested stack's template in product stack.

Current Behavior

Error: Cannot find asset at /path/to/project/root/cdk.out/ServicecatalogSampleStackSampleProductStackSampleNestedStack62A00127.nested.template.json
    at new AssetStaging (/path/to/project/root/node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:1298)
    at new Asset (/path/to/project/root/node_modules/aws-cdk-lib/aws-s3-assets/lib/asset.js:1:736)
    at Object.bind (/path/to/project/root/node_modules/aws-cdk-lib/aws-s3-deployment/lib/source.js:1:1200)
    at /path/to/project/root/node_modules/aws-cdk-lib/aws-s3-deployment/lib/bucket-deployment.js:1:2942
    at Array.map (<anonymous>)
    at new BucketDeployment (/path/to/project/root/node_modules/aws-cdk-lib/aws-s3-deployment/lib/bucket-deployment.js:1:2923)
    at ProductStackSynthesizer.addFileAsset (/path/to/project/root/node_modules/aws-cdk-lib/aws-servicecatalog/lib/private/product-stack-synthesizer.js:1:944)
    at SampleNestedStack._prepareTemplateAsset (/path/to/project/root/node_modules/aws-cdk-lib/core/lib/nested-stack.js:1:2902)
    at defineNestedStackAsset (/path/to/project/root/node_modules/aws-cdk-lib/core/lib/private/prepare-app.js:1:845)
    at Object.prepareApp (/path/to/project/root/node_modules/aws-cdk-lib/core/lib/private/prepare-app.js:1:695)

Subprocess exited with error 1

Reproduction Steps

1. Use case:

If you want to write your product stack in CDK and use nested stack for better modularity.

2. Code Replication:

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import {
  aws_servicecatalog as sc,
  aws_s3 as s3,
  NestedStack,
  Stack,
} from 'aws-cdk-lib'

const app = new cdk.App();

export class ServiceCatalogSampleStack extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);


    new sc.CloudFormationProduct(this, 'SampleProduct', {
      productName: 'Sample Product',
      owner: 'owner',
      productVersions: [
        {
          productVersionName: 'v1',
          cloudFormationTemplate: sc.CloudFormationTemplate.fromProductStack(new SampleProductStack(this, 'SampleProductStack', {
            assetBucket: new s3.Bucket(this, 'AssetBucket', {
              bucketName: 'asset-bucket-for-service-catalog-' + Stack.of(this).account
            }),
          })),
        },
      ],
    });
  }
}

export class SampleNestedStack extends NestedStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new s3.Bucket(this, 'SampleBucketInNestedStack');
  }
}

export class SampleProductStack extends sc.ProductStack {
  constructor(scope: Construct, id: string, props: sc.ProductStackProps) {
    super(scope, id, props);

    new SampleNestedStack(this, 'SampleNestedStack');
  }
}
new ServiceCatalogSampleStack(app, 'ServicecatalogSampleStack');

Possible Solution

Create asset for nested stack's template in product stack.

Additional Information/Context

No response

CDK CLI Version

2.66.0 (build c96c17d)

Framework Version

No response

Node.js Version

v18.7.0

OS

macOS Ventura 13.2.1

Language

Typescript

Language Version

Version 4.9.5

Other information

No response

@kobe9286 kobe9286 added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Feb 24, 2023
@github-actions github-actions bot added the @aws-cdk/aws-servicecatalog Related to AWS Service Catalog label Feb 24, 2023
@gbvanrenswoude
Copy link

This fails as well using npx cdk list and the default test setup with npm run test:update / npm run test. Additionally this fails as well in cdk-pipelines Stages.

For example, using a ProductStack using Assets:

class LpeProduct extends sc.ProductStack {
  constructor(scope: Construct, id: string, props: sc.ProductStackProps) {
    super(scope, id, props);

    new s3.Bucket(this, "LpeBucketSc", {
      removalPolicy: RemovalPolicy.DESTROY,
    });
    new s3.Bucket(this, "AnotherLpeBucketSc", {
      removalPolicy: RemovalPolicy.DESTROY,
    });

    // this generates an asset
    const handler = new lambdaNodeJs.NodejsFunction(this, "LpeLambdaSc", {
      entry: "src/example-lambda.ts", // add this to disk if running this example
      bundling: {
        minify: true,
      },
    });

    new apigateway.LambdaRestApi(this, "LpeApiSc", {
      handler,
    });
  }
}

and consuming it in a Stack:

export class LpeServiceCatalogStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const assetBucket = new s3.Bucket(this, "LpeBucket", {
      bucketName: `${id}-assets-bucket`,
      removalPolicy: RemovalPolicy.DESTROY,
    });
    const portfolio = new sc.Portfolio(this, "LpePortfolio", {
      displayName: id,
      providerName: "LpeAdmin",
      description:
        "Sadness",
      messageLanguage: sc.MessageLanguage.EN,
    });

    const productStackHistory = new sc.ProductStackHistory(
      this,
      "ProductStackHistory",
      {
        productStack: new LpeProduct(this, "MyProductStack", {
          assetBucket: assetBucket,
        }),
        currentVersionName: "v2",
        currentVersionLocked: true,
        validateTemplate: true,
      }
    );

    const product = new sc.CloudFormationProduct(this, "LpeProduct", {
      productName: "An example Product",
      owner: "some Product Owner",
      productVersions: [
        productStackHistory.currentVersion(),
        productStackHistory.versionFromSnapshot("v1"),
      ],
    });

    portfolio.addProduct(product);
  }
}

in all above variations mentioned throws the similar Error.

@pahud pahud added needs-reproduction This issue needs reproduction. and removed needs-triage This issue or PR still needs to be triaged. labels Mar 1, 2023
@pahud pahud self-assigned this Mar 1, 2023
@pahud
Copy link
Contributor

pahud commented Mar 15, 2023

Yes I can reproduce this error but no idea off the top of my head. Making this a p1 bug for now.

@pahud pahud added the p1 label Mar 15, 2023
@pahud pahud removed their assignment Mar 15, 2023
@bendudz
Copy link

bendudz commented Apr 25, 2023

Hi is there any update on this please?

I’m seeing the same issue. It looks like the *.nested.template.json or tree.json or manifest.json or asset.json files are not generated & added to the cdk.out folder.

It looks like the “asset.{guid}” folders & zips are present.

@pahud pahud added effort/medium Medium work item – several days of effort needs-review and removed needs-reproduction This issue needs reproduction. needs-review labels May 9, 2023
@mackalex
Copy link
Contributor

Hi all. I am working on reproducing the issue locally to determine if this bug encompasses all asset generation when using ProductStack or if it's more exclusive to certain Lambda constructs and nested stacks. I'll report my results here and what I find.

@mackalex
Copy link
Contributor

I reproduced the problem locally and determined that the ProductStack stack synthesizer implementation does not add a file asset to the manifest for NestedStacks in the same way that the DefaultStackSynthesizer does. Rather, the ProductStackSynthesizer takes an existing asset's path (such as a Lambda's source code file in a working directory) and tells CDK to synth a bucket deployment to publish that existing asset to a S3 Bucket (here). This seems like an edge-case that was missed during the implementation of file asset support in the SC ProductStack CDK construct which unit tests could have caught after designing a test plan.

I think a potential solution is to replicate the behavior of asset file generation from the DefaultStackSynthesizer into the ProductStack synthesizer's implementation of addFileAsset().

At this time, the Service Catalog team does not plan to prioritize this bug fix. Is there curiosity from other engineers who are willing to pick up the implementation of this solution?

@colifran colifran added the in-progress This issue is being actively worked on. label Jun 26, 2023
@mergify mergify bot closed this as completed in #26311 Jul 12, 2023
mergify bot pushed a commit that referenced this issue Jul 12, 2023
This PR fixes a bug that prevented a nested stack from being used within a product stack. The logic in the `addFileAsset` method as part of the `ProductStackSynthesizer` was updated to forward all assets to the parent stack and uses the `FileAssetLocation` returned from the parent stack synthesizer to create a bucket `Source` from the  `bucketName` and `objectKey`.

Closes #24317

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

bmoffatt pushed a commit to bmoffatt/aws-cdk that referenced this issue Jul 29, 2023
This PR fixes a bug that prevented a nested stack from being used within a product stack. The logic in the `addFileAsset` method as part of the `ProductStackSynthesizer` was updated to forward all assets to the parent stack and uses the `FileAssetLocation` returned from the parent stack synthesizer to create a bucket `Source` from the  `bucketName` and `objectKey`.

Closes aws#24317

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-servicecatalog Related to AWS Service Catalog bug This issue is a bug. effort/medium Medium work item – several days of effort in-progress This issue is being actively worked on. p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants