在模板中创建等待条件 - AWS CloudFormation

在模板中创建等待条件

重要

对于 Amazon EC2 和 Auto Scaling 资源,我们建议您使用 CreationPolicy 属性而非等待条件。当实例创建过程成功完成后,将“CreationPolicy”属性添加到这些资源,并使用 cfn-signal 帮助程序脚本发送信号。

有关更多信息,请参阅CreationPolicy 属性使用 AWS CloudFormation 在 Amazon EC2 上部署应用程序

利用 AWS::CloudFormation::WaitConditionHandle 资源和 CreationPolicy 属性 属性,您可以执行以下操作:

  • 将堆栈资源创建与堆栈创建之外的其他配置操作进行协调

  • 跟踪配置过程的状态

例如,您可以在应用程序配置部分完成后开始另一个资源的创建,或者也可以在安装和配置过程中发送信号以跟踪其进度。

使用等待条件句柄

注意

如果使用 VPC 端点功能,则响应等待条件的 VPC 中的资源必须能够访问 AWS CloudFormation 特定的 Amazon Simple Storage Service(Amazon S3)桶。资源必须将等待条件响应发送到预签名 Amazon S3 URL。如果不能向 Amazon S3 发送响应,AWS CloudFormation 不会收到响应,堆栈操作就会失败。有关更多信息,请参阅 设置 AWS CloudFormation 的 VPC 端点针对 Amazon S3 的 VPC 端点的存储桶策略的示例

您可以使用等待条件和等待条件句柄让 AWS CloudFormation 暂停堆栈的创建,并在继续创建堆栈前等待一个信号。例如,在考虑完成 Amazon EC2 实例的创建前,您可能需要下载和配置 Amazon EC2 实例上的应用程序。

以下列表概述了带有等待条件句柄的等待条件的工作原理:

  • 跟任何其他资源一样,AWS CloudFormation 将创建等待条件。当 AWS CloudFormation 创建等待条件时,它会报告等待条件的状态为 CREATE_IN_PROGRESS,并进行等待,直到它接收必要数量的成功信号或等待条件的超时周期过期。如果在超时期限过期前,AWS CloudFormation 接收了必要数量的成功信号,那么它将继续创建堆栈;否则,它会将等待条件状态设定为 CREATE_FAILED 并回滚堆栈。

  • Timeout 属性确定 AWS CloudFormation 等待必需数量的成功信号的时间长度。Timeout 是一种最低时限属性,表示超时的发生时间不会早于您指定的时间,但可能会在之后的很短时间内发生。您可指定的最长时间为 43200 秒 (12 小时)。

  • 通常情况下,特定资源创建后,例如 Amazon EC2 实例、RDS 数据库实例或自动扩缩组,您会想要等待条件立即开始。可以通过为等待条件添加 DependsOn 属性来完成此操作。在将 DependsOn 属性添加至等待条件后,仅可在特定资源创建完成后指定创建等待条件。等待条件创建后,AWS CloudFormation 即开始超时周期,并等待成功信号。

  • 您还可以使用其他资源上的 DependsOn 属性。例如,创建使用数据库的 EC2 实例前,您可能想要先创建一个 Amazon RDS 数据库实例并在该数据库实例上配置一个数据库。在这种情况下,您可以创建拥有指定数据库实例的 DependsOn 属性的等待条件;此外,您还可以创建拥有指定等待条件的 DependsOn 属性的 EC2 实例资源。通过上述操作可以确保数据库实例和等待条件完成后,仅可以直接创建 EC2 实例。

  • 将等待条件状态设置为 CREATE_COMPLETE 并继续创建堆栈前,AWS CloudFormation 必须接收针对等待条件的指定数量的成功信号。等待条件的 Count 属性将指定成功信号的数量。如果无一设置,则默认值为 1。

  • 等待条件需要等待条件句柄来设置用作信号机制的预签名 URL。通过预签名 URL,您可以发送信号,而无需提供 AWS 凭证。您将使用预签名 URL 发送成功或失败信号,其内嵌于 JSON 语句中。有关 JSON 语句格式,请参阅 等待条件信号 JSON 格式

  • 如果在超时期限过期前,等待条件接受了必要数量的成功信号(按照计数属性的定义),那么 AWS CloudFormation 会将等待信号标记为 CREATE_COMPLETE,并继续创建堆栈。否则,AWS CloudFormation 将放弃等待条件,并回滚堆栈(例如,如果超时期限过期,而此时并未接收到必要数量的成功信号或者接收到失败信号)。

如需在堆栈中使用等待条件:
  1. 在堆栈模板中声明 AWS::CloudFormation::WaitConditionHandle 资源。等待条件句柄并无属性;但是,WaitConditionHandle 资源参考将解析您用于向 WaitCondition 发送成功或失败信号的预签名 URL。例如:

    "myWaitHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle", "Properties" : { } }
  2. 在堆栈模板中声明 AWS::CloudFormation::WaitCondition 资源。WaitCondition 资源具有两项必要属性:Handle 为模板中已声明 WaitConditionHandle 的参考,Timeout 为 AWS CloudFormation 等待的秒数。您也可以选择设置 Count 属性,其将确定 AWS CloudFormation 重新开始创建堆栈前,等待条件必须接收的成功信号的数量。

    您应在等待条件中设置 DependsOn 属性,才能在等待条件触发后进行控制操作。DependsOn 子句将资源与等待条件相关联。在 AWS CloudFormation 创建 DependsOn 资源后,它将阻止堆栈资源的进一步创建,直至出现以下任一情况:a)超时期限过期;b)接收到必要数量的成功信号;c)接收到失败信号。

    此处为等待条件的一项示例,它在 Ec2Instance 资源成功创建后开始,运用 myWaitHandle 资源作为 WaitConditionHandle,超时为 4500 秒,默认 Count 为 1(因尚未指定 Count 属性):

    "myWaitCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "Ec2Instance", "Properties" : { "Handle" : { "Ref" : "myWaitHandle" }, "Timeout" : "4500" } }
  3. 获取用于发送信号的预签名 URL。

    在模板中,可通过将 AWS::CloudFormation::WaitConditionHandle 资源的逻辑名称传输至 Ref 内置函数,实现对预签名 URL 的检索。例如,您可以使用 AWS::EC2::Instance 资源的 UserData 属性将预签名 URL 传递给 Amazon EC2 实例,以使这些实例上运行的脚本或应用程序可以向 AWS CloudFormation 发送成功或失败信号:

    "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "", ["SignalURL=", { "Ref" : "myWaitHandle" } ] ] } }

    注意:在 AWS Management Console 或 AWS CloudFormation 命令行工具中,预签名 URL 显示为等待条件句柄资源的物理 ID。

  4. 当堆栈进入等待条件后,选择检测方法。

    如果您通过启用的通知创建堆栈,那么 AWS CloudFormation 将向指定主题发布针对每项堆栈事件的通知。如果您或您的应用程序订阅了该主题,您可以监测针对等待条件句柄创建事件的通知,并通过通知消息来检索预签名 URL。

    您还可以使用 AWS Management Console、AWS CloudFormation 命令行工具或 AWS CloudFormation API 来监控堆栈事件。

  5. 利用预签名 URL 发送成功或失败信号。

    您需要通过预签名 URL 发送 HTTP 请求消息之后,才能发送信号。请求方法必须为 PUT,并且 Content-Type 标题必须为空字符串或省略。请求消息必须为 等待条件信号 JSON 格式 指定表单的 JSON 结构。

    您需要针对 AWS CloudFormation 按顺序发送由 Count 属性指定数量的成功信息,才能继续堆栈创建。如果您的 Count 超过 1,则在发送到特定等待条件的所有信号中,每个信号的 UniqueId 值必须是唯一的。UniqueId 是随机的字母数字字符串。

    curl 命令是发送信号的一种方式。以下示例显示了向等待条件发送成功信号的 curl 命令行。

    $ curl -T /tmp/a \ "https://cloudformation-waitcondition-test.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-2%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"

    其中文件 /tmp/a 包含以下 JSON 结构:

    { "Status" : "SUCCESS", "Reason" : "Configuration Complete", "UniqueId" : "ID1234", "Data" : "Application has completed configuration." }

    此示例显示发送同一成功信号的 curl 命令行,不同的是,它将 JSON 结构作为命令行参数发送。

    $ curl -X PUT \ -H 'Content-Type:' --data-binary '{"Status" : "SUCCESS","Reason" : "Configuration Complete","UniqueId" : "ID1234","Data" : "Application has completed configuration."}' \ "https://cloudformation-waitcondition-test.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-2%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"

等待条件信号 JSON 格式

当您发送等待条件的信号时,您必须使用以下 JSON 格式:

{ "Status" : "StatusValue", "UniqueId" : "Some UniqueId", "Data" : "Some Data", "Reason" : "Some Reason" }

其中:

StatusValue 必须为以下数值之一:

  • SUCCESS 表示成功信号。

  • FAILURE 表示失败信号,同时触发失败等待条件,且堆栈发生回滚。

UniqueId 将信号标识为 AWS CloudFormation。如果等待条件的 Count 属性大于 1,那么在针对特定等待条件发送的所有信号中,UniqueId 值必须唯一;否则,AWS CloudFormation 会将该信号视为对先前已发送的具有相同 UniqueId 的信号的重传,继而忽略该信号。

Data 为要通过信号发送回的任何信息。可以通过调用模板中的 Fn::GetAtt 函数来访问 Data 值。例如,如果您针对等待条件 mywaitcondition 创建以下输出值,则可以使用 aws cloudformation describe-stacks 命令、DescribeStacks API 操作或 AWS CloudFormation 控制台的输出选项卡,来查看通过有效信号发送到 AWS CloudFormation 的 Data

"WaitConditionData" : { "Value" : { "Fn::GetAtt" : [ "mywaitcondition", "Data" ]}, "Description" : "The data passed back as part of signalling the WaitCondition" },

Fn::GetAtt 函数将返回 UniqueIdData 作为 JSON 结构中的名称/值对。以下示例是由上面定义的 WaitConditionData 输出值返回的 Data 属性:

{"Signal1":"Application has completed configuration."}

Reason 为字符串,除与 JSON格式 相一致外,其内容中无任何其他限制。