簡體   English   中英

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

[英]Referencing !Ref DynamoDB table name in a AWS CloudFormation template

我正在嘗試在本地測試傳遞在我的 CloudFormation 模板文件中聲明的 DynamoDB 表的表名。

從我閱讀的所有文檔中,我應該能夠使用!Ref內在 function 引用 DynamoDB 資源的TableName屬性值。但是,當我在本地測試時,該屬性未定義。

考慮以下示例:

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但它返回未定義。 如何讓模板按預期工作?

正如其他人所說,AWS::DynamoDB::Table 公開的唯一屬性是: ArnStreamArn (請參閱AWS CloudFormation DynamoDB 文檔)。

提供 DynamoDB 的arn的語法,您可以通過以下方式檢索表名:

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

這將返回DynamoDBTableName

!Ref通過“邏輯名稱”返回資源的名稱,應該適用於您的情況。 但是資源(您的表)在您引用它之前應該存在,因此您有兩個選擇:

  • 在模板中更早地聲明您的表資源(在您引用它之前)

  • 在您的 lambda 上使用DependsOn屬性,例如

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

至於使用Fn::GetAtt

根據AWS 文檔,當您創建AWS::DynamoDB::Table類型的資源時,只有 2 個屬性可用於Fn::GetAtt

  • Arn
  • StreamArn

這意味着在當前版本的Fn::GetAtt中無法使用Fn::GetAtt獲取 DynamoDB 表的TableName屬性。

您能否通過查看控制台中的 lambda 函數並驗證環境變量不在它應該在的位置來驗證這是否不起作用?

我也在苦苦掙扎,看起來您無法訪問 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;

我希望他們盡快解決這個問題……這種方式並不理想。 干杯!

即使 !Ref 確實返回資源的邏輯 id,在這種情況下是 DyanmoDB 表名,您需要在引用資源之前確保該資源存在。

據我在您的代碼中看到的功能創建不依賴於首先創建的 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

在這種情況下,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 不會未定義,因為該表已經存在並且可以被引用

!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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM