-
General Issuecdk synth fails on CfnInclude when using ref on sam generated resource The QuestionWe use Example (simplified) template: AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Resources:
MyServerlessFunction:
Type: "AWS::Serverless::Function"
Properties:
AutoPublishAlias: myalias
FunctionName: MyFunction
CodeUri: index.js
GGCoreLambdaComponent:
Type: AWS::GreengrassV2::ComponentVersion
Properties:
LambdaFunction:
LambdaArn: !Ref MyServerlessFunction.Version #this is the failing line This would generate the error I understand why it's erroring and that the If helpful, the cdk code is the following: import * as cdk from "aws-cdk-lib";
import { CfnInclude } from "aws-cdk-lib/cloudformation-include";
import { Construct } from "constructs";
import { readdirSync, existsSync } from "fs";
const stackName = "GreengrassComponentsNode";
const entries = readdirSync("./components", { withFileTypes: true })
.filter(
(dirent) =>
dirent.isDirectory() &&
existsSync(`./components/${dirent.name}/template.yml`)
)
.map((dirent) => {
return {
name: dirent.name,
template: `./components/${dirent.name}/template.yml`,
};
});
class GreengrassComponentsStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new CfnInclude(this, "BaseTemplate", {
templateFile: "./template.yml",
});
entries.forEach((entry) => {
new CfnInclude(this, entry.name, {
templateFile: entry.template,
});
});
}
}
const app = new cdk.App();
new GreengrassComponentsStack(app, stackName); CDK CLI Version2.18.0 Framework VersionNo response Node.js Version16.6.2 OSmacOS, linux LanguageTypescript Language VersionTypeScript (4.5.4) Other informationStacktrace
Other possible workaroundsThese are pretty specific to our use case but:
But we'd like to avoid these more error prone and manual steps. |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments
-
Hey @jluttrell, thanks for opening the issue. This is indeed a very tricky situation. I think you should be able to unblock yourself by downloading the processed template from the CloudFormation console, and including that. Now, that will make But there's actually a problem, because a no-op deployment will not update the template, so cfnInclude = new CfnInclude(this, "BaseTemplate", {
templateFile: "./template.yml",
});
const r = cfnInclude.getResource('MyServerlessFunction');
r.addMetadata('A', 'B'); So, to sum up:
Hope this helps! Thanks, |
Beta Was this translation helpful? Give feedback.
-
hi @skinny85, thanks for the quick response! I understand the process you've outlined. Indeed, pre-processing the individual templates with SAM would solve the issue. However, this process runs in our CI/CD pipeline so manual step of downloading processed template isn't possible. As far as I remember, SAM requires the template to be processed in the cloud. So I'm not sure how I could pre-process all the child templates and then use cdk to include the already processed templates. But I'll look into if/how that's possible. To give brief background on what we're trying to achieve, we want individuals to create greengrass core components (and required aws resources such as iam roles/policies, dynamo tables, sqs queues, etc) in this mono repo using cloudformation templates they're familiar with and then compiling them all into a single template (automated using the cdk) for deployment to a single stack. We could use only SAM (and no cdk) and have a "master" template that directly references each of the individual component templates as i.e. ComponentOne:
Type: AWS::Serverless::Application
Properties:
Location: ./components/ComponentOne/template.yml
ComponentTwo:
Type: AWS::Serverless::Application
Properties:
Location: ./components/ComponentTwo/template.yml And this wouldn't be a terrible solution but this would require a manual update of the child template path in the master template for each created/deleted template and I thought we'd try and be clever using the cdk to automate that 😎 Which makes me think we may be able to use the cdk to add the child templates as More in regards to the cdk, are there any plans to better integrate with SAM, perhaps not in processing the template but at least parsing SAM schema (such as any of its referenceable properties on autogenerated resources) as valid? So that we could use |
Beta Was this translation helpful? Give feedback.
-
Got it to work by including the child templates as import * as cdk from "aws-cdk-lib";
import { CfnInclude } from "aws-cdk-lib/cloudformation-include";
import { aws_sam as sam } from "aws-cdk-lib";
import { Construct } from "constructs";
import { readdirSync, existsSync } from "fs";
const stackName = "GreengrassComponentsNode";
const entries = readdirSync("./components", { withFileTypes: true })
.filter(
(dirent) =>
dirent.isDirectory() &&
existsSync(`./components/${dirent.name}/template.yml`)
)
.map((dirent) => {
return {
name: dirent.name,
template: `./components/${dirent.name}/template.yml`,
};
});
class GreengrassComponentsStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new CfnInclude(this, "BaseTemplate", {
templateFile: "./template.yml",
});
entries.forEach((entry) => {
new sam.CfnApplication(this, entry.name, {
location: entry.template,
});
});
}
}
const app = new cdk.App();
new GreengrassComponentsStack(app, stackName); Now the child templates are created as nested stacks but that may be even better than all as a single stack. Thanks for the help! |
Beta Was this translation helpful? Give feedback.
-
I'm glad you got it working @jluttrell!
I meant downloading the processed template from the CloudFormation console: Not sure if there's a way to do it through the CloudFormation API though. |
Beta Was this translation helpful? Give feedback.
-
Hello! Reopening this discussion to make it searchable. |
Beta Was this translation helpful? Give feedback.
Hey @jluttrell,
thanks for opening the issue. This is indeed a very tricky situation.
I think you should be able to unblock yourself by downloading the processed template from the CloudFormation console, and including that. Now, that will make
cdk diff
show a million changes. However! I believe runningcdk deploy
should actually not replace anything, and just be a no-op. But, to make sure I'm right, please test it on a development environment before doing this in production!But there's actually a problem, because a no-op deployment will not update the template, so
cdk diff
ran after the deployment will still show the million changes. So, you need to make any change to the Stack so that i…