微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有办法从 CloudFormation 模板填充 Amazon DynamoDB 表?

如何解决有没有办法从 CloudFormation 模板填充 Amazon DynamoDB 表?

我需要创建一个 DynamoDB 表,这是它作为参数在 CloudFormation 模板中传递的属性值之一:

DynamoDB 表应如下所示:

PhoneNumber     |       OrderNumber

223546421               11545154
784578745               11547854
223458784               11547487
XXXXXXXXX               11578451

属性值“XXXXXXXXX”需要作为 CloudFormation 模板中的参数传递,以便创建 DynamoDB 表并填充上述信息。

这是构建 DynamoDB 表的当前 CF 模板:

{
    "AWstemplateFormatVersion": "2010-09-09","Resources": {
        "OrdersTable": {
            "Type": "AWS::DynamoDB::Table","Properties": {
                "TableName": "ClientOrders","AttributeDeFinitions": [
                    {
                        "AttributeName": "PhoneNumber","AttributeType": "S"
                    },{
                        "AttributeName": "OrderNumber","AttributeType": "S"
                    }
                ],"KeySchema": [
                    {
                        "AttributeName": "PhoneNumber","KeyType": "HASH"
                    },"KeyType": "RANGE"
                    }
                ],"TimetoLiveSpecification": {
                    "AttributeName": "ExpirationTime","Enabled": true
                },"ProvisionedThroughput": {
                    "ReadCapacityUnits": "10","WriteCapacityUnits": "5"
                }
            },"DependsOn": [
                "DynamoDBQueryPolicy"
            ]
        },"DynamoDBQueryPolicy": {
            "Type": "AWS::IAM::Policy","Properties": {
                "PolicyName": "DynamoDBQueryPolicy","PolicyDocument": {
                    "Version": "2012-10-17","Statement": [
                        {
                            "Effect": "Allow","Action": "dynamodb:Query","Resource": "*"
                        }
                    ]
                },"Roles": [
                    {
                        "Ref": "OrdersTableQueryRole"
                    }
                ]
            }
        },"OrdersTableQueryRole": {
            "Type": "AWS::IAM::Role","Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17","Principal": {
                                "Service": [
                                    "dynamodb.amazonaws.com"
                                ]
                            },"Action": [
                                "sts:AssumeRole"
                            ]
                        }
                    ]
                },"Path": "/"
            }
        }
    }
}

我需要帮助来用上面提到的值填充表格以及如何将提到的属性值作为参数传递。

对此的任何帮助将不胜感激。

谢谢

解决方法

我们需要 custom cloudformation 资源才能将条目添加到 Dynamo 表中。

来自文档:

使用 Lambda 函数和自定义资源,您可以在 响应堆栈事件(创建、更新和删除)。

此自定义资源调用 Lambda 函数并将 StackName 属性作为输入发送给它。该函数使用此属性从适当的堆栈中获取输出。

这是我为 1 个键创建的示例,需要一些小的更改:

我们需要两件事。

一个,一个保存 Lambda 函数的堆栈。有了这个,我们没有一个 cloudformation 资源,当我们添加/删除/更新资源时,它会在幕后调用这个 Lambda。这通常一起进入单独的堆栈。

AWSTemplateFormatVersion: '2010-09-09'
Resources:
    DynamoCfnLambdaRole:
        Type: AWS::IAM::Role
        Properties:
            AssumeRolePolicyDocument:
                Version: '2012-10-17'
                Statement:
                    - Effect: Allow
                      Principal:
                          Service:
                              - lambda.amazonaws.com
                      Action:
                          - sts:AssumeRole
            Path: '/'
            Policies:
                - PolicyName: dynamodbAccessRole
                  PolicyDocument:
                      Version: '2012-10-17'
                      Statement:
                          - Effect: Allow
                            Action:
                                - dynamodb:*
                            Resource: '*'
                          - Effect: Allow
                            Action:
                                - logs:*
                            Resource: '*'
    CfnCrtUpdDltDynamodbDocumentLambda:
        Type: AWS::Lambda::Function
        Properties:
            FunctionName: 'cfn-crt-upd-dlt-dynamodb-document'
            Code:
                ZipFile: >
                    const AWS = require("aws-sdk");
                    const response = require("./cfn-response");
                    const docClient = new AWS.DynamoDB.DocumentClient();
                    exports.handler = function(event,context) {
                      console.log(JSON.stringify(event,null,2));
                      var item = JSON.parse(event.ResourceProperties.DynamoItem);
                      var keyProperty = event.ResourceProperties.DynamoKeyProperty;
                      var tableName = event.ResourceProperties.DynamoTableName;
                      if (event.RequestType == "Create" || event.RequestType == "Update") {
                        console.log("item:",item);
                        var params = {
                          TableName: tableName,Item: item
                        };
                        console.log("Creating or Updating Document");
                        docClient.put(params,function(err,data) {                
                          if (err) {
                            console.log('error creating/updating document',err);
                            response.send(event,context,"FAILED",{},tableName + '_' + item[keyProperty]);
                          } else {
                            response.send(event,"SUCCESS",tableName + '_' + item[keyProperty]);
                          }
                        });
                      }

                      if (event.RequestType == "Delete") {
                        console.log("Deleting a Document");
                        var params = {
                          TableName: tableName,Key: {
                            [keyProperty]: item[keyProperty]
                          }
                        };
                        docClient.delete(params,data) {
                          if (err) {
                            response.send(event,{});
                          } else {
                            response.send(event,{});
                          }
                        });
                      }
                    };
            Handler: index.handler
            Role: !GetAtt DynamoCfnLambdaRole.Arn
            Runtime: nodejs10.x
            Timeout: 60

其次,我们需要添加资源块 Custom::ThisCouldBeAnything,其中 ServiceToken 指向我们上面创建的 Lambda Arn。每当我们

  • 在任何 cloudformation 中添加一个新块,Lambda 将通过 Create 调用,从而在 Dynamo 表中创建一个条目。
  • 从 Cloudformation 中删除块,将使用 Delete 调用 Lambda,从 Dynamo 表中删除条目。
  • 更改资源块中的某些内容,例如更改 DynamoItem 中的某些内容,Lambda 将通过 Update 调用。

对于需要插入 Dynamo 的每条记录,我们都需要一个资源块。

Resources:
    MyPhone223546421:
        Type: Custom::CrtUpdDltDynamodbDocumentLambda
        Properties:
            ServiceToken: !GetAtt CfnCrtUpdDltDynamodbDocumentLambda.Arn
            DynamoTableName: My-Table
            DynamoKeyProperty: 'PhoneNumber'
            DynamoItem: |
                {
                  "PhoneNumber": "223546421","OrderNumber": "11545154","someKey": "someValue"
                }
    MyPhone784578745:
        Type: Custom::CrtUpdDltDynamodbDocumentLambda
        Properties:
            ServiceToken: !GetAtt CfnCrtUpdDltDynamodbDocumentLambda.Arn
            DynamoTableName: My-Table
            DynamoKeyProperty: 'PhoneNumber'
            DynamoItem: |
                {
                  "PhoneNumber": "784578745","OrderNumber": "11547854","someKey": "someValue"
                }
,

本机无法通过 CloudFormation 向 DynamoDB 表添加行。 CloudFormation 是一种旨在创建/管理基础设施而非数据的工具。我建议在一个单独的过程中这样做。例如,如果您通过 CodePipeline 进行部署,您可以有一个在创建 CloudFormation 后运行的 CodeBuild 作业。该代码几乎可以做任何你想让它做的事情。

可以选择创建 custom resourceresource provider,但虽然有可能,但我认为这不符合其预期目的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。