2016-03-31 5 views
10

CloudFormationテンプレートを使用してS3バケットを作成しています。 S3バケットにファイルが追加されるたびに、ラムダ関数を関連付ける(S3バケットにイベントを追加する)ようにしたいと思います。クラウド情報を使用してS3バケットにラムダ機能を有効にする

CloudFormationテンプレートを使用するとどうなりますか? CloudFormationで使用する必要があるプロパティは何ですか?

+0

あなたが必要とする関連資料に? – helloV

答えて

5

CloudFormationテンプレートにNotificationConfigurationプロパティが必要です。残念ながら、すでにバケツが存在する必要があるようです。これを回避するには、最初のスタックを作成し、それをNotificationConfigurationで更新することができます。たとえば:

// template1.json 
{ 
    "AWSTemplateFormatVersion": "2010-09-09", 
    "Parameters": { 
    "mylambda": { 
     "Type": "String" 
    } 
    }, 
    "Resources": { 
    "bucketperm": { 
     "Type": "AWS::Lambda::Permission", 
     "Properties" : { 
     "Action": "lambda:InvokeFunction", 
     "FunctionName": {"Ref": "mylambda"}, 
     "Principal": "s3.amazonaws.com", 
     "SourceAccount": {"Ref": "AWS::AccountId"}, 
     "SourceArn": { "Fn::Join": [":", [ 
      "arn", "aws", "s3", "" , "", {"Ref" : "mybucket"}]] 
     } 
     } 
    }, 
    "mybucket": { 
     "Type": "AWS::S3::Bucket" 
    } 
    } 
} 

// template2.json -- adds the ConfigurationNotification 
{ 
    "AWSTemplateFormatVersion": "2010-09-09", 
    "Parameters": { 
    "mylambda": { 
     "Type": "String" 
    } 
    }, 
    "Resources": { 
    "bucketperm": { 
     "Type": "AWS::Lambda::Permission", 
     "Properties" : { 
     "Action": "lambda:InvokeFunction", 
     "FunctionName": {"Ref": "mylambda"}, 
     "Principal": "s3.amazonaws.com", 
     "SourceAccount": {"Ref": "AWS::AccountId"}, 
     "SourceArn": { "Fn::Join": [":", [ 
      "arn", "aws", "s3", "" , "", {"Ref" : "mybucket"}]] 
     } 
     } 
    }, 
    "mybucket": { 
     "Type": "AWS::S3::Bucket", 
     "Properties": { 
     "NotificationConfiguration": { 
      "LambdaConfigurations": [ 
      { 
       "Event" : "s3:ObjectCreated:*", 
       "Function" : {"Ref": "mylambda"} 
      } 
      ] 
     } 
     } 
    } 
    } 
} 

次のようなスタックを作成するために、AWS CLIツールを使用することができます。

$ aws cloudformation create-stack --stack-name mystack --template-body file://template1.json --parameters ParameterKey=mylambda,ParameterValue=<lambda arn> 
# wait until stack is created 
$ aws cloudformation update-stack --stack-name mystack --template-body file://template2.json --parameters ParameterKey=mylambda,ParameterValue=<lambda arn> 
+0

CFTのresourcesセクションにラムダのコードを書く必要がありますか?あなたがmylambdaを参照しているように? – shiv455

+0

問題は、新しいファイルがバケットに追加されたときではなく、バケットが作成されたときにラムダをトリガする方法です。 – helloV

+0

ラムダを同じテンプレートで定義する必要はありません。バケットの設定では、ラムダARNが必要です。ラムダが別の場所に設定されている場合は、ARNをテンプレートパラメータとして渡します。 – ataylor

1

を私はS3バケットを作成するために使用されcloudformationでnotificationconfigurationと一緒にバケツパーマの下に追加されました。 。出来た !!

"bucketperm": { 
      "Type": "AWS::Lambda::Permission", 
      "Properties": { 
       "Action": "lambda:invokeFunction", 
       "FunctionName": "<arnvalue>", 
       "Principal": "s3.amazonaws.com" 
      } 
} 
12

ここでファイルがS3バケットに追加されるたびにラムダ関数をトリガする方法を示し、完全な、自己完結型のCloudFormationテンプレートです:

Launch Stack

Description: Upload an object to an S3 bucket, triggering a Lambda event, returning the object key as a Stack Output. 
Parameters: 
    Key: 
    Description: S3 Object key 
    Type: String 
    Default: test 
    Body: 
    Description: S3 Object body content 
    Type: String 
    Default: TEST CONTENT 
    BucketName: 
    Description: S3 Bucket name 
    Type: String 
Resources: 
    Bucket: 
    Type: AWS::S3::Bucket 
    DependsOn: BucketPermission 
    Properties: 
     BucketName: !Ref BucketName 
     NotificationConfiguration: 
     LambdaConfigurations: 
     - Event: 's3:ObjectCreated:*' 
      Function: !GetAtt BucketWatcher.Arn 
    BucketPermission: 
    Type: AWS::Lambda::Permission 
    Properties: 
     Action: 'lambda:InvokeFunction' 
     FunctionName: !Ref BucketWatcher 
     Principal: s3.amazonaws.com 
     SourceAccount: !Ref "AWS::AccountId" 
     SourceArn: !Sub "arn:aws:s3:::${BucketName}" 
    BucketWatcher: 
    Type: AWS::Lambda::Function 
    Properties: 
     Description: Sends a Wait Condition signal to Handle when invoked 
     Handler: index.handler 
     Role: !GetAtt LambdaExecutionRole.Arn 
     Code: 
     ZipFile: !Sub | 
      exports.handler = function(event, context) { 
      console.log("Request received:\n", JSON.stringify(event)); 
      var responseBody = JSON.stringify({ 
       "Status" : "SUCCESS", 
       "UniqueId" : "Key", 
       "Data" : event.Records[0].s3.object.key, 
       "Reason" : "" 
      }); 
      var https = require("https"); 
      var url = require("url"); 
      var parsedUrl = url.parse('${Handle}'); 
      var options = { 
       hostname: parsedUrl.hostname, 
       port: 443, 
       path: parsedUrl.path, 
       method: "PUT", 
       headers: { 
        "content-type": "", 
        "content-length": responseBody.length 
       } 
      }; 
      var request = https.request(options, function(response) { 
       console.log("Status code: " + response.statusCode); 
       console.log("Status message: " + response.statusMessage); 
       context.done(); 
      }); 
      request.on("error", function(error) { 
       console.log("send(..) failed executing https.request(..): " + error); 
       context.done(); 
      }); 
      request.write(responseBody); 
      request.end(); 
      }; 
     Timeout: 30 
     Runtime: nodejs4.3 
    Handle: 
    Type: AWS::CloudFormation::WaitConditionHandle 
    Wait: 
    Type: AWS::CloudFormation::WaitCondition 
    Properties: 
     Handle: !Ref Handle 
     Timeout: 300 
    S3Object: 
    Type: Custom::S3Object 
    Properties: 
     ServiceToken: !GetAtt S3ObjectFunction.Arn 
     Bucket: !Ref Bucket 
     Key: !Ref Key 
     Body: !Ref Body 
    S3ObjectFunction: 
    Type: AWS::Lambda::Function 
    Properties: 
     Description: S3 Object Custom Resource 
     Handler: index.handler 
     Role: !GetAtt LambdaExecutionRole.Arn 
     Code: 
     ZipFile: !Sub | 
      var response = require('cfn-response'); 
      var AWS = require('aws-sdk'); 
      var s3 = new AWS.S3(); 
      exports.handler = function(event, context) { 
      console.log("Request received:\n", JSON.stringify(event)); 
      var responseData = {}; 
      if (event.RequestType == 'Create') { 
       var params = { 
       Bucket: event.ResourceProperties.Bucket, 
       Key: event.ResourceProperties.Key, 
       Body: event.ResourceProperties.Body 
       }; 
       s3.putObject(params).promise().then(function(data) { 
       response.send(event, context, response.SUCCESS, responseData); 
       }).catch(function(err) { 
       console.log(JSON.stringify(err)); 
       response.send(event, context, response.FAILED, responseData); 
       }); 
      } else if (event.RequestType == 'Delete') { 
       var deleteParams = { 
       Bucket: event.ResourceProperties.Bucket, 
       Key: event.ResourceProperties.Key 
       }; 
       s3.deleteObject(deleteParams).promise().then(function(data) { 
       response.send(event, context, response.SUCCESS, responseData); 
       }).catch(function(err) { 
       console.log(JSON.stringify(err)); 
       response.send(event, context, response.FAILED, responseData); 
       }); 
      } else { 
       response.send(event, context, response.SUCCESS, responseData); 
      } 
      }; 
     Timeout: 30 
     Runtime: nodejs4.3 
    LambdaExecutionRole: 
    Type: AWS::IAM::Role 
    Properties: 
     AssumeRolePolicyDocument: 
     Version: '2012-10-17' 
     Statement: 
     - Effect: Allow 
      Principal: {Service: [lambda.amazonaws.com]} 
      Action: ['sts:AssumeRole'] 
     Path:/
     ManagedPolicyArns: 
     - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 
     Policies: 
     - PolicyName: S3Policy 
     PolicyDocument: 
      Version: '2012-10-17' 
      Statement: 
      - Effect: Allow 
       Action: 
       - 's3:PutObject' 
       - 'S3:DeleteObject' 
       Resource: !Sub "arn:aws:s3:::${BucketName}/${Key}" 
Outputs: 
    Result: 
    Value: !GetAtt Wait.Data 
+0

実例をありがとうございました。それは多くの時間を節約!しかし、そのテンプレートに 'S3Object'がある理由を教えてください。私はそれがどこにでも言及されていることはわかりませんか? – Cherry

+0

@Cherry 'S3Object'と' S3ObjectFunction'はS3バケットにオブジェクトを自動的に生成し、テストのためにラムダ関数をトリガします。通常、これは手動でアップロードするオブジェクトによってトリガーされるため、独自の実装では必要ありません。 – wjordan

0

はい、それが可能ですあなたが構成する必要があるものは次のとおりです。

1)AWS::S3::Bucketリソースと

0上記のs3リソースに対しては、

2)NotificationConfigurationの設定(この場合はLambdaConfigurationsを使用してください)。あなたはバケットが作成されたとき、またはオブジェクト(のputObjectは)バケットで作成したときにラムダがトリガーたい

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html#cfn-s3-bucket-notification

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-notificationconfig.html

関連する問題