cfn-response 모듈 - AWS CloudFormation

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 개발자 안내서프로그래밍 모델(Node.js)을 참조하세요.

responseStatus

함수가 성공적으로 완료되었는지 여부를 나타냅니다. cfnresponse 모듈 제약을 사용하여 실행 성공에 대해 SUCCESS를 지정하고 실행 실패에 대해 FAILED를 지정합니다.

responseData

사용자 지정 응답 객체Data 필드입니다. 데이터는 이름-값 페어 목록입니다.

physicalResourceId

선택 사항입니다. 함수를 호출한 사용자 지정 리소스의 고유 식별자입니다. 기본적으로 이 모듈은 Lambda 함수와 연결된 Amazon CloudWatch Logs 로그 스트림의 이름을 사용합니다.

PhysicalResourceId에 대해 반환된 값은 사용자 지정 리소스 업데이트 작업을 변경할 수 있습니다. 반환된 값이 같은 경우 일반 업데이트로 간주됩니다. 반환된 값이 다른 경우 AWS CloudFormation은 업데이트를 교체로 인식하고 기존 리소스에 삭제 요청을 전송합니다. 자세한 내용은 AWS::CloudFormation::CustomResource 단원을 참조하십시오.

noEcho

선택 사항입니다. Fn::GetAtt 함수를 사용하여 조회할 때 사용자 지정 리소스의 출력을 마스킹할지 여부를 나타냅니다. true로 설정하면 아래 지정된 위치에 저장된 정보를 제외하고, 반환된 모든 값은 별표(*****)로 마스킹됩니다. 기본적으로 이 값은 false입니다.

중요

NoEcho 속성을 사용해도 다음에 저장된 정보는 마스킹되지 않습니다.

  • Metadata 템플릿 섹션. CloudFormation은 Metadata 섹션에 포함된 정보를 변환, 수정 또는 삭제하지 않습니다. 자세한 내용은 Metadata 단원을 참조하십시오.

  • Outputs 템플릿 섹션. 자세한 내용은 결과 단원을 참조하십시오.

  • 리소스 정의의 Metadata 속성입니다. 자세한 내용은 Metadata 속성 단원을 참조하십시오.

이러한 메커니즘을 사용하여 암호나 보안 정보와 같은 중요한 정보를 포함하지 않는 것이 좋습니다.

NoEcho를 사용하여 민감한 정보를 마스킹 처리하는 방법에 대한 자세한 내용은 템플릿에 자격 증명을 포함하지 않음 모범 사례를 참조하세요.

Node.js

다음 Node.js 예제에서 인라인 Lambda 함수는 입력 값을 받아서 그 값에 5를 곱합니다. 인라인 함수를 사용하면 패키지를 생성하여 Amazon S3 버킷에 업로드하는 대신에 템플릿에서 소스 코드를 직접 지정할 수 있으므로 인라인 함수는 작은 함수에 특히 유용합니다. 이 함수는 cfn-response send 메서드를 사용하여 호출했던 사용자 지정 리소스로 결과를 다시 전송합니다.

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 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 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: " + parseInt(response.statusCode)); context.done(); }); request.on("error", function(error) { console.log("send(..) failed executing https.request(..): " + error); context.done(); }); request.write(responseBody); request.end(); }

다음은 Python 2와 3 함수에 대한 응답 모듈 소스 코드입니다.

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 from __future__ import print_function import urllib3 import json SUCCESS = "SUCCESS" FAILED = "FAILED" http = urllib3.PoolManager() def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False, reason=None): responseUrl = event['ResponseURL'] print(responseUrl) responseBody = { 'Status' : responseStatus, 'Reason' : reason or "See the details in CloudWatch Log Stream: {}".format(context.log_stream_name), 'PhysicalResourceId' : physicalResourceId or context.log_stream_name, 'StackId' : event['StackId'], 'RequestId' : event['RequestId'], 'LogicalResourceId' : event['LogicalResourceId'], 'NoEcho' : noEcho, 'Data' : responseData } json_responseBody = json.dumps(responseBody) print("Response body:") print(json_responseBody) headers = { 'content-type' : '', 'content-length' : str(len(json_responseBody)) } try: response = http.request('PUT', responseUrl, headers=headers, body=json_responseBody) print("Status code:", response.status) except Exception as e: print("send(..) failed executing http.request(..):", e)