Amazon SNS 支持的自定义资源
以下主题展示了如何使用服务令牌配置自定义资源,该令牌指定了 CloudFormation 向其发送请求的 Amazon SNS 主题。您还将了解自定义资源堆栈创建、更新和删除过程中发送和接收的事件和消息的顺序。
通过自定义资源和 Amazon SNS,您可以启用方案,例如向堆栈添加新资源和向堆栈注入动态数据。例如,创建堆栈时,CloudFormation 可以向被 Amazon EC2 实例上运行的应用程序监控的主题发送 Create
请求。Amazon SNS 通知触发应用程序以执行其他预置任务,如检索列在白名单中的弹性 IP 池。完成后,应用程序发送响应(和任何输出数据),通知 CloudFormation 继续执行堆栈操作。
将 Amazon SNS 主题指定为自定义资源的目标时,CloudFormation 会在涉及自定义资源的堆栈操作期间,向指定的 SNS 主题发送消息。要处理这些消息并执行必要的操作,必须有一个订阅 SNS 主题的受支持端点。
有关自定义资源及其工作原理的介绍,请参阅使用自定义资源创建自定义预置逻辑。有关 Amazon SNS 及其工作原理的信息,请参阅 Amazon Simple Notification Service Developer Guide。
使用 Amazon SNS 创建自定义资源
步骤 1:堆栈创建
-
模板开发人员创建包含自定义资源的 CloudFormation 堆栈。
在以下模板示例中,对具有逻辑 ID
Custom::
的自定义资源使用自定义资源类型名称SeleniumTester
。自定义资源类型名称必须是字母数字字符,最大长度为 60 个字符。MySeleniumTest
自定义资源类型是使用服务令牌、可选提供商特定属性以及由自定义资源提供商定义的可选 Fn::GetAtt 属性声明的。使用这些属性和特性可以将信息从template developer传递给custom resource provider,反之亦然。服务令牌指定资源提供商已配置的 Amazon SNS 主题。
{ "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "
MySeleniumTest
" : { "Type": "Custom::SeleniumTester
", "Version" : "1.0", "Properties" : { "ServiceToken": "arn:aws:sns:us-west-2
:123456789012
:CRTest
","seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
} } }, "Outputs" : { "topItem
" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest
", "resultsPage
"] } }, "numRespondents
" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest"
, "lastUpdate
"] } } } }注意
在提供商响应 CloudFormation 期间,自定义资源提供商会返回使用
访问的数据的名称和值。如果custom resource provider是第三方,则template developer必须从custom resource provider获取这些返回值的名称。Fn::GetAtt
-
CloudFormation 使用
"RequestType" : "Create"
向资源提供者发送一条 Amazon SNS 通知,其中包含有关堆栈的信息、堆栈模板中的自定义资源属性和用于响应的 S3 URL。用于发送通知的 SNS 主题嵌入在模板的
ServiceToken
属性中。要避免使用硬编码值,模板开发人员可以使用模板参数,以便在启动堆栈时输入值。以下示例显示一个自定义资源
Create
请求,其中包含一个用Custom::SeleniumTester
的LogicalResourceId
创建的自定义资源类型名称MySeleniumTester
:{ "RequestType" : "Create", "ResponseURL" : "http://pre-signed-S3-url-for-response", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this create request", "ResourceType" : "Custom::SeleniumTester", "LogicalResourceId" : "MySeleniumTester", "ResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4" ] } }
有关
Create
请求的请求对象的详细信息,请参阅 创建 主题。 -
custom resource provider处理template developer发送的数据,并确定
Create
请求是否已成功。然后,资源提供者使用 CloudFormation 发送的 S3 URL 来发送SUCCESS
或FAILED
响应。根据响应类型,CloudFormation 将需要不同的响应字段。有关特定请求类型的响应字段的信息,请参阅 自定义资源请求类型 部分中该请求类型的文档。
在响应创建或更新请求时,custom resource provider 可以在响应的 Data 字段中返回数据元素。这些是名称/值对,名称对应于用于堆栈模板中的自定义资源的
属性。该值是模板开发人员对具有此属性名称的资源调用Fn::GetAtt
时返回的数据。Fn::GetAtt
以下是自定义资源响应的示例:
{ "Status" : "SUCCESS", "PhysicalResourceId" : "Tester1", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this create request", "LogicalResourceId" : "MySeleniumTester", "Data" : { "resultsPage" : "http://www.myexampledomain/test-results/guid", "lastUpdate" : "2012-11-14T03:30Z" } }
有关
Create
请求的响应对象的详细信息,请参阅 创建 主题。StackId
、RequestId
和LogicalResourceId
字段必须从请求中逐字复制。 -
CloudFormation 将堆栈状态声明为
CREATE_COMPLETE
或CREATE_FAILED
。如果堆栈已成功创建,template developer通过 Fn::GetAtt 访问已创建的自定义资源的输出值,可以使用这些值。例如,用于举例说明的自定义资源模板使用
将资源输出复制到堆栈输出:Fn::GetAtt
"Outputs" : { "
topItem
" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest
", "resultsPage
"] } }, "numRespondents
" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest
", "lastUpdate
"] } } }
步骤 2:堆栈更新
要更新现有堆栈,您必须提交一个指定了堆栈资源属性更新的模板,如下面的示例所示。CloudFormation 只更新模板中指定了更改的资源。有关更多信息,请参阅 理解堆栈资源的更新行为。
您可以更新需要替换基础物理资源的自定义资源。在 CloudFormation 模板中更新某个自定义资源时,CloudFormation 会向该自定义资源发送更新请求。如果需要替换自定义资源,新的自定义资源必须使用新的物理 ID 发送响应。CloudFormation 收到响应时,会比较新旧自定义资源的 PhysicalResourceId
。如果不同,CloudFormation 会将更新视为替换,并向旧资源发送删除请求,如 步骤 3:堆栈删除 中所示。
注意
如果您没有对自定义资源进行更改,CloudFormation 在堆栈更新过程中不会向资源发送请求。
-
template developer启动对包含自定义资源的堆栈的更新。在更新期间,template developer可以在堆栈模板中指定新属性。
下面是一个使用自定义资源类型的堆栈模板
Update
示例:{ "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "MySeleniumTest" : { "Type": "Custom::SeleniumTester", "Version" : "1.0", "Properties" : { "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest", "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
"http://mynewsite.com"
], "frequencyOfTestsPerHour" : [ "3", "2", "4","3"
] } } }, "Outputs" : { "topItem" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] } }, "numRespondents" : { "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] } } } } -
CloudFormation 会使用
"RequestType" : "Update"
向资源提供者发送一条 Amazon SNS 通知,其中包含与Create
调用类似的信息,不同的是,OldResourceProperties
字段包含旧的资源属性,而 ResourceProperties 包含已更新的(如果有)资源属性。以下是一个
Update
请求的示例:{ "RequestType" : "Update", "ResponseURL" : "http://pre-signed-S3-url-for-response", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "uniqueid for this update request", "LogicalResourceId" : "MySeleniumTester", "ResourceType" : "Custom::SeleniumTester", "PhysicalResourceId" : "Tester1", "ResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com", "http://mynewsite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ] }, "OldResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4" ] } }
有关
Update
请求的请求对象的详细信息,请参阅 更新 主题。 -
自定义资源提供商处理由 CloudFormation 发送的数据。自定义资源执行更新并向 S3 URL 发送
SUCCESS
或FAILED
响应。然后,CloudFormation 比较新旧自定义资源的PhysicalResourceIDs
。如果不同,CloudFormation 将认为更新需要替换,并向旧资源发送删除请求。下面的示例说明custom resource provider对Update
请求的响应。{ "Status" : "SUCCESS", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "uniqueid for this update request", "LogicalResourceId" : "MySeleniumTester", "PhysicalResourceId" : "Tester2" }
有关
Update
请求的响应对象的详细信息,请参阅 更新 主题。StackId
、RequestId
和LogicalResourceId
字段必须从请求中逐字复制。 -
CloudFormation 将堆栈状态声明为
UPDATE_COMPLETE
或UPDATE_FAILED
。如果更新失败,堆栈将回滚。如果堆栈更新成功,template developer可以使用
访问已创建自定义资源的任何新输出值。Fn::GetAtt
步骤 3:堆栈删除
-
模板开发人员删除包含自定义资源的堆栈。CloudFormation 将获取堆栈模板中指定的当前属性及 SNS 主题,并准备向自定义资源提供商发出请求。
-
CloudFormation 使用
"RequestType" : "Delete"
向资源提供者发送一条 Amazon SNS 通知,其中包含有关堆栈的当前信息、堆栈模板中的自定义资源属性和用于响应的 S3 URL。只要您删除堆栈或进行自定义资源的删除或替换更新,CloudFormation 都会比较新旧自定义资源的
PhysicalResourceId
。如果不同,CloudFormation 会将更新视为替换,并向旧资源 (OldPhysicalResource
) 发送删除请求,如下面的Delete
请求示例所示。{ "RequestType" : "Delete", "ResponseURL" : "http://pre-signed-S3-url-for-response", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this delete request", "ResourceType" : "Custom::SeleniumTester", "LogicalResourceId" : "MySeleniumTester", "PhysicalResourceId" : "Tester1", "ResourceProperties" : { "seleniumTester" : "SeleniumTest()", "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com", "http://mynewsite.com" ], "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ] } }
有关
Delete
请求的请求对象的详细信息,请参阅 删除 主题。DescribeStackResource
、DescribeStackResources
和ListStackResources
显示用户定义的名称 (如果已指定)。 -
自定义资源提供商处理 CloudFormation 发送的数据,并确定
Delete
请求是否已成功。然后,资源提供者使用 CloudFormation 发送的 S3 URL 来发送SUCCESS
或FAILED
响应。要成功删除带自定义资源的堆栈,custom resource provider 必须成功响应删除请求。以下是custom resource provider响应
Delete
请求的示例:{ "Status" : "SUCCESS", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this delete request", "LogicalResourceId" : "MySeleniumTester", "PhysicalResourceId" : "Tester1" }
有关
Delete
请求的响应对象的详细信息,请参阅 删除 主题。StackId
、RequestId
和LogicalResourceId
字段必须从请求中逐字复制。 -
CloudFormation 将堆栈状态声明为
DELETE_COMPLETE
或DELETE_FAILED
。