I’ve following stack which deploys the two constructs within. The construct DynamoDBConstruct
exports the table name, and the construct IAMRoleConstruct
consumes it. However, during deployment, it fails stating No export named dbTableName found
, despite the fact that dependency is added/specified, the IAMRoleConstruct
gets deployed first, why?
Stack:
public AllStacks(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
var db = new DynamoDBConstruct(this, "DynamoDB");
var iam = new IAMRoleConstruct(this, "IAMRole");
iam.Node.AddDependency(db);
}
DynamoDBConstruct
public DynamoDBConstruct(Construct scope, string id): base(scope, id)
{
var dbTable = new Table(this, "dbTable", new TableProps()
{
PartitionKey = new Attribute
{
Name = "contactID",
Type = AttributeType.STRING
},
TableClass = TableClass.STANDARD,
TableName = (string)Node.TryGetContext("dbTableName"),
RemovalPolicy = RemovalPolicy.DESTROY
});
new CfnOutput(this, "OutputTableName", new CfnOutputProps()
{
ExportName = "dbTableName",
Value = dbTable.TableName
});
}
IAMRoleConstruct
public IAMRoleConstruct(Construct scope, string id) : base(scope, id)
{
var dbTableName = Fn.ImportValue("dbTableName");
/*
Some code
.
*/
}
2
Answers
The reason for the error is that you are trying to produce and consume a Stack Output in the same stack. That won’t work:
No worries! As @Victor says, there is a much easier alternative. Get rid of the Outputs. Instead, share data between your custom constructs by declaring public fields (e.g.
public Table table
) in the providing class, passing the references as props to the consuming class. This is what the CDK constructs do.See the C# example stacks in the aws-cdk-examples repo.
With the disclaimer that I am not sure what language your code is in, I’m going to write in CDK’s native language (which I recommend you to do as well) – Typescript.
The problem comes most likely from the fact that you are using the export within the same CDK/CFN stack. The export won’t be available during stack creation, as that is part of the stack creation itself.
When you’re working within a single stack, the simplest, most intuitive way of "moving data" from one construct to another is to just expose values through a public member of your class, e.g.:
Now inside your stack, you can simply use that table name: