自定义资源 CloudFormation 以标记事件规则
Custom Resource CloudFormation to tag Event Rules
我正在尝试在 CloudFormation 中创建自定义资源来标记事件规则。
这是 lambda:
from json import dumps
import sys
import traceback
import urllib.request
import boto3
def send_response(event, context, response):
"""Send a response to CloudFormation to handle the custom resource lifecycle"""
response_body = {
'Status': response,
'StackId': event['StackId'],
'RequestId': event['RequestId'],
'LogicalResourceId': event['LogicalResourceId'],
}
print('RESPONSE BODY: \n' + dumps(response_body))
data = dumps(response_body).encode('utf-8')
req = urllib.request.Request(
event['ResponseURL'],
data,
headers={'Content-Length': len(data), 'Content-Type': ''})
req.get_method = lambda: 'PUT'
try:
with urllib.request.urlopen(req) as resp:
print(f'response.status: {resp.status}, ' +
f'response.reason: {resp.reason}')
print('response from cfn: ' + resp.read().decode('utf-8'))
except Exception as e:
print(e)
raise Exception('Received non-200 response while sending response to AWS CloudFormation')
return True
def custom_resource_handler(event, context):
print("Event JSON: \n" + dumps(event))
ResourceARN = event['ResourceProperties']['ResourceARN']
tags = event['ResourceProperties']['Tags']
response = 'FAILED'
client = boto3.client('events')
if event['RequestType'] == 'Create':
try:
response = client.tag_resource(
ResourceARN=ResourceARN,
Tags=tags)
response = 'SUCCESS'
except Exception as e:
print(e)
send_response(event, context, response)
return
if event['RequestType'] == 'Update':
# Do nothing and send a success immediately
send_response(event, context, response)
return
if event['RequestType'] == 'Delete':
try:
response = client.untag_resource(
ResourceARN = ResourceARN,
TagKeys = tags['Key']
)
response = 'SUCCESS'
except Exception as e:
print(e)
send_response(event, context, response)
def lambda_handler(event, context):
"""Lambda handler for the custom resource"""
try:
return custom_resource_handler(event, context)
except Exception as e:
print(e)
raise
这是 CFN 块:
CustomTagEvent:
Type: Custom::TagEventRule
Version: "1.0"
DependsOn: EventRule
Properties:
ServiceToken: "LAMBDA_ARN"
ResourceARN:
Fn::GetAtt:
- "EventRule"
- "Arn"
Tags:
-
Key: Name
创建 CLoudFormation 时出现错误“CREATE FAILED”。
“无效的 PhysicalResourceId”
但是,不知何故设法创建了标签。
需要帮助来理解为什么它在创建标签时会出现 CloudFormation 错误?
自定义资源需要 specific output 其中包含 PhysicalResourceId
:
{
"Status" : "SUCCESS",
"PhysicalResourceId" : "TestResource1",
"StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/stack-name/guid",
"RequestId" : "unique id for this create request",
"LogicalResourceId" : "MyTestResource",
"Data" : {
"OutputName1" : "Value1",
"OutputName2" : "Value2",
}
}
您的 lambda 函数不会生成这样的响应,因此会出错。
创建自定义资源的最佳方法是使用 AWS 专门为此目的提供的 cfn-response。
这解决了标记问题:
Code:
ZipFile: |
import boto3
import botocore
from botocore.exceptions import ClientError
import cfnresponse
import json
client = boto3.client("events")
def handler(event, context):
ResourceARN = event['ResourceProperties']['ResourceARN']
tags = event['ResourceProperties']['Tags']
if event['RequestType'] == 'Create':
response = client.tag_resource(
ResourceARN = ResourceARN,
Tags = tags
)
response = 'SUCCESS'
responseData = {}
responseData['Data'] = response
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
if event['RequestType'] == 'Update':
response = 'SUCCESS'
responseData = {}
responseData['Data'] = response
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
if event['RequestType'] == 'Delete':
for i in tags:
response = client.untag_resource(
ResourceARN = ResourceARN,
TagKeys = [i['Key']]
)
response = 'SUCCESS'
responseData = {}
responseData['Data'] = response
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
我正在尝试在 CloudFormation 中创建自定义资源来标记事件规则。 这是 lambda:
from json import dumps
import sys
import traceback
import urllib.request
import boto3
def send_response(event, context, response):
"""Send a response to CloudFormation to handle the custom resource lifecycle"""
response_body = {
'Status': response,
'StackId': event['StackId'],
'RequestId': event['RequestId'],
'LogicalResourceId': event['LogicalResourceId'],
}
print('RESPONSE BODY: \n' + dumps(response_body))
data = dumps(response_body).encode('utf-8')
req = urllib.request.Request(
event['ResponseURL'],
data,
headers={'Content-Length': len(data), 'Content-Type': ''})
req.get_method = lambda: 'PUT'
try:
with urllib.request.urlopen(req) as resp:
print(f'response.status: {resp.status}, ' +
f'response.reason: {resp.reason}')
print('response from cfn: ' + resp.read().decode('utf-8'))
except Exception as e:
print(e)
raise Exception('Received non-200 response while sending response to AWS CloudFormation')
return True
def custom_resource_handler(event, context):
print("Event JSON: \n" + dumps(event))
ResourceARN = event['ResourceProperties']['ResourceARN']
tags = event['ResourceProperties']['Tags']
response = 'FAILED'
client = boto3.client('events')
if event['RequestType'] == 'Create':
try:
response = client.tag_resource(
ResourceARN=ResourceARN,
Tags=tags)
response = 'SUCCESS'
except Exception as e:
print(e)
send_response(event, context, response)
return
if event['RequestType'] == 'Update':
# Do nothing and send a success immediately
send_response(event, context, response)
return
if event['RequestType'] == 'Delete':
try:
response = client.untag_resource(
ResourceARN = ResourceARN,
TagKeys = tags['Key']
)
response = 'SUCCESS'
except Exception as e:
print(e)
send_response(event, context, response)
def lambda_handler(event, context):
"""Lambda handler for the custom resource"""
try:
return custom_resource_handler(event, context)
except Exception as e:
print(e)
raise
这是 CFN 块:
CustomTagEvent:
Type: Custom::TagEventRule
Version: "1.0"
DependsOn: EventRule
Properties:
ServiceToken: "LAMBDA_ARN"
ResourceARN:
Fn::GetAtt:
- "EventRule"
- "Arn"
Tags:
-
Key: Name
创建 CLoudFormation 时出现错误“CREATE FAILED”。
“无效的 PhysicalResourceId”
但是,不知何故设法创建了标签。 需要帮助来理解为什么它在创建标签时会出现 CloudFormation 错误?
自定义资源需要 specific output 其中包含 PhysicalResourceId
:
{
"Status" : "SUCCESS",
"PhysicalResourceId" : "TestResource1",
"StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/stack-name/guid",
"RequestId" : "unique id for this create request",
"LogicalResourceId" : "MyTestResource",
"Data" : {
"OutputName1" : "Value1",
"OutputName2" : "Value2",
}
}
您的 lambda 函数不会生成这样的响应,因此会出错。
创建自定义资源的最佳方法是使用 AWS 专门为此目的提供的 cfn-response。
这解决了标记问题:
Code:
ZipFile: |
import boto3
import botocore
from botocore.exceptions import ClientError
import cfnresponse
import json
client = boto3.client("events")
def handler(event, context):
ResourceARN = event['ResourceProperties']['ResourceARN']
tags = event['ResourceProperties']['Tags']
if event['RequestType'] == 'Create':
response = client.tag_resource(
ResourceARN = ResourceARN,
Tags = tags
)
response = 'SUCCESS'
responseData = {}
responseData['Data'] = response
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
if event['RequestType'] == 'Update':
response = 'SUCCESS'
responseData = {}
responseData['Data'] = response
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
if event['RequestType'] == 'Delete':
for i in tags:
response = client.untag_resource(
ResourceARN = ResourceARN,
TagKeys = [i['Key']]
)
response = 'SUCCESS'
responseData = {}
responseData['Data'] = response
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")