AWS - 使用CloudFormation将数据从一个S3存储桶移动到另一个存储桶

时间:2015-11-02 17:06:16

标签: amazon-web-services amazon-s3 aws-lambda amazon-cloudformation

我尝试使用CloudFormation创建堆栈。堆栈需要从中央S3存储桶中获取一些数据文件并将其复制到自己的“本地”存储桶中。桶。

我已经写了一个lambda函数来执行此操作,当我在带有测试事件的Lambda控制台中运行它时它会起作用(测试事件使用真正的中央存储库并成功复制该文件到指定的仓库。)

我当前的CloudFormation脚本执行以下操作:

  1. 创建" local" S3桶
  2. 创建Lambda函数可用于访问存储桶的角色
  3. 定义Lambda函数以将指定文件移动到" local"桶
  4. 定义一些自定义资源以调用Lambda函数。
  5. 它在第4步开始出错 - Cloudformation执行似乎在这里冻结(CREATE_IN_PROGESS)。此外,当我尝试删除堆栈时,它似乎只会卡在DELETE_IN_PROGRESS上。

    以下是我在CloudFormation脚本中调用Lambda函数的方法:

    "DataSync": {
        "Type": "Custom::S3DataSync",
        "Properties": {
            "ServiceToken": { "Fn::GetAtt" : [ "S3DataSync", "Arn" ] },
            "InputFile": "data/provided-as-ip-v6.json",
            "OutputFile": "data/data.json"
        }
    },
    "KeySync1": {
        "Type": "Custom::S3DataSync",
        "Properties": {
            "ServiceToken": { "Fn::GetAtt" : [ "S3DataSync", "Arn" ] },
            "InputFile": "keys/1/public_key.pem"
        }
    },
    "KeySync2": {
        "Type": "Custom::S3DataSync",
        "Properties": {
            "ServiceToken": { "Fn::GetAtt" : [ "S3DataSync", "Arn" ] },
            "InputFile": "keys/2/public_key.pem"
        }
    }
    

    Lambda函数本身:

    exports.handler = function(event, context) {
        var buckets = {};
        buckets.in = {
            "Bucket":"central-data-repository",
            "Key":"sandbox" + "/" + event.ResourceProperties.InputFile
        };   
        buckets.out = {       
            "Bucket":"sandbox-data",       
            "Key":event.ResourceProperties.OutputFile || event.ResourceProperties.InputFile   
        };   
    
        var AWS = require('aws-sdk');   
        var S3 = new AWS.S3();   
    
        S3.getObject(buckets.in, function(err, data) {       
            if (err) {           
                console.log("Couldn't get file " + buckets.in.Key);           
                context.fail("Error getting file: " + err)       
            }       
            else {           
                buckets.out.Body = data.Body;           
                S3.putObject(buckets.out, function(err, data) {               
                    if (err) {                   
                        console.log("Couln't write to S3 bucket " + buckets.out.Bucket);                   
                        context.fail("Error writing file: " + err);               
                    }               
                    else {                   
                        console.log("Successfully copied " + buckets.in.Key + " to " + buckets.out.Bucket + " at " + buckets.out.Key);                   
                        context.succeed();               
                    }           
                });       
            }   
        });
    }
    

2 个答案:

答案 0 :(得分:3)

您的自定义资源功能需要将信号发送回CloudFormation以指示完成,状态和任何返回的值。您将看到CREATE_IN_PROGRESS作为CloudFormation中的状态,直到您通知它您的功能已完成。

信令CloudFormation的一般方式是发布对预先签名的S3 URL的响应。但是有一个cfn-response模块可以使Lambda函数更容易实现。有趣的是,为Lambda支持的自定义资源提供的两个示例使用不同的方法:

答案 1 :(得分:0)

是的,我做了同样的事情。我们需要上传(PUT请求)请求状态。(需要发送状态为SUCCESS)