skip to Main Content

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


  1. 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:

    Docs: Output values are available after the stack operation is complete. Stack output values aren’t available when a stack status is in any of the IN_PROGRESS status.

    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.

    Login or Signup to reply.
  2. 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.:

    class DynamoDBConstruct extends Construct {
        public readonly tableName: string;
    
        constructor(scope: Construct, id: string, props: Whatever) {
            super(scope, id);
    
            const table = new Table(this, 'Table', {
                partitionKey: { name: 'id', type: AttributeType.STRING },
                billingMode: BillingMode.PAY_PER_REQUEST,
                // omitting table name on purpose - it will be generated by CDK
            });
    
            this.tableName = table.tableName;
        }
    }
    

    Now inside your stack, you can simply use that table name:

    class MyStack extends Stack {
        constructor(scope: App, id: string, props: Whatever) {
            const table = new DynamoDBConstruct(...);
            const myOtherConstruct = new MyOtherConstruct(this, 'myOtherConstruct', {
                // using table name here
                tableName: table.tableName,
            });
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search