AWS CloudFormation
ユーザーガイド (API バージョン 2010-05-15)

AWS Lambda 関数コード

CodeAWS::Lambda::Function リソースのプロパティで、Lambda 関数のコードを指定します。すべてのランタイムの場合、Amazon S3 内のデプロイパッケージの場所を指定できます。Node.js および Python 関数の場合は、テンプレートにインラインで関数コードを指定することもできます。

注記

Amazon S3 内のデプロイパッケージの変更は自動的には検出されません。関数コードを更新するには、オブジェクトキーを変更するか、オブジェクトのバージョニングを使用してテンプレートのバージョン番号を変更します。

構文

JSON

{ "S3Bucket" : String, "S3Key" : String, "S3ObjectVersion" : String, "ZipFile" : String }

YAML

S3Bucket: String S3Key: String S3ObjectVersion: String ZipFile: String

プロパティ

S3Bucket

関数と同じリージョンにある Amazon S3 バケット。バケットがある AWS アカウントは異なる場合があります。

注記

cfn-response モジュールは Amazon S3 バケットに保存されたソースコードには使用できません。応答を送信するには、独自の関数を作成します。

Required: Conditional.S3Bucket プロパティと S3Key プロパティの両方を指定するか、ZipFile プロパティを指定します。

Type: String

S3Key

デプロイパッケージの Amazon S3 キー。

Required: Conditional.S3Bucket プロパティと S3Key プロパティの両方を指定するか、ZipFile プロパティを指定する必要があります。

Type: String

S3ObjectVersion

バージョニングされたオブジェクトの場合、使用するデプロイパッケージオブジェクトのバージョン。

Required: No

Type: String

ZipFile

(Node.js および Python) Lambda 関数のソースコード。このパラメータに関数のソースをインラインで含めると、AWS CloudFormation では、これを index というファイルに配置して圧縮し、デプロイパッケージを作成します。Handler プロパティの場合、ハンドラー識別子の最初の部分は index にする必要があります。("index.handler" など)。

ソースコードには、最大 4,096 文字を含めることができます。JSON の場合は、引用符と、改行 (\n) などの特殊文字はバックスラッシュを使用してエスケープする必要があります。

AWS CloudFormation カスタムリソースと通信する関数を指定する場合、関数を呼び出したカスタムリソースに応答を送信するために独自の関数を作成する必要はありません。AWS CloudFormation に、応答の送信を簡素化する応答モジュールが用意されています。詳細については、「cfn-response モジュール」を参照してください。

Required: Conditional.S3Bucket プロパティと S3Key プロパティの両方を指定するか、ZipFile プロパティを指定する必要があります。

Type: String

cfn-response モジュール

ZipFile プロパティを使用して関数のソースコードを指定し、その関数が AWS CloudFormation カスタムリソースと通信する場合、cfn-response モジュールをロードしてこれらのリソースに応答を送信できます。このモジュールには send メソッドが含まれています。このメソッドは、Amazon S3 の署名付き URL (ResponseURL) を経由して、カスタムリソースに応答オブジェクトを送信します。

send メソッドを実行した後、Lambda 関数は終了するため、メソッドの後の記述は無視されます。

注記

cfn-response モジュールは、ZipFile プロパティを使用してソースコードを作成した場合にのみ使用できます。Amazon S3 バケットに保存されたソースコードには使用できません。バケットのコードでは、独自の関数を作成してレスポンスを送信する必要があります。

cfn-response モジュールの読み込み

Node.js 関数の場合は、require() 関数を使用して cfn-response モジュールをロードします。たとえば、次のコードでは、cfn-response という名前で response オブジェクトを作成しています。

var response = require('cfn-response');

Python の場合は、次の例に示すように、import ステートメントを使用して cfnresponse モジュールをロードします。

注記

この完全インポートステートメントを使用します。インポートステートメントの他の形式では、AWS CloudFormation では応答モジュールが含まれません。

import cfnresponse

send メソッドのパラメーター

send メソッドで次のパラメーターを使用できます。

event

カスタムリソースのリクエストに含まれるフィールド。

context

関数および任意のコールバックが実行完了したとき、または Lambda 実行環境内からの情報にアクセスするときに指定できる Lambda 関数固有のオブジェクト。詳細については、AWS Lambda Developer Guide の「プログラミングモデル (Node.js)」を参照してください。

responseStatus

関数が正常に完了したかどうか。このステータスを指定するには、cfnresponse モジュール定数を使用します。成功に実行した場合は SUCCESS、失敗した場合は FAILED を指定します。

responseData

カスタムリソースの応答オブジェクトData フィールド。データの内容は、名前と値のペアのリストです。

physicalResourceId

オプション。関数を呼び出したカスタムリソースの一意の識別子。モジュールのデフォルトでは、Lambda 関数に関連付けられている Amazon CloudWatch Logs ログストリームの名前が使用されます。

noEcho

オプション。Fn::GetAtt 関数を使用してカスタムリソースの出力を取得したときに、それをマスクするかどうかを示します。true に設定した場合、返されるすべての値はアスタリスク (*****) でマスクされます。デフォルトでは、この値は false です。

Node.js

次の Node.js の例では、インラインの Lambda 関数で入力値を受け取り、その値に 5 を乗算しています。インライン関数は、パッケージを作成して Amazon S3 バケットにアップロードするのではなく、ソースコードをテンプレート内で直接指定できるため、小さな関数の場合は特に便利です。この関数では、cfn-responsesend メソッドを使用して、呼び出たカスタムリソースに結果を返しています。

JSON
"ZipFile": { "Fn::Join": ["", [ "var response = require('cfn-response');", "exports.handler = function(event, context) {", " var input = parseInt(event.ResourceProperties.Input);", " var responseData = {Value: input * 5};", " response.send(event, context, response.SUCCESS, responseData);", "};" ]]}
YAML
ZipFile: > var response = require('cfn-response'); exports.handler = function(event, context) { var input = parseInt(event.ResourceProperties.Input); var responseData = {Value: input * 5}; response.send(event, context, response.SUCCESS, responseData); };

Python

次の Python の例では、インラインの Lambda 関数で整数値を受け取り、その値に 5 を乗算しています。

JSON
"ZipFile" : { "Fn::Join" : ["\n", [ "import json", "import cfnresponse", "def handler(event, context):", " responseValue = int(event['ResourceProperties']['Input']) * 5", " responseData = {}", " responseData['Data'] = responseValue", " cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, \"CustomResourcePhysicalID\")" ]]}
YAML
ZipFile: | import json import cfnresponse def handler(event, context): responseValue = int(event['ResourceProperties']['Input']) * 5 responseData = {} responseData['Data'] = responseValue cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")

モジュールのソースコード

Node.js 関数のレスポンスモジュールのソースコードは次のとおりです。これを確認してモジュールの動作を理解し、独自の応答関数の実装に役立ててください。

/* Copyright 2015 Amazon Web Services, Inc. or its affiliates. All Rights Reserved. This file is licensed to you under the AWS Customer Agreement (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/agreement/ . This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions and limitations under the License. */ exports.SUCCESS = "SUCCESS"; exports.FAILED = "FAILED"; exports.send = function(event, context, responseStatus, responseData, physicalResourceId, noEcho) { var responseBody = JSON.stringify({ Status: responseStatus, Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName, PhysicalResourceId: physicalResourceId || context.logStreamName, StackId: event.StackId, RequestId: event.RequestId, LogicalResourceId: event.LogicalResourceId, NoEcho: noEcho || false, Data: responseData }); console.log("Response body:\n", responseBody); var https = require("https"); var url = require("url"); var parsedUrl = url.parse(event.ResponseURL); 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(); }

Python 3 関数のレスポンスモジュールのソースコードは次のとおりです。

# Copyright 2016 Amazon Web Services, Inc. or its affiliates. All Rights Reserved. # This file is licensed to you under the AWS Customer Agreement (the "License"). # You may not use this file except in compliance with the License. # A copy of the License is located at http://aws.amazon.com/agreement/ . # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. # See the License for the specific language governing permissions and limitations under the License. from botocore.vendored import requests import json SUCCESS = "SUCCESS" FAILED = "FAILED" def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False): responseUrl = event['ResponseURL'] print(responseUrl) responseBody = {} responseBody['Status'] = responseStatus responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name responseBody['StackId'] = event['StackId'] responseBody['RequestId'] = event['RequestId'] responseBody['LogicalResourceId'] = event['LogicalResourceId'] responseBody['NoEcho'] = noEcho responseBody['Data'] = responseData json_responseBody = json.dumps(responseBody) print("Response body:\n" + json_responseBody) headers = { 'content-type' : '', 'content-length' : str(len(json_responseBody)) } try: response = requests.put(responseUrl, data=json_responseBody, headers=headers) print("Status code: " + response.reason) except Exception as e: print("send(..) failed executing requests.put(..): " + str(e))

Python 2 関数のレスポンスモジュールのソースコードは次のとおりです。

# Copyright 2016 Amazon Web Services, Inc. or its affiliates. All Rights Reserved. # This file is licensed to you under the AWS Customer Agreement (the "License"). # You may not use this file except in compliance with the License. # A copy of the License is located at http://aws.amazon.com/agreement/ . # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. # See the License for the specific language governing permissions and limitations under the License. from botocore.vendored import requests import json SUCCESS = "SUCCESS" FAILED = "FAILED" def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False): responseUrl = event['ResponseURL'] print responseUrl responseBody = {} responseBody['Status'] = responseStatus responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name responseBody['StackId'] = event['StackId'] responseBody['RequestId'] = event['RequestId'] responseBody['LogicalResourceId'] = event['LogicalResourceId'] responseBody['NoEcho'] = noEcho responseBody['Data'] = responseData json_responseBody = json.dumps(responseBody) print "Response body:\n" + json_responseBody headers = { 'content-type' : '', 'content-length' : str(len(json_responseBody)) } try: response = requests.put(responseUrl, data=json_responseBody, headers=headers) print "Status code: " + response.reason except Exception as e: print "send(..) failed executing requests.put(..): " + str(e)