2016-08-01 59 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函數引用環境變量。