简体   繁体   English

在 AWS CloudFormation 模板中引用 !Ref DynamoDB 表名

[英]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.我正在尝试在本地测试传递在我的 CloudFormation 模板文件中声明的 DynamoDB 表的表名。

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.从我阅读的所有文档中,我应该能够使用!Ref内在 function 引用 DynamoDB 资源的TableName属性值。但是,当我在本地测试时,该属性未定义。

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.我希望TABLE_NAME环境变量是DynamoDBTableName但它返回未定义。 How do I get the template to work as expected?如何让模板按预期工作?

As stated by someone else the only attributes exposed by an AWS::DynamoDB::Table are: Arn and StreamArn (See AWS CloudFormation DynamoDB Documentation ).正如其他人所说,AWS::DynamoDB::Table 公开的唯一属性是: ArnStreamArn (请参阅AWS CloudFormation DynamoDB 文档)。

Provided the syntax of the DynamoDB's arn s you can retrieve the table name in the following way:提供 DynamoDB 的arn的语法,您可以通过以下方式检索表名:

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

which will return DynamoDBTableName .这将返回DynamoDBTableName

!Ref returns a name of the resource by "logical name" and should work for your situation. !Ref通过“逻辑名称”返回资源的名称,应该适用于您的情况。 However resource (your table) should exists before you reference it, so you have 2 options:但是资源(您的表)在您引用它之前应该存在,因此您有两个选择:

  • declare you table resource earlier in the template (before you reference it)在模板中更早地声明您的表资源(在您引用它之前)

  • use DependsOn property on your lambda like在您的 lambda 上使用DependsOn属性,例如

ServerlessFunction:
    Type: AWS::Serverless::Function
    DependsOn: DynamoDBTable

As for using Fn::GetAtt :至于使用Fn::GetAtt

Based on AWS Documentation when you create a resource of type AWS::DynamoDB::Table there are only 2 attributes available for Fn::GetAtt :根据AWS 文档,当您创建AWS::DynamoDB::Table类型的资源时,只有 2 个属性可用于Fn::GetAtt

  • Arn
  • StreamArn

which means there is no way to get TableName attribute for DynamoDB table with Fn::GetAtt in current version of CloudFormation.这意味着在当前版本的Fn::GetAtt中无法使用Fn::GetAtt获取 DynamoDB 表的TableName属性。

您能否通过查看控制台中的 lambda 函数并验证环境变量不在它应该在的位置来验证这是否不起作用?

I was struggling with the same, it looks like you can't access the TableName.我也在苦苦挣扎,看起来您无法访问 TableName。

The workaround I'm doing is to call the resource in the tamplate.yml with the same table name...我正在做的解决方法是使用相同的表名调用 tamplate.yml 中的资源...

In template.yml:在 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:然后,在我的 .js 组件中:

const tableName = process.env.DYNAMODB_TABLE;

I hope they solve this soon.... this way is not ideal.我希望他们尽快解决这个问题……这种方式并不理想。 Cheers!干杯!

Even though !Ref does return the Logical id of the resource, in this case the DyanmoDB table name, you need to make sure that the resource exist before referencing it.即使 !Ref 确实返回资源的逻辑 id,在这种情况下是 DyanmoDB 表名,您需要在引用资源之前确保该资源存在。

As far as I can see in your code the function creation is not dependent on the Dynamo table beign created first据我在您的代码中看到的功能创建不依赖于首先创建的 Dynamo 表

ServerlessFunction:
Type: AWS::Serverless::Function
Properties:
  Runtime: nodejs10.x
  Handler: index.handler
  Environment: 
    Variables:
      TABLE_NAME: !Ref DynamoDBTable 
  Events:
    GetCocktails:
      Type: Api
      Properties:
        Path: /
        Method: get

In this case CFN will create resources from top to bottom meaning the lambda function will be created before the DyanoDb table causing the !Ref to be undefined given the fact that the table does not exist yet.在这种情况下,CFN 将从上到下创建资源,这意味着 lambda 函数将在 DyanoDb 表之前创建,导致 !Ref 未定义,因为该表尚不存在。 You can fix this by adding a dependency on the lambda resource like so:您可以通过添加对 lambda 资源的依赖来解决此问题,如下所示:

ServerlessFunction:
DependsOn: DyanamoDBTable # <- will not be created before the dyanmoDB table
Type: AWS::Serverless::Function
Properties:
  Runtime: nodejs10.x
  Handler: index.handler
  Environment: 
    Variables:
      TABLE_NAME: !Ref DynamoDBTable
  Events:
    GetCocktails:
      Type: Api
      Properties:
        Path: /
        Method: get

This will make sure that no matter what, your table is created first and then the !Ref to the resource will not be undefined since the table already exist and can be referenced这将确保无论如何,首先创建您的表,然后对资源的 !Ref 不会未定义,因为该表已经存在并且可以被引用

The !Ref DynamoDBTable returns the ARN from your resource so, you get your reference response like this: !Ref DynamoDBTable从您的资源中返回ARN ,因此您会得到如下的参考响应:

arn:aws:dynamodb:us-east-1:123456789012:table/testddbstack-myDynamoDBTable-012A1SL7SMP5Q/stream/2015-11-30T20:10:00.000 . arn:aws:dynamodb:us-east-1:123456789012:table/testddbstack-myDynamoDBTable-012A1SL7SMP5Q/stream/2015-11-30T20:10:00.000

Instead you only need to provide the name DynamoDBTableName so, my suggestion is to use !GetAtt CloudFormation intrinsic function and get the name: !GetAtt DynamoDBTable.TableName相反,您只需要提供名称DynamoDBTableName因此,我的建议是使用!GetAtt CloudFormation内部函数并获取名称: !GetAtt DynamoDBTable.TableName

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS DynamoDB Cloudformation 模板验证失败 - “未加密”, - 但它是 - AWS DynamoDB Cloudformation template validation failing - "not encrypted", - but it is 如何在 AWS CloudFormation 模板中使用参考号 function? - How is the !Ref function used in an AWS CloudFormation template? 我们如何在 Cloudformation 模板中将相同的标签用于两个 AWS::DynamoDB::Table - How we can use same Tags into two AWS::DynamoDB::Table with in Cloudformation Template 如何在Cloudformation模板中引用DynamoDB表的最新Stream - How to reference the latest Stream of a DynamoDB table in a Cloudformation template AWS 上的 CloudFormation 模板错误 - CloudFormation Template errors on AWS 在没有参数化的情况下在 AWS CloudFormation 中引用 EC2 实例的名称标签 - Referencing an EC2 instance's name tag in AWS CloudFormation without parameterization 当使用 cloudformation 模板对 dynamodb 表进行任何更改时,如何触发 Function? - How trigger Function when any changes in dynamodb table using cloudformation template? AWS CDK Typescript 模板中未生成导入 DynamoDB 表 - AWS CDK Typescript Import DynamoDB table not generated in template AWS Cloudformation 模板配置无效 - AWS Cloudformation template configuration is not valid 如何使用 AWS Cli 更新 DynamoDB 中的现有表名? - How to update existing table name in DynamoDB using AWS Cli?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM