背景
资源编排服务(Resource Orchestration Service, 简称ROS)是阿里云提供的一项简化云计算资源管理的服务。您可以遵循ROS定义的模板规范编写资源栈模板,在模板中定义所需的云计算资源(例如ECS实例、RDS数据库实例)、资源间的依赖关系等。ROS的编排引擎将根据模板自动完成所有资源的创建和配置,实现自动化部署及运维。
在创建资源栈时,允许对所有资源执行所有更新操作。默认情况下,具有资源栈更新权限的任何人均可更新资源栈中的所有资源。在更新期间,一些资源可能需要中断。使用资源栈策略可以防止资源栈资源在资源栈更新过程中被意外更新或删除。资源栈策略是一个 JSON/YAML 文档,该文档定义可对指定资源执行的更新操作。
设置资源栈策略后,默认情况下将保护资源栈中的所有资源。要允许对特定资源进行更新,您可在资源栈策略中为这些资源指定明确的 Allow 语句。您只能为每个资源栈定义一个资源栈策略,但在一个策略中可以保护多个资源。资源栈策略适用于所有尝试更新资源栈的 ROS 用户。您不能将不同的资源栈策略与不同的用户关联。
资源栈策略仅在资源栈更新过程中适用。与 RAM 策略不同,它不提供访问控制。仅将资源栈策略用作故障保护功能来防止意外更新特定资源栈资源。
关于资源栈策略的更多功能,可以参考这里。
功能介绍
简单示例
我们先看一个简单示例。下面的示例资源栈策略阻止更新 WebServers
资源:
{
"Statement" : [
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
},
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "LogicalResourceId/WebServers"
}
]
}
当您设置资源栈策略时,将默认保护所有资源。为了允许对所有资源进行更新,我们添加了一个 Allow
语句来允许对所有资源执行的所有操作。虽然 Allow
语句指定所有资源,但显式 Deny
语句将为具有 WebServers
逻辑 ID 的资源覆盖前者。此 Deny
语句阻止对 WebServers
资源进行的所有更新操作。
如何定义资源栈策略
定义资源栈策略 在创建资源栈时,未设置资源栈策略,因此允许对所有资源执行所有更新操作。要阻止对资源栈资源执行更新操作,可定义一个资源栈策略,然后对资源栈设置该策略。资源栈策略是一个 JSON/YAML 文档,它定义 ROS 用户可以执行的 ROS 资源栈更新操作以及这些操作应用到的资源。在创建资源栈时,可通过指定一个包含资源栈策略的文本文件或键入该策略来设置资源栈策略。在资源栈上设置资源栈策略时,默认情况下会拒绝未显式允许的任何更新。
您可定义一个带 5 个元素的资源栈策略:Effect
、Action
、Principal
、Resource
和 Condition
。下面的伪代码显示了资源栈策略语法。
{
"Statement" : [
{
"Effect" : "Deny_or_Allow",
"Action" : "update_actions",
"Principal" : "*",
"Resource" : "LogicalResourceId/resource_logical_ID",
"Condition" : {
"StringEquals_or_StringLike" : {
"ResourceType" : [resource_type, ...]
}
}
}
]
}
- Effect
确定是拒绝还是允许对指定资源执行指定的操作。您只能指定
Deny
或Allow
,例如:"Effect" : "Deny"
说明 如果资源栈策略包含重叠语句 (同时允许和拒绝对资源进行更新),则Deny
语句始终将覆盖Allow
语句。要确保某一资源受到保护,请对该资源使用Deny
语句。 - Action
指定拒绝或允许的更新操作:
- Update:Modify
指定在对资源应用更改期间不会中断或有某些中断的更新操作。
- Update:Delete
指定删除资源的更新操作。从资源栈模板中完全删除资源的更新都需要此操作。
- Update:*
指定所有更新操作。星号是通配符,代表所有更新操作。
说明Action
还可以指定Update:Replace
作为保留功能。但替换功能,目前尚未支持。以下示例说明如何只指定修改和删除操作:
"Action" : ["Update:Modify", "Update:Delete"]
要允许除某个更新操作之外的所有更新操作,请使用
NotAction
。例如,要允许除Update:Delete
之外的所有更新操作,请使用NotAction
,如本示例中所示:{ "Statement" : [ { "Effect" : "Allow", "NotAction" : "Update:Delete", "Principal": "*", "Resource" : "*" } ] }
- Update:Modify
- Principal
指定策略应用于的实体。需要此元素,但仅支持通配符 (*),这意味着策略应用于所有主体。
- Resource
指定将应用策略的资源的逻辑 ID。要指定资源类型,请使用
Condition
元素。要指定一个资源,请使用其逻辑 ID。例如:
"Resource" : ["LogicalResourceId/myECS"]
您可以对逻辑 ID 使用通配符。例如,如果您对所有相关资源使用一个通用逻辑 ID 前缀,则可使用通配符指定所有资源:
"Resource" : ["LogicalResourceId/Prefix*"]
您还可以对资源使用 Not 元素。例如,要允许对所有资源执行除某个更新之外的所有更新,请使用
NotResource
元素保护该资源:{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "NotResource" : "LogicalResourceId/WebServers" } ] }
设置资源栈策略时,会拒绝未显式允许的任何更新。通过允许更新
WebServers
资源之外的所有资源,会拒绝更新WebServers
资源。 - Condition
指定应用策略的资源类型。要指定特定资源的逻辑 ID,请使用
Resource
元素。您可以指定资源类型(如所有 ECS 和 RDS 数据库实例),如以下示例所示:
{ "Statement" : [ { "Effect" : "Deny", "Principal" : "*", "Action" : "Update:*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["ALIYUN::ECS::Instance", "ALIYUN::RDS::DBInstance"] } } }, { "Effect" : "Allow", "Principal" : "*", "Action" : "Update:*", "Resource" : "*" } ] }
Allow
语句授予对所有资源的更新权限,而Deny
语句拒绝对 ECS 和 RDS 数据库实例的更新。Deny
语句始终覆盖允许操作。您可以对资源类型使用通配符。例如,您可以使用通配符拒绝所有 ALIYUN ECS 资源(如实例、安全组和子网)的更新权限,如以下示例所示:
"Condition" : { "StringLike" : { "ResourceType" : ["ALIYUN::ECS::*"] } }
使用通配符时,必须使用 StringLike 条件。
更多示例
以下示例策略说明如何阻止对所有资源栈资源和特定资源进行更新,并阻止特定类型的更新。
阻止对所有资源栈资源的更新
要阻止对所有资源栈资源的更新,以下策略为所有资源的所有更新操作指定 Deny
语句。
{
"Statement" : [
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
}
]
}
阻止对单个资源的更新
以下策略拒绝对带 WebServers
逻辑 ID 的虚拟机执行的所有更新操作。它使用 Allow
语句允许对所有其他资源栈资源进行全部更新操作。Allow
语句不应用于 WebServers
资源,因为 Deny
语句始终覆盖允许操作。
{
"Statement" : [
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "LogicalResourceId/WebServers"
},
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
}
]
}
您可以使用默认拒绝来获得与上一示例相同的结果。设置资源栈策略时,ROS 会拒绝未显式允许的任何更新。以下策略允许对除 WebServers
资源 (默认情况下,拒绝更新此资源) 之外的所有资源进行的更新。
{
"Statement" : [
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"NotResource" : "LogicalResourceId/WebServers"
}
]
}
Allow
语句 (例如,使用通配符的
Allow
语句),则可能意外授予 (原本不打算授予) 对资源的更新权限。由于显式拒绝将覆盖任何允许操作,因此可以使用
Deny
语句确保保护资源。
阻止对资源类型的所有实例进行更新
以下策略拒绝针对 RDS 数据库实例资源类型的所有更新操作。它使用 Allow
语句允许对所有其他资源栈资源进行全部更新操作。Allow
语句不应用于 RDS 数据库实例资源,因为 Deny
语句始终覆盖允许操作。
{
"Statement" : [
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*",
"Condition" : {
"StringEquals" : {
"ResourceType" : ["ALIYUN::RDS::DBInstance"]
}
}
},
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
}
]
}
阻止对嵌套资源栈进行更新
以下策略拒绝针对 ROS 资源栈资源类型 (嵌套资源栈) 的所有更新操作。它使用 Allow
语句允许对所有其他资源栈资源进行全部更新操作。Allow
语句不会应用于 ROS 资源栈资源,因为 Deny
语句始终覆盖 Allow
操作。
{
"Statement" : [
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*",
"Condition" : {
"StringEquals" : {
"ResourceType" : ["ALIYUN::ROS::Stack"]
}
}
},
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
}
]
}
测试验证
1. 在ROS控制台使用如下模板创建一个资源栈。这个模板包含一个名为WaitConditionHandle的资源,用于示例。
ROSTemplateFormatVersion: '2015-09-01'
Parameters:
UpdateVersion:
Type: Number
Resources:
WaitConditionHandle:
Type: ALIYUN::ROS::WaitConditionHandle
Properties:
UpdateVersion:
Ref: UpdateVersion
Outputs:
CurlCli:
Value:
Fn::GetAtt:
- WaitConditionHandle
- CurlCli
资源栈配置如下:
资源栈策略配置如下:
资源栈策略内容如下:
{
"Statement" : [
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "LogicalResourceId/WaitConditionHandle"
},
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
}
]
}
2. 尝试更新资源栈。
发现更新失败回滚。失败原因是资源栈策略不允许更新WaitConditionHandle资源。
3.使用临时资源栈策略更新资源栈。
该策略允许所有更新。
{
"Statement" : [
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
}
]
}
发现资源栈更新成功。