[英]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 公开的唯一属性是:
Arn
和StreamArn
(请参阅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.