Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Referencing !Ref DynamoDB table name in a AWS CloudFormation template

I am trying to locally test passing the table name of a DynamoDB table as declared in my CloudFormation template file.

From all the documentation I have read, I should be able to reference the the TableName property value of a DynamoDB resource using the !Ref intrinsic function. However when I test this locally the property is undefined.

Consider the following example:

Transform: 'AWS::Serverless-2016-10-31'
Resources:
  ServerlessFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: nodejs10.x
      Handler: index.handler
      Environment: 
        Variables:
          TABLE_NAME: !Ref DynamoDBTable # <- returning undefined
      Events:
        GetCocktails:
          Type: Api
          Properties:
            Path: /
            Method: get
  DynamoDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: DynamoDBTableName
      AttributeDefinitions:
        - AttributeName: ID
          AttributeType: S
      KeySchema:
        - AttributeName: ID
          KeyType: HASH
      ProvisionedThroughput: 
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1

I expect the TABLE_NAME environment variable to be DynamoDBTableName however it returns undefined. How do I get the template to work as expected?

like image 523
McShaman Avatar asked Aug 06 '19 03:08

McShaman


2 Answers

As stated by someone else the only attributes exposed by an AWS::DynamoDB::Table are: Arn and StreamArn (See AWS CloudFormation DynamoDB Documentation).

Provided the syntax of the DynamoDB's arns you can retrieve the table name in the following way:

      Environment: 
        Variables:
          TABLE_NAME: !Select [1, !Split ['/', !GetAtt DynamoDBTable.Arn]] 

which will return DynamoDBTableName.

like image 200
Lord of the Goo Avatar answered Sep 18 '22 18:09

Lord of the Goo


I was struggling with the same, it looks like you can't access the TableName.

The workaround I'm doing is to call the resource in the tamplate.yml with the same table name...

In template.yml:

Globals:
  Function:
    Runtime: nodejs12.x
    ...
    Environment:
      Variables:
        DYNAMODB_TABLE: !Ref MyDynamoTable
MyDynamoTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: MyDynamoTable
      AttributeDefinitions:
        - AttributeName: PK
          AttributeType: S
        - AttributeName: SK
          AttributeType: S

Then, in my .js component:

const tableName = process.env.DYNAMODB_TABLE;

I hope they solve this soon.... this way is not ideal. Cheers!

like image 44
Nacho Avatar answered Sep 17 '22 18:09

Nacho