使用Cloudformation来部署Lamba,包括函数将有权访问的参数

我们有一个API用于使用Cloud Formation在AWS中提供某些资源。 这包括一个将事件发送到S3的Lambda函数,并且可以configuration该存储桶。 事情是,当我们提供lambda时,我们会知道bucket名称,而不是lambda代码本身。

据我所知,在configuration时无法在Cloud Formation模板本身中注入S3存储桶名称。 真的吗?

我可以看到的唯一解决scheme是即时生成function代码,并将其embedded到Cloud Formation模板中。 这将使我们无法使用任何NPM依赖关系以及function代码。 有更好的select吗?

所以,我意识到我从来没有用我的最终解决scheme更新这个问题。 我最终将一个代理lambda函数embedded到cloudformation模板中,这使我能够注入模板参数。

例:

 { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Creates a function to relay messages from a Kinesis instance to S3", "Parameters": { "S3Bucket" : { "Type": "String", "Description": "The name of the S3 bucket where the data will be stored" }, "S3Key": { "Type": "String", "Description": "The key of the directory where the data will be stored" } }, "Resources": { "mainLambda": { "Type" : "AWS::Lambda::Function", "Properties" : { "Handler" : "index.handler", "Description" : "Writes events to S3", "Role" : { "Ref": "LambdaRoleARN" }, "Runtime" : "nodejs4.3", "Code" : { "S3Bucket": "streams-resources", "S3Key": "astro-bass/${GIT_COMMIT}/lambda/astro-bass.zip" } } }, "lambdaProxy": { "Type" : "AWS::Lambda::Function", "Properties" : { "Handler" : "index.handler", "Runtime" : "nodejs", "Code" : { "ZipFile": { "Fn::Join": ["", [ "var AWS = require('aws-sdk');", "var lambda = new AWS.Lambda();", "exports.handler = function(event, context) {", "event.bundledParams = ['", { "Ref": "S3Bucket" }, "','", { "Ref": "S3Key" }, "'];", "lambda.invoke({", "FunctionName: '", { "Ref": "mainLambda" }, "',", "Payload: JSON.stringify(event, null, 2),", "InvocationType: 'Event'", "}, function(err, data) {", "if(err) {", "context.fail(err);", "}", "context.done();", "});", "};" ]]} } } }, }, ... } 

代理函数将参数注入其代码(s3bucket / key),然后使用修改的事件对象调用主lambda。 这有点不正规,但比其他可用的解决scheme更加清洁,比如parsing堆栈名/ etc。 工作到目前为止。

请注意,此解决scheme仅适用于传统节点环境。 这不是一个问题,但在这个解决scheme的寿命方面令人担忧。

更新:我们遇到了以前的解决scheme的局限性,不得不另辟蹊径。 我们结束了描述字段的标签外使用以embeddedconfiguration值。 这是我们的Lambda

 'use strict'; var aws = require('aws-sdk'); var lambda = new aws.Lambda({apiVersion: '2014-11-11'}); let promise = lambda.getFunctionConfiguration({ FunctionName: process.env['AWS_LAMBDA_FUNCTION_NAME'] }).promise(); exports.handler = async function getTheConfig(event, context, cb) { try { let data = await promise; cb(null, JSON.parse(data.Description).bucket); } catch(e) { cb(e); } }; 

然后,在描述字段中,可以像下面这样embedded一个简单的JSON:

 { "bucket": "bucket-name" } 

而且,这个结构使用处理程序外部的承诺,将请求限制为仅在容器产生时发生 – 而不是针对每个lambda执行。

不是最干净的解决scheme,而是我们发现的最实用的解决scheme。

目前没有办法将parameter passing给事件旁边的Lambda函数。

如果使用CloudFormation创buildLambda函数,则可以使用以下解决方法:

  • 使用Lambda函数名称来派生CloudFormation堆栈名称。
  • 执行Lambda函数时,使用CloudFormation堆栈名称访问资源或堆栈的参数。