2016-08-01 37 views
4

访问参数我有一个CloudFormation模板,看起来像这样:CloudFormation - 从LAMBDA代码

{ 
    "AWSTemplateFormatVersion": "2010-09-09", 
    "Description": "This template will deploy stuff", 
    "Parameters":{ 
    "myParamToLambdaFunction" : { 
     "Description" : "Please enter the the value", 
     "Type" : "String", 
     "ConstraintDescription" : "must have some value." 
    } 
}, 
"Resources": { 
    "SecGrpValidatorFromCFTemplate": { 
     "Type": "AWS::Lambda::Function", 
     "Properties": { 
      "FunctionName": "mylambdafunctionname", 
      "Handler": "myfile.lambda_handler", 
      "Role": { 
       "Fn::GetAtt": ["somerole", "Arn"] 
      }, 
      "Timeout": "30", 
      "Runtime": "python2.7", 
      "Code": { 
       "S3Bucket":"mybucket", 
       "S3Key":"mylambdafunction.zip" 
      } 
     } 
    } 
} 

我需要的myParamToLambdaFunction值传递给lambda函数。

有没有办法做到这一点?

回答

0

一旦您像在模板中那样创建lambda函数,就可以定义一个Lambda支持的自定义资源以使用自定义参数调用该函数,并且还可以处理来自lambda的响应。有关更多信息和示例,请参阅https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html

+0

不是我真正想要的。我需要将CloudFormation的输入参数的值注入到Lambda中的一个变量中。我已将这个问题发布到AWS论坛以及更多详细信息:[链接到AWS论坛上的问题](https://forums.aws.amazon.com/thread.jspa?threadID=236582&tstart=0) – Asdfg

+0

您可以在node.js中执行它,因为你可以在CF中直接提供lambda代码,但是在python中我不认为有办法做到这一点。 –

0

如果您的lambda不是太复杂,您可以将它内联到您的模板中,而不是依赖上传的zip文件。

这里有一个,我没有使用的输入参数:

"CopyLogsStreamToFirehose": { 
    "Type": "AWS::Lambda::Function", 
    "Properties": { 
    "Code": { 
     "ZipFile": { 
     "Fn::Join": [ 
      "", 
      [ 
      "import base64\n", 
      "import boto3\n", 
      "def on_new_kinesis_data(event, context):\n", 
      " client = boto3.client('firehose')\n", 
      " records = [ {'Data': base64.b64decode(r['kinesis']['data']) + '\\n' } for r in event['Records']]\n", 
      " client.put_record_batch(DeliveryStreamName='", 
      { 
       "Ref": "LogsDeliveryStream" 
      }, 
      "', Records=records)\n", 
      " print 'Successfully processed {} records.'.format(len(event['Records']))\n" 
      ] 
     ] 
     } 
    }, 
    "Description": "Kinesis Stream to Firehose Stream", 
    "Handler": "index.on_new_kinesis_data", 
    "Role": { 
     "Fn::GetAtt": [ 
     "CopyLogsStreamToFirehoseRole", 
     "Arn" 
     ] 
    }, 
    "Runtime": "python2.7", 
    "Timeout": 5 
    } 
+2

我的lambda函数超过了4096个字符,这是内联函数的一个限制,我在lambda函数中使用了多个库。 – Asdfg

+1

如果您的lambda与某些其他资源相关(例如:EC2实例),则可以将该参数设置为CloudFormation中的EC2标签,然后使用lambda检索它。我之前做过一次:我从AutoScaling组读取标签,然后使用此信息更新route53中的记录。 –

0

这是拉姆达需要的环境变量。这对我的工作来说是一个巨大的问题。我尝试了两种方法。

1 - 您的lambda函数名称将包含您的堆栈名称。使用一些分割,提取该值,例如var stackName = context.functionName.split('-')[0];,然后调用describeStacks来检索您的堆栈。从那里的输出/参数中提取所需的数据。这工作正常,但请注意,查询CloudFormation堆栈的限制相当有限。如果您的lambda快速启动,选项2将更适合您。

2 - 使用堆栈名称作为密钥(根据您的延迟要求,S3中的文件也可以工作)将您的端点手动输出到DynamoDB表中并查询您的环境数据。如果您真的想要使用自定义的cloudformation资源来自动执行此堆栈数据输出。

0

无论调用您的lambda函数,都可以在元数据调用时将元数据传递给lambda函数。

例如,使用自动缩放组,可能您希望在实例启动或终止时调用lambda函数。在这种情况下,AWS::AutoScaling::LifecycleHook资源包括NotificationMetadata其中包含了字典,一个项目,Route53ZoneId

"MyLifecycleHook": { 
    "Type": "AWS::AutoScaling::LifecycleHook", 
    "Properties": { 
    "AutoScalingGroupName": { "Ref": "MyASG" }, 
    "LifecycleTransition": "autoscaling:EC2_INSTANCE_LAUNCHING", 
    "NotificationMetadata": { "Fn::Join": [ "", [ 
     "{", 
     " \"Route53ZoneId\": \"YOUR_ROUTE53_ZONE_IDENTIFIER_HERE\"", 
     "}" 
    ] ] }, 
    "NotificationTargetARN": { "Ref": "MyTopic" }, 
    "RoleARN": { "Fn::GetAtt": [ "MyLifecycleHookRole", "Arn" ] } 
    } 
} 

然后在你的拉姆达处理程序,假设你用Python写它,你可以在词典中的变量,例如:

def handler(event, context): 
    message = json.loads(event[u'Records'][0][u'Sns'][u'Message']) 
    metadata = json.loads(message['NotificationMetadata']) 

    logger.info("Route53 Zone Identifier {0}".format(metadata['Route53ZoneId'])) 
+1

这听起来很酷。 – Asdfg

+0

是的,我们在生产中使用它,它运作良好。请注意,您需要上述示例中的SNS主题,因为自动缩放生命周期钩子不能直接调用lambda,只能发布到SNS,而SNS会调用lambda。 –

+0

我的lambda将由Cloudwatch事件调用。我希望他们支持NotificationMetadata。 – Asdfg

0

如果你的lambda函数的背后是API网关,您可以使用RequestTemplates到达函数之前修改请求。下面的配置将发送的原始请求体定义为YourCloudformationParameter参数沿着:

"RequestTemplates": { 
    "application/json": { 
    "Fn::Join": [ 
     "", 
     [ 
     "{", 
      "\"body\": $input.json('$'),", 
      "\"env\": {", 
      "\"yourCloudformationParameter\": \"", { "Ref": "YourCloudformationParameter" }, "\"", 
      "}", 
     "}" 
     ] 
    ] 
    } 
}, 
2

作为18 Nov 2016,AWS LAMBDA现在支持environment variables,其CloudFormation通过对AWS::Lambda::Function资源的Environment属性支持。

一个Environment属性添加到您的资源是这样的:

{ 
    "AWSTemplateFormatVersion": "2010-09-09", 
    "Description": "This template will deploy stuff", 
    "Parameters":{ 
    "myParamToLambdaFunction" : { 
     "Description" : "Please enter the the value", 
     "Type" : "String", 
     "ConstraintDescription" : "must have some value." 
    } 
}, 
"Resources": { 
    "SecGrpValidatorFromCFTemplate": { 
     "Type": "AWS::Lambda::Function", 
     "Properties": { 
      "FunctionName": "mylambdafunctionname", 
      "Handler": "myfile.lambda_handler", 
      "Role": { 
       "Fn::GetAtt": ["somerole", "Arn"] 
      }, 
      "Timeout": "30", 
      "Runtime": "python2.7", 
      "Code": { 
       "S3Bucket":"mybucket", 
       "S3Key":"mylambdafunction.zip" 
      }, 
      "Environment": { 
       "Variables": { 
        "myParam": { 
         "Ref": "myParamToLambdaFunction" 
        } 
       } 
      } 
     } 
    } 
} 

然后根据你的运行平台(例如,os.environ['myParam']在Python)从部署的lambda函数引用环境变量。