AWS CloudFormation
User Guide (API Version 2010-05-15)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。请点击 Amazon AWS 入门,可查看中国地区的具体差异

防止更新堆栈资源

在创建堆栈时,允许对所有资源执行所有更新操作。默认情况下,具有堆栈更新权限的任何人均可更新堆栈中的所有资源。在更新期间,一些资源可能需要中断或可能已完全替换,这会生成新的物理 ID 或全新的存储。使用堆栈策略可以防止堆栈资源在堆栈更新过程中被意外更新或删除。堆栈策略是一个 JSON 文档,该文档定义可对指定资源执行的更新操作。

设置堆栈策略后,默认情况下将保护堆栈中的所有资源。要允许对特定资源进行更新,您可在堆栈策略中为这些资源指定明确的 Allow 语句。您只能为每个堆栈定义一个堆栈策略,但在一个策略中可以保护多个资源。堆栈策略适用于所有尝试更新堆栈的 AWS CloudFormation 用户。您不能将不同的堆栈策略与不同的用户关联。

堆栈策略仅在堆栈更新过程中适用。它不提供访问控制,如 AWS Identity and Access Management (IAM) 策略。仅将堆栈策略用作故障保护功能来防止意外更新特定堆栈资源。要控制对 AWS 资源或操作的访问,请使用 IAM。

示例堆栈策略

下面的示例堆栈策略阻止更新 ProductionDatabase 资源:

{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" }, { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "LogicalResourceId/ProductionDatabase" } ] }

当您设置堆栈策略时,将默认保护所有资源。为了允许对所有资源进行更新,我们添加了一个 Allow 语句来允许对所有资源执行的所有操作。虽然 Allow 语句指定所有资源,但显式 Deny 语句将为具有 ProductionDatabase 逻辑 ID 的资源覆盖前者。此 Deny 语句阻止对 ProductionDatabase 资源进行的所有更新操作,例如替换或删除。

需要 Principal 元素,但仅支持通配符 (*),这意味着语句适用于所有委托人

注意

在堆栈更新期间,AWS CloudFormation 自动更新依赖其他更新后的资源的资源。例如,AWS CloudFormation 更新引用更新后的资源的资源。AWS CloudFormation 不对自动更新的资源进行任何物理更改(例如,资源的 ID),但如果这些资源关联有堆栈策略,则您必须获得权限才能更新它们。

定义堆栈策略

在创建堆栈时,未设置堆栈策略,因此允许对所有资源执行所有更新操作。要阻止对堆栈资源执行更新操作,可定义一个堆栈策略,然后对堆栈设置该策略。堆栈策略是一个 JSON 文档,它定义 AWS CloudFormation 用户可执行的 AWS CloudFormation 堆栈更新操作以及这些操作应用于的资源。在创建堆栈时,可通过指定一个包含堆栈策略的文本文件或键入该策略来设置堆栈策略。在堆栈上设置堆栈策略时,默认情况下会拒绝未显式允许的任何更新。

您可定义一个带 5 个元素的堆栈策略:EffectActionPrincipalResourceCondition。下面的伪代码显示了堆栈策略语法。

{ "Statement" : [ { "Effect" : "Deny_or_Allow", "Action" : "update_actions", "Principal" : "*", "Resource" : "LogicalResourceId/resource_logical_ID", "Condition" : { "StringEquals_or_StringLike" : { "ResourceType" : [resource_type, ...] } } }   ] }
效果

确定是拒绝还是允许对指定资源执行指定的操作。您只能指定 DenyAllow,例如:

"Effect" : "Deny"

重要

如果堆栈策略包含重叠语句(同时允许和拒绝对资源进行更新),则 Deny 语句始终将覆盖 Allow 语句。要确保某一资源受到保护,请对该资源使用 Deny 语句。

操作

指定拒绝或允许的更新操作:

更新:修改

指定在对资源应用更改期间不会中断或有某些中断的更新操作。所有资源都保持其物理 ID。

更新:替换

指定重新创建资源的更新操作。AWS CloudFormation 使用指定的更新创建新资源,然后删除旧资源。由于资源是重新创建的,因此新资源的物理 ID 可能不相同。

更新:删除

指定删除资源的更新操作。从堆栈模板中完全删除资源的更新都需要此操作。

更新:*

指定所有更新操作。星号是通配符,代表所有更新操作。

下面的示例说明如何只指定替换和删除操作:

"Action" : ["Update:Replace", "Update:Delete"]

要允许除某个更新操作之外的所有更新操作,请使用 NotAction。例如,要允许除 Update:Delete 之外的所有更新操作,请使用 NotAction,如本示例中所示:

{ "Statement" : [ { "Effect" : "Allow", "NotAction" : "Update:Delete", "Principal": "*", "Resource" : "*" } ] }

有关堆栈更新的更多信息,请参阅AWS CloudFormation 堆栈更新

委托人

Principal 元素指定策略应用于的实体。需要此元素,但仅支持通配符 (*),这意味着策略应用于所有主体

资源

指定将应用策略的资源的逻辑 ID。要指定资源类型,请使用 Condition 元素。

要指定一个资源,请使用其逻辑 ID。例如:

"Resource" : ["LogicalResourceId/myEC2instance"]

您可以对逻辑 ID 使用通配符。例如,如果您对所有相关资源使用一个通用逻辑 ID 前缀,则可使用通配符指定所有资源:

"Resource" : ["LogicalResourceId/CriticalResource*"]

您还可以对资源使用 Not 元素。例如,要允许对所有资源执行除某个更新之外的所有更新,请使用 NotResource 元素保护该资源:

{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "NotResource" : "LogicalResourceId/ProductionDatabase" } ] }

设置堆栈策略时,会拒绝未显式允许的任何更新。通过允许更新 ProductionDatabase 资源之外的所有资源,会拒绝更新 ProductionDatabase 资源。

条件

指定应用策略的资源类型。要指定特定资源的逻辑 ID,请使用 Resource 元素。

您可以指定资源类型(如所有 EC2 和 RDS 数据库实例),如以下示例所示:

{ "Statement" : [ { "Effect" : "Deny", "Principal" : "*", "Action" : "Update:*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::EC2::Instance", "AWS::RDS::DBInstance"] } } }, { "Effect" : "Allow", "Principal" : "*", "Action" : "Update:*", "Resource" : "*" } ] }

Allow 语句授予对所有资源的更新权限,而 Deny 语句拒绝对 EC2 和 RDS 数据库实例的更新。Deny 语句始终覆盖允许操作。

您可以对资源类型使用通配符。例如,可以使用通配符拒绝对所有 Amazon EC2 资源(如实例、安全组和子网)的更新权限,如以下示例所示:

"Condition" : { "StringLike" : { "ResourceType" : ["AWS::EC2::*"] } }

使用通配符时,必须使用 StringLike 条件。

设置堆栈策略

您可以使用控制台或 AWS CLI 在创建堆栈时应用堆栈策略。您也可以使用 AWS CLI 将堆栈策略应用于现有堆栈。应用堆栈策略后,无法将其从堆栈中删除,但您可以使用 AWS CLI 修改该策略。

堆栈策略适用于所有尝试更新堆栈的 AWS CloudFormation 用户。您不能将不同的堆栈策略与不同的用户关联。

有关如何编写堆栈策略的信息,请参阅定义堆栈策略

在创建堆栈时设置堆栈策略(控制台)

  1. 通过以下网址打开 AWS CloudFormation 控制台:https://console.amazonaws.cn/cloudformation

  2. CloudFormation Stacks 页上,选择 Create Stack

  3. 在“Create Stack”向导的 Options 页上,展开 Advanced 部分。

  4. 选择 Browse,然后选择包含堆栈策略的文件或在 Stack policy 文本框中键入策略。

在创建堆栈时设置堆栈策略 (CLI)

  • aws cloudformation create-stack 命令与 --stack-policy-body 选项结合使用可键入修改后的策略,或将此命令与 --stack-policy-url 选项结合使用可指定包含策略的文件。

在现有堆栈上设置堆栈策略(仅限 CLI)

  • aws cloudformation set-stack-policy 命令与 --stack-policy-body 选项结合使用可键入修改后的策略,或将此命令与 --stack-policy-url 选项结合使用可指定包含策略的文件。

    注意

    要向现有堆栈添加策略,您必须有权执行 AWS CloudFormation SetStackPolicy 操作。

更新受保护资源

要更新受保护的资源,可创建一个覆盖堆栈策略并允许对这些资源进行更新的临时策略。在更新堆栈时指定覆盖策略。覆盖策略不会永久更改堆栈策略。

要更新受保护的资源,您必须拥有使用 AWS CloudFormation SetStackPolicy 操作的权限。有关设置 AWS CloudFormation 权限的信息,请参阅使用 AWS Identity and Access Management 控制访问

注意

在堆栈更新期间,AWS CloudFormation 自动更新依赖其他更新后的资源的资源。例如,AWS CloudFormation 更新引用更新后的资源的资源。AWS CloudFormation 不对自动更新的资源进行任何物理更改(例如,资源的 ID),但如果这些资源关联有堆栈策略,则您必须获得权限才能更新它们。

更新受保护的资源(控制台)

  1. 通过以下网址打开 AWS CloudFormation 控制台:https://console.amazonaws.cn/cloudformation

  2. 选择要更新的堆栈,然后依次选择 ActionsUpdate Stack

  3. 如果您修改了堆栈模板,请指定更新的模板的位置。否则,请选择 Use current template

    • 对于在计算机上本地存储的模板,选择 Upload a template to Amazon S3。选择 Choose File 以导航到文件并选中它,然后选择 Next

    • 对于在 Amazon S3 存储桶中存储的模板,选择 Specify an Amazon S3 URL。键入或粘贴模板的 URL,然后单击 Next

      如果您的模板存储在启用了版本控制的存储桶中,则您可以指定模板的具体版本,例如:https://s3.amazonaws.com/templates/myTemplate.template?versionId=123ab1cdeKdOW5IH4GAcYbEngcpTJTDW。有关更多信息,请参阅 Amazon Simple Storage Service 控制台用户指南 中的在启用了版本控制的存储桶中管理对象

  4. 如果您的模板包含参数,则在 Specify Parameters 页上,输入或修改参数值,然后选择 Next

    AWS CloudFormation 会使用当前在堆栈中设置的值填充每个参数(使用 NoEcho 属性声明的参数除外)。可以选择 Use existing value 来对这些参数使用当前值。

  5. Options 页上,选择包含覆盖堆栈策略的文件或键入策略,然后选择 Next。覆盖策略必须为您要更新的受保护资源指定 Allow 语句。

    例如,要更新所有受保护资源,可以指定允许所有更新的临时覆盖策略:

    { "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" }   ] }

    注意

    AWS CloudFormation 仅在此更新期间应用覆盖策略。覆盖策略不会永久更改堆栈策略。要修改堆栈策略,请参阅修改堆栈策略

  6. 审查提交的堆栈信息和更改。

    Review 部分中,检查您是否已提交正确的信息,例如参数值或模板 URL。如果您的模板包含 IAM 资源,请选择 I acknowledge that this template may create IAM resources 以指定您要使用模板中的 IAM 资源。有关使用模板中的 IAM 资源的更多信息,请参阅使用 AWS Identity and Access Management 控制访问

    Preview your changes 部分中,检查 AWS CloudFormation 是否将执行所有预期更改。例如,检查 AWS CloudFormation 是否将添加、删除和修改您打算添加、删除或修改的资源。AWS CloudFormation 通过为堆栈创建更改集来生成此预览。有关更多信息,请参阅 使用更改集更新堆栈

  7. 选择 Update

    您的堆栈将进入 UPDATE_IN_PROGRESS 状态。更新完成后,状态将设置为 UPDATE_COMPLETE

    如果堆栈更新失败,则 AWS CloudFormation 会自动回滚更改,并将状态设置为 UPDATE_ROLLBACK_COMPLETE

更新受保护资源 (CLI)

  • aws cloudformation update-stack 命令与 --stack-policy-during-update-body 选项结合使用可键入修改后的策略,或将此命令与 --stack-policy-during-update-url 选项结合使用可指定包含策略的文件。

    注意

    AWS CloudFormation 仅在此更新期间应用覆盖策略。覆盖策略不会永久更改堆栈策略。要修改堆栈策略,请参阅修改堆栈策略

修改堆栈策略

要保护其他资源或从资源中删除保护,请修改堆栈策略。例如,当您将要保护的数据库添加到堆栈时,会将该数据库的 Deny 语句添加到堆栈策略。要修改策略,您必须有权使用 SetStackPolicy 操作。

使用 AWS CLI 修改堆栈策略。

修改堆栈策略 (CLI)

  • aws cloudformation set-stack-policy 命令与 --stack-policy-body 选项结合使用可键入修改后的策略,或将此命令与 --stack-policy-url 选项结合使用可指定包含策略的文件。

您无法删除堆栈策略。要从所有资源删除全部保护,您可修改策略以明确允许对所有资源执行全部操作。以下策略允许对所有资源进行全部更新:

{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" }   ] }

更多示例堆栈策略

下面的示例策略说明如何阻止对所有堆栈资源和特定资源进行更新,并阻止特定类型的更新。

阻止对所有堆栈资源的更新

要阻止对所有堆栈资源的更新,以下策略为所有资源的所有更新操作指定 Deny 语句。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*" }   ] }

阻止对单个资源的更新

以下策略拒绝对带 MyDatabase 逻辑 ID 的数据库执行的所有更新操作。它使用 Allow 语句允许对所有其他堆栈资源进行全部更新操作。Allow 语句不应用于 MyDatabase 资源,因为 Deny 语句始终覆盖允许操作。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "LogicalResourceId/MyDatabase" }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

您可以使用默认拒绝来获得与上一示例相同的结果。设置堆栈策略时,AWS CloudFormation 会拒绝未显式允许的任何更新。以下策略允许对除 ProductionDatabase 资源(默认情况下,拒绝更新此资源)之外的所有资源进行的更新。

{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "NotResource" : "LogicalResourceId/ProductionDatabase" } ] }

重要

使用默认拒绝存在风险。如果您策略中的其他位置具有 Allow 语句(例如,使用通配符的 Allow 语句),则可能意外授予(原本不打算授予)对资源的更新权限。由于显式拒绝将覆盖任何允许操作,因此可以使用 Deny 语句确保保护资源。

阻止对资源类型的所有实例进行更新

以下策略拒绝针对 RDS 数据库实例资源类型的所有更新操作。它使用 Allow 语句允许对所有其他堆栈资源进行全部更新操作。Allow 语句不应用于 RDS 数据库实例资源,因为 Deny 语句始终覆盖允许操作。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::RDS::DBInstance"] } } }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

阻止针对实例的替换更新

以下策略拒绝会导致替换具有 MyInstance 逻辑 ID 的实例的更新。它使用 Allow 语句允许对所有其他堆栈资源进行全部更新操作。Allow 语句不应用于 MyInstance 资源,因为 Deny 语句始终覆盖允许操作。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:Replace", "Principal": "*", "Resource" : "LogicalResourceId/MyInstance" }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

阻止对嵌套堆栈进行更新

以下策略拒绝针对 AWS CloudFormation 堆栈资源类型(嵌套堆栈)的所有更新操作。它使用 Allow 语句允许对所有其他堆栈资源进行全部更新操作。Allow 语句不应用于 AWS CloudFormation 堆栈资源,因为 Deny 语句始终覆盖允许操作。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::CloudFormation::Stack"] } } }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }