Aws-cdk: cli: cdk synth doesn't output yaml when having dependency stacks

Created on 20 Aug 2019  路  17Comments  路  Source: aws/aws-cdk

:question: General Issue

I have a LambdaStack depending on NetworkStack's vpc. There is the code

LambdaStack

import cdk = require('@aws-cdk/core');
import lambda = require('@aws-cdk/aws-lambda');
import iam = require('@aws-cdk/aws-iam');
import vpc = require('@aws-cdk/aws-ec2')

interface LambdaStackProps extends cdk.StackProps {
  vpc: vpc.Vpc
}

export class LambdaStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props: LambdaStackProps) {
    super(scope, id, props);
    // define lambdas by using props.vpc
  }
}

NetworkStack

import cdk = require('@aws-cdk/core');
import ec2 = require("@aws-cdk/aws-ec2");
import iam = require("@aws-cdk/aws-iam");


interface NetworkStackProps extends cdk.StackProps { }

export class NetworkStack extends cdk.Stack {
  public readonly vpc: ec2.Vpc;
  constructor(scope: cdk.Construct, id: string, prop: NetworkStackProps) {
    super(scope, id, prop);
    this.vpc = new ec2.Vpc(some code here);
  }
}

app

const networkStack = new NetworkStack(app, 'network-stack-dev', { env: UsEast1Env });
const lambdaStack = new LambdaStack(app, 'lambda-stack-dev', { 
  env: UsEast1Env,
  vpc: networkStack.vpc
});

I tried to generate yaml file for LambdaStack by executing

cdk synth lambda-stack-dev > template.yaml

Then I got

Including dependency stacks: network-stack-dev
Successfully synthesized to /Users/whao/Developer/serverless-dev/cdk.out
Supply a stack name (network-stack-dev, lambda-stack-dev) to display its template.

I tried cdk synth network-stack-dev lambda-stack-dev but it gave the same output. I am kinda confused with what Supply a stack name (network-stack-dev, lambda-stack-dev) to display its template. means

I have read issue #3259 but I didn't find it helpful.
Forgive me if I am asking stupid questions.

Environment

  • CDK CLI Version: 1.4.0 (build 175471f)
  • Module Version: N/A
  • OS: macOS 10.14.6
  • Language: TypeScript
bug efformedium p1 packagtools

Most helpful comment

@sacag I was struggling with this myself and I found that if I added the --exclusively, -e flag to the synth command, I could get it to generate the YAML for the dependent stack. Hope that helps.

All 17 comments

Met same issue.

UPDATE:

I have re-structure my multi-stacks CDK app to multi-construct in single stack structure. And both cross-stack reference issue (#3705) and yaml output issue are solved 馃槂馃槂馃槂 . I don't know if this is legit but this is my solution for now and it seems to be working quite well so far. I will be keeping discovering.

We also have this issue. We found that commenting out any use of the resources shared between stacks would result in cdk synth working and outputting a YAML. It almost seems like cdk synth is recognizing it has a dependent stack, but not synthesizing it and using the synthesized resources in the dependee stack.

Our infrastructure relies on these YAML files being produced properly and we would like to maintain seperate stacks with a few shared resources to be able to deploy them separate of each other.

EDIT Our multi-stack infrastructure works correctly when doing a cdk deployment.

I have a similar issue, I'm provisioning a couple of SQS queues and I need to pass the queue url to the docker image being deployed.

When the image is being created I get the message Error: Resolution error: Cross-stack reference (x-image -> x-queues/some-queue/Resource) has not been assigned a value--call prepare() first.

I've tried explicitly declaring the dependencies by using the method addDependency but it didn't work as well.

Facing same issue, when stack have dependencies i dont see yml output
Finally, not able to run sam local on it

As a workaround, both the synthesized stack is present in the cdk.out folder in JSON format. That should unblock anyone who wants to find the synthesized stacks.

@jayrmotta - the issue you're pointing out is being tracked in #3705. This one is about cdk synth not producing the expected synthesized yaml.

Reproduction -

#!/usr/bin/env node
import cdk = require('@aws-cdk/core');
import ec2 = require('@aws-cdk/aws-ec2')
import lambda = require('@aws-cdk/aws-lambda');

interface LambdaStackProps extends cdk.StackProps {
  vpc: ec2.Vpc
}

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

    new lambda.Function(this, 'some-lambda', {
      code: lambda.Code.fromAsset('resources'),
      handler: 'index.handler',
      runtime: lambda.Runtime.NODEJS_10_X,
      vpc: props.vpc
    });
  }
}

export class NetworkStack extends cdk.Stack {
  public readonly vpc: ec2.Vpc;
  constructor(scope: cdk.Construct, id: string, prop?: cdk.StackProps) {
    super(scope, id, prop);
    this.vpc = new ec2.Vpc(this, 'some-vpc');
  }
}

const app = new cdk.App();
const networkStack = new NetworkStack(app, 'network-stack-dev');
new LambdaStack(app, 'lambda-stack-dev', { vpc: networkStack.vpc });

Commenting out the vpc: props.vpc line in the Lambda function definition generates the expected output.

It seems that this happens only when a resource from one stack is actually referenced into the other stack.

We're still seeing this issue in 1.19.0 - what's the likelihood of it being picked up? It'd be great to be able to synth stacks without relying on cdk.out and having to convert the generated json into yaml for readability

EDIT: After looking through the code in aws-cdk, it appears that what's happening is upstream stacks are being synthesized too, even if you specify a particular stack. Adding the -e flag sets exclusively to true, and only synthesizes the specified stack. It's not clear from the docs that the list of stacks to synthesize is also the list of stacks it tries to print, so if there's a dependency, it'll try to synthesize those also, and fail to print to stdout because there are more than one.

I'd suggest updating the printed text on packages/aws-cdk/bin/cdk.ts:334 to suggest that -e might help if there are dependencies.

@dabarrell - thanks for the suggestion! We'll change for this to explain this better.

Also, we're fairly good at reviewing and accepting pull requests, in case you'd like to help us out.

Hello @nija-at - do you know if there is a solution to generate YAML for dependent stacks?

I've run into an issue with CDK where I have an Elastic Beanstalk environment that may or may not be created based on a parameter.

If the environment is created, then it should be created before a pipeline that deploys to it.

I tried using the AddDependency() feature, but when I try to deploy the stack, it fails if I don't create the EB environment.

There is no way to do a conditional depencency (if creating eb environment, then the pipeline depends on it).

I though that nested stack would be a way to get around this. Create one stack with the environment first, then create a second stack with the pipeline, and add the dependency at the stack level.

There is one big issue though, when I run cdk synth no matter what I do (nested stack or just multiple top level stacks), I end up with either a main stack with empty contents like {} or a main stack that just has a bunch of parameters that reference s3 buckets.

Since my use case is service catalog entries, obviously referencing s3 buckets is a no-go.

Is there any way at all with CDK to use nested stack to get around this whole 'cannot use if statements in conjunction with dependencies' issue and still end up with a single yaml or json template that can be uploaded to Service catalog?

I would prefer to not create 2 separate service catalog entries as it is much less user-friendly workflow than just a single entry with a dropdown true/false option for creating the EB environment.

Do you have any updates on this issue?

bumping this up as a p1 to prioritize a fix

Any updates on this???

@sacag I was struggling with this myself and I found that if I added the --exclusively, -e flag to the synth command, I could get it to generate the YAML for the dependent stack. Hope that helps.

+1 for a fix anytime soon.

any news on this issue? @sacag even adding the --exclusively will generate an empty yml file. this is the command I used [ cdk synth --exclusively --profile crpdev > template-export.yml ]

Was this page helpful?
0 / 5 - 0 ratings