我正在尝试在本地测试传递CloudFormation模板文件中声明的DynamoDB表的表名。
从我阅读的所有文档中,我应该能够使用TableName
内在函数来引用DynamoDB资源的!Ref
属性值。但是,当我在本地测试此属性时,该属性未定义。
考虑以下示例:
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
我希望TABLE_NAME
环境变量为DynamoDBTableName
,但是它返回未定义的值。如何使模板按预期工作?
答案 0 :(得分:1)
您是否可以通过在控制台中查看lambda函数并在不应该位于其预期位置的下方验证环境变量来验证其是否无效?
答案 1 :(得分:0)
!Ref
通过“逻辑名称”返回资源的名称,并且应该适合您的情况。但是,资源(您的表)在引用之前应该已经存在,因此您有2个选择:
在模板的较早位置(在引用之前)声明您的表资源
在您的lambda上使用DependsOn
属性,例如
ServerlessFunction:
Type: AWS::Serverless::Function
DependsOn: DynamoDBTable
关于使用Fn::GetAtt
:
基于AWS Documentation,当您创建类型为AWS::DynamoDB::Table
的资源时,Fn::GetAtt
只有2个属性可用:
Arn
StreamArn
,这意味着在当前版本的CloudFormation中,无法使用TableName
获取DynamoDB表的Fn::GetAtt
属性。
答案 2 :(得分:0)
如其他人所述,AWS :: DynamoDB :: Table公开的唯一属性是:
Arn
和StreamArn
(请参阅AWS CloudFormation DynamoDB Documentation)。
提供了DynamoDB arn
的语法,您可以通过以下方式检索表名:
Environment:
Variables:
TABLE_NAME: !Select [1, !Split ['/', !GetAtt DynamoDBTable.Arn]]
这将返回DynamoDBTableName
。
答案 3 :(得分:0)
我也遇到了同样的问题,您似乎无法访问 TableName。
我正在做的解决方法是使用相同的表名调用 tamplate.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
然后,在我的 .js 组件中:
const tableName = process.env.DYNAMODB_TABLE;
我希望他们尽快解决这个问题……这种方式并不理想。 干杯!
答案 4 :(得分:-1)
!Ref DynamoDBTable
从您的资源中返回ARN,因此,您将获得如下的参考响应:
arn:aws:dynamodb:us-east-1:123456789012:table/testddbstack-myDynamoDBTable-012A1SL7SMP5Q/stream/2015-11-30T20:10:00.000
。
相反,您只需要提供名称DynamoDBTableName
,因此,我的建议是使用!GetAtt CloudFormation内在函数并获得名称:
!GetAtt DynamoDBTable.TableName
答案 5 :(得分:-2)
即使!Ref确实返回了资源的逻辑ID,在本例中为DyanmoDB表名,您仍需要在引用之前确保该资源存在。
据我在您的代码中看到的那样,函数的创建不依赖于首先创建的Dynamo表beign
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
在这种情况下,CFN将自上而下创建资源,这意味着lambda函数将在DyanoDb表之前创建,从而导致!Ref不确定,因为该表尚不存在。您可以通过添加对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
这将确保无论如何先创建您的表,然后再对资源的!Ref进行定义,因为该表已经存在并且可以被引用