2016-08-03 9 views
7

के साथ एक एस 3 बाल्टी में एक लैम्ब्डा अधिसूचना बनाएं, मैं क्लाउडफॉर्मेशन टेम्पलेट में लैम्ब्डा फ़ंक्शन के लिए एक S3 ट्रिगर बनाने की कोशिश कर रहा हूं। एस 3 बाल्टी पहले से मौजूद है, और लैम्ब्डा समारोह बनाया जा रहा है।क्लाउडफॉर्मेशन

This कहना है कि वह एक सीएफटी के साथ पहले से मौजूदा बुनियादी ढांचे को संशोधित करने (S3 इस मामले में) संभव नहीं है, लेकिन this बाल्टी जा पूर्व मौजूदा नहीं है कहने के लिए लगता है।

  1. ऐसा लगता है कि ट्रिगर एक सीएफटी प्रकार का उपयोग नहीं बनाया जा सकता "एडब्ल्यूएस :: लैम्ब्डा ..." और स्रोत सेवा ट्रिगर बनाने के लिए जरूरत है। मेरे मामले में, यह एक एस 3 बाल्टी के लिए एक अधिसूचना कॉन्फ़िगरेशन-लैम्ब्डा कॉन्फ़िगरेशन है। क्या यह सब सही है?

  2. जब मैं एक सीएफटी के साथ मौजूदा एस 3 बाल्टी में अधिसूचना कॉन्फ़िगरेशन जोड़ने की कोशिश करता हूं, तो यह कहता है कि मैं नहीं कर सकता। क्या इसे करने का कोई तरीका है?

+0

मैं काफी हद तक निश्चित है कि जब बाल्टी का अस्तित्व है, यह टेम्पलेट के सृजन से पहले अस्तित्व में नहीं है हूँ। अधिसूचना कॉन्फ़िगरेशन के साथ बाल्टी बनाना और उसी टेम्पलेट में लैम्ब्डा फ़ंक्शन आपके उपयोग के मामले में फिट होगा? यदि ऐसा है, तो मौजूदा पद्धति को संशोधित करने से आपकी सहायता करने के लिए यह विधि बहुत आसान होगी। किसी भी तरह से कोई समाधान है, लेकिन एक बहुत सुंदर है –

+0

जब आप कहते हैं कि 'एस 3 बाल्टी पहले से मौजूद है', तो क्या आप यह भी कह रहे हैं कि बाल्टी क्लाउडफॉर्मेशन के बाहर बनाई गई थी? – Aditya

उत्तर

4

दुर्भाग्य से, सरकारी AWS::CloudFormation टेम्पलेट केवल आप माता-पिता AWS::S3::Bucket संसाधन, जिसका अर्थ है कि आप किसी भी मौजूदा बाल्टी को यह विन्यास अनुलग्न नहीं कर सकते की एक NotificationConfiguration property रूप Amazon S3 NotificationConfiguration नियंत्रित करने देता है, तो आप एक के लिए इसे लागू करने के लिए है काम करने के लिए क्लाउडफॉर्मेशन-प्रबंधित बाल्टी।

जावास्क्रिप्ट एपीआई कॉल का उपयोग कर Lambda-backed Custom Resource के रूप में सीधे Lambda-backed Custom Resource के रूप में कॉल करने के लिए एक वर्कअराउंड है। हालांकि, क्योंकि एस 3 बाल्टी पर अधिसूचना कॉन्फ़िगरेशन को संशोधित करना बाल्टी के निर्माता तक ही सीमित है, आपको AWS::S3::BucketPolicy संसाधन को s3:PutBucketNotification क्रिया में अपना लैम्ब्डा फ़ंक्शन पहुंच प्रदान करने की आवश्यकता भी है।

यहाँ यह दर्शाता है कि कैसे एक लैम्ब्डा समारोह जब भी एक फ़ाइल एक मौजूदा S3 बाल्टी में जोड़ा जाता है को गति प्रदान करने बाल्टी अधिसूचना विन्यास स्थापित करने के लिए का उपयोग कर 2 लैम्डा-बैक्ड कस्टम संसाधन (BucketConfiguration, एक पूर्ण, संयमी CloudFormation टेम्पलेट है, S3Object बाल्टी पर ऑब्जेक्ट अपलोड करने के लिए) और बाल्टी पर ऑब्जेक्ट अपलोड होने पर प्रतीक्षा स्थिति को ट्रिगर करने के लिए एक तीसरा लैम्ब्डा फ़ंक्शन (BucketWatcher)।

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 (must already exist) 
    Type: String 
Resources: 
    BucketConfiguration: 
    Type: Custom::S3BucketConfiguration 
    DependsOn: 
    - BucketPermission 
    - NotificationBucketPolicy 
    Properties: 
     ServiceToken: !GetAtt S3BucketConfiguration.Arn 
     Bucket: !Ref BucketName 
     NotificationConfiguration: 
     LambdaFunctionConfigurations: 
     - Events: ['s3:ObjectCreated:*'] 
      LambdaFunctionArn: !GetAtt BucketWatcher.Arn 
    S3BucketConfiguration: 
    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) { 
      var respond = (e) => response.send(event, context, e ? response.FAILED : response.SUCCESS, e ? e : {}); 
      process.on('uncaughtException', e=>failed(e)); 
      var params = event.ResourceProperties; 
      delete params.ServiceToken; 
      if (event.RequestType === 'Delete') { 
       params.NotificationConfiguration = {}; 
       s3.putBucketNotificationConfiguration(params).promise() 
       .then((data)=>respond()) 
       .catch((e)=>respond()); 
      } else { 
       s3.putBucketNotificationConfiguration(params).promise() 
       .then((data)=>respond()) 
       .catch((e)=>respond(e)); 
      } 
      }; 
     Timeout: 30 
     Runtime: nodejs4.3 
    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 
    DependsOn: BucketConfiguration 
    Properties: 
     ServiceToken: !GetAtt S3ObjectFunction.Arn 
     Bucket: !Ref BucketName 
     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) { 
      var respond = (e) => response.send(event, context, e ? response.FAILED : response.SUCCESS, e ? e : {}); 
      var params = event.ResourceProperties; 
      delete params.ServiceToken; 
      if (event.RequestType == 'Create' || event.RequestType == 'Update') { 
       s3.putObject(params).promise() 
       .then((data)=>respond()) 
       .catch((e)=>respond(e)); 
      } else if (event.RequestType == 'Delete') { 
       delete params.Body; 
       s3.deleteObject(params).promise() 
       .then((data)=>respond()) 
       .catch((e)=>respond(e)); 
      } else { 
       respond({Error: 'Invalid request type'}); 
      } 
      }; 
     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}" 
    NotificationBucketPolicy: 
    Type: AWS::S3::BucketPolicy 
    Properties: 
     Bucket: !Ref BucketName 
     PolicyDocument: 
     Statement: 
      - Effect: "Allow" 
      Action: 
      - 's3:PutBucketNotification' 
      Resource: !Sub "arn:aws:s3:::${BucketName}" 
      Principal: 
       AWS: !GetAtt LambdaExecutionRole.Arn 
Outputs: 
    Result: 
    Value: !GetAtt Wait.Data 
संबंधित मुद्दे