Stack policies can be used to prevent stack resources from being unexpectedly updated or deleted during a stack update. This topic describes stack policies and how to configure and update a stack policy.

Background information

A stack policy is a JSON or YAML document that defines all update actions that are allowed on specified resources. When you create a stack, all update actions are allowed on all resources of the stack. Users with stack update permissions can update all resources in the stack. During an update, some running resources may be interrupted to ensure that the update is successful. After a stack policy is configured, Resource Orchestration Service (ROS) protects all resources in the stack. To allow updates to specific resources, you can specify an Allow statement for those resources in your stack policy.

Note
  • You can define only one stack policy for each stack. A single policy can protect multiple resources.
  • During a stack update, ROS automatically updates the resources that depend on other updated resources. For example, ROS automatically updates resources that reference an updated resource. However, you must have permissions to update resources that are associated with the stack policy.

A stack policy takes effect only during stack updates. Unlike RAM policies, stack policies do not provide access control. A stack policy can be used only as a fail-safe mechanism that prevents unintended updates to specific stack resources.

Define a stack policy

If no stack policy is configured when you create a stack, all update actions are allowed on all resources. To prevent updates to resources in a stack, you can define a stack policy and configure it for your stack. When you create a stack, you can enter a stack policy or specify a text file that contains your stack policy. After you configure the stack policy, updates that are not allowed are denied.

You can define a stack policy that has the following elements: Effect, Action, Principal, Resource, and Condition.

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

The following section describes the preceding elements:

  • Effect

    Indicates whether the specified actions are denied or allowed on the specified resources. You can specify only Deny or Allow. Example:

    "Effect" : "Deny"
    Note If a stack policy includes both Allow and Deny statements, the Deny statement overrides the Allow statement. If you want to protect your resource, use the Deny statement.
  • Action

    The update actions that are denied or allowed:

    • Update:Modify

      The update action during which resources may experience no interruptions or some interruptions while changes are being applied.

    • Update:Delete

      The update action during which resources are deleted. This action is required if you want to delete all resources from a stack template.

    • Update:*

      All update actions. The wildcard character (*) is used to represent all update actions.

    Note You can also specify Update:Replace as a reserved feature for Action. However, the replacement feature is unavailable.

    The following example shows how to specify the Update:Delete and Update:Modify actions:

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

    If you want to allow all update actions except one, use the NotAction statement. In the following example, NotAction is used to allow all update actions except for Update:Delete.

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

    The principal to which the policy applies. This parameter only accepts the wildcard character (*), which specifies that the policy applies to all principals.

  • Resource

    The logical IDs of the resources to which the policy applies. If you want to specify resource types, use the Condition element.

    If you want to specify a resource, use the logical ID of that resource. Example:

    "Resource" : ["LogicalResourceId/myECS"]

    This parameter supports the wildcard character (*). For example, if you want to match logical IDs that have the same prefix, append the wildcard character (*) to the end of the prefix.

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

    You can also add the Not prefix to the Resource element. For example, if you want to allow updates to all resources except for one, use the NotResource element to disallow updates to the resource.

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

    After you configure a stack policy, updates to resources that are not allowed are denied. For example, if you want to allow updates to all resources except for the WebServers resource, the stack policy denies updates to the WebServers resource.

  • Condition

    The resource type to which the policy applies. If you want to specify the logical IDs of specific resources, use the Resource element.

    You can specify a resource type, such as all ECS or ApsaraDB RDS instances.

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

    The Allow statement grants update permissions on all resources, and the Deny statement denies all updates to ECS and ApsaraDB RDS instances. The Deny statement overrides the Allow statement.

    This parameter supports the wildcard character (*). For example, you can use the wildcard character (*) to deny updates to all ECS resources, such as instances, security groups, and subnets.

    "Condition" : {
      "StringLike" : {
        "ResourceType" : ["ALIYUN::ECS::*"]
      }
    }
    Note You must use the StringLike condition when you use the wildcard character (*).

Configure a stack policy

You can use the ROS console or Alibaba Cloud CLI to apply a stack policy when you create a stack. You can also use the Alibaba Cloud CLI to apply a stack policy to an existing stack. After you apply a stack policy, you cannot delete the policy from the stack, but you can use the Alibaba Cloud CLI to modify the policy.

  • Configure a stack policy in the ROS console when you create a stack
    1. Log on to the ROS console.
    2. In the left-side navigation pane, click Stacks.
    3. In the upper-left corner, select a region from the drop-down list.
    4. On the Stacks page, click Create Stack and select Use New Resources (Standard) from the drop-down list.
    5. In the Select Template step of the Use New Resources (Standard) wizard, specify a template and click Next.
    6. In the Configure Template Parameters step of the Use New Resources (Standard) wizard, set Stack Name and other required parameters, and then click Next.
    7. In the Configure Stack step of the Use New Resources (Standard) wizard, set Stack Policy to Input Stack Policy.
    8. Configure a stack policy.
      • Input Stack Policy: Enter a stack policy.
      • Upload File: Upload a file in the JSON or YAML format that contains a stack policy.
    9. Follow the on-screen instructions to complete creating the stack.
  • Use the Alibaba Cloud CLI to configure a stack policy when you create a stack

    You can use one of the following methods to configure a stack policy:

    • Call the CreateStack operation to configure a stack policy.

      Use the aliyun ros CreateStack command with the --StackPolicyBody option to configure a policy that allows updates, or use the aliyun ros CreateStack command with the --StackPolicyURL option to specify a file that contains a policy.

    • Call the CreateChangeSet operation to configure a stack policy.

      Use the aliyun ros CreateChangeSet command with the --StackPolicyBody option to configure a policy that allows updates, or use the aliyun ros CreateChangeSet command with the --StackPolicyURL option to specify a file that contains a policy.

  • Use only the Alibaba Cloud CLI to configure a stack policy for an existing stack
    Use the aliyun ros SetStackPolicy command with the --StackPolicyBody option to configure a policy that allows updates, or use the aliyun ros SetStackPolicy command with the --StackPolicyURL option to specify a file that contains a policy.
    Note To configure a policy for an existing stack, you must have the permissions to call the SetStackPolicy operation.

Update protected resources

To update protected resources, you can create a temporary policy that overrides the stack policy and allows updates to those resources. The temporary policy does not permanently override the stack policy.

To update protected resources, you must have the permissions to call the SetStackPolicy operation. For more information about how to configure ROS permissions, see Use RAM to control resource access.

  • Update protected resources in the ROS console
    1. Log on to the ROS console.
    2. In the left-side navigation pane, click Stacks.
    3. In the upper-left corner, select the region where your stack resides from the drop-down list.
    4. On the Stacks page, click Update in the Actions column corresponding to the stack whose resources you want to update.
    5. In the Configure Template Parameters step, click Next.
    6. In the Configure Stack step, select Optional. Specify a temporary stack policy in JSON or YAML format.
    7. Configure a temporary stack policy.

      When you specify a temporary stack policy, the policy takes effect only for this update. In the temporary policy, you must specify an Allow statement for the protected resources that you want to update. For example, if you want to update all protected resources, you must specify a temporary overriding policy that allows all updates to your resources.

      {
        "Statement" : [
          {
            "Effect" : "Allow",
            "Action" : "Update:*",
            "Principal": "*",
            "Resource" : "*"
          }  
        ]
      }
    8. Follow the on-screen instructions to complete updating the stack.
  • Use the Alibaba Cloud CLI to update protected resources

    You can update protected resources in one of the following ways:

    • Call the UpdateStack operation.

      Use the aliyun ros UpdateStack command with the --StackPolicyDuringUpdateBody option to configure a policy that allows updates, or use the aliyun ros UpdateStack command with the --StackPolicyDuringUpdateURL option to specify a file that contains a policy.

    • Call the CreateChangeSet operation.

      Use the aliyun ros CreateChangeSet command with the --StackPolicyDuringUpdateBody option to configure a policy that allows updates, or use the aliyun ros CreateChangeSet command with the --StackPolicyDuringUpdateURL option to specify a file that contains a policy.

    Note ROS applies the temporary policy only during this update. The temporary policy does not permanently override the stack policy.

Update a stack policy

If you want to protect other resources or stop protecting the resources, you can update your stack policy. For example, to add a database that you want to protect to a stack, add a Deny statement for that database to the stack policy. To update the policy, you must have the permissions to call the SetStackPolicy operation.

  • Update a stack policy in the ROS console
    1. Log on to the ROS console.
    2. In the left-side navigation pane, click Stacks.
    3. In the upper-left corner, select the region where your stack resides from the drop-down list.
    4. On the Stacks page, find the desired stack and click the stack ID in the Stack Name column.
    5. In the Stack Policy section of the Stack Information tab, click Edit.
    6. In the Modify resource stack policy dialog box, enter the stack policy content.
    7. Click OK.
  • Use the Alibaba Cloud CLI to update a stack policy

    Use the aliyun ros SetStackPolicy command with the --StackPolicyBody option to configure a policy that allows updates, or use the aliyun ros SetStackPolicy command with the --StackPolicyURL option to specify a file that contains a policy.

    The following policy allows all updates on all resources:

    {
      "Statement" : [
        {
          "Effect" : "Allow",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*"
        }
      ]
    }
  • Use the Alibaba Cloud CLI to update a stack policy when you update a stack

    Use the aliyun ros UpdateStack command with the --StackPolicyBody option to configure a policy that allows updates, or use the aliyun ros UpdateStack command with the --StackPolicyURL option to specify a file that contains a policy.

    Use the aliyun ros CreateChangeSet command with the --StackPolicyBody option to configure a policy that allows updates, or use the aliyun ros CreateChangeSet command with the --StackPolicyURL option to specify a file that contains a policy.

Examples

The following sample policies show how to prevent updates to all or specific resources, and prevent specific types of update actions.

  • Prevent updates to all stack resources
    The following policy specifies a Deny statement to prevent all update actions on all stack resources:
    {
      "Statement" : [
        {
          "Effect" : "Deny",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*"
        }
      ]
    }
  • Prevent updates to a single resource (WebServers)
    • Example 1: Use the Deny statement to prevent updates to the WebServers resource.
      {
        "Statement" : [
          {
            "Effect" : "Allow",
            "Action" : "Update:*",
            "Principal": "*",
            "Resource" : "*"
          },
          {
            "Effect" : "Deny",
            "Action" : "Update:*",
            "Principal": "*",
            "Resource" : "LogicalResourceId/WebServers"
          }
        ]
      }

      The following section describes the preceding elements:

      • Allow: the actions allowed on all resources.
      • Deny: the actions denied on the resources that have the WebServers logical ID.
      • Principal: the principal to which the policy applies. This parameter only accepts the wildcard character (*), which specifies that the policy applies to all principals.
    • Example 2: Use the Allow statement to allow updates to all resources except WebServers.
      {
        "Statement" : [
          {
            "Effect" : "Allow",
            "Action" : "Update:*",
            "Principal": "*",
            "NotResource" : "LogicalResourceId/WebServers"
          }
        ]
      }
      Note
      • If you do not specify whether to update a resource when you configure a stack policy, the resource cannot be updated.
      • Risks may arise if you implement the default denial policy. If you have an Allow statement elsewhere in the policy, such as an Allow statement that uses a wildcard character, you might unintentionally grant update permissions to some resources. You can use the Deny statement to ensure that a resource is protected, because an explicit denial overrides all Allow actions.
  • Prevent updates to all instances of a resource type

    The following policy denies all update actions on ApsaraDB RDS instances. You can use the Allow statement to allow all update actions on all other stack resources. The Allow statement does not apply to ApsaraDB RDS instances because a Deny statement always overrides Allow actions.

    {
      "Statement" : [
        {
          "Effect" : "Deny",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*",
          "Condition" : {
            "StringEquals" : {
              "ResourceType" : ["ALIYUN::RDS::DBInstance"]
            }
          }
        },
        {
          "Effect" : "Allow",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*"
        }
      ]
    }
  • Prevent updates to nested stacks
    The following policy denies all update actions on nested ROS stack resources. You can use the Allow statement to allow all update operations on all other stack resources. The Allow statement does not apply to ROS stack resources because a Deny statement always overrides Allow actions.
    {
      "Statement" : [
        {
          "Effect" : "Deny",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*",
          "Condition" : {
            "StringEquals" : {
              "ResourceType" : ["ALIYUN::ROS::Stack"]
            }
          }
        },
        {
          "Effect" : "Allow",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*"
        }
      ]
    }