This topic describes what a stack policy is and how to set, update, and modify a stack policy.

Background information

When you create a stack, all update operations are allowed on all resources. By default, anyone with stack update permissions can update all resources in the stack. During an update, some resources may be interrupted. You can use a stack policy to prevent stack resources from being unintentionally updated or deleted during a stack update.

A stack policy is a JSON or YAML document that defines the update operations that can be performed on specified resources.

After a stack policy is set, ROS protects all resources in the stack. To allow updates on specific resources, you can specify an explicit Allow statement for those resources in your stack policy. You can define only one stack policy for each stack, but a single policy can protect multiple resources. A stack policy applies to all ROS users who attempt to update the stack.

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

Sample stack policy

The following sample stack policy prevents updates to the WebServers resource:

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

The following elements are included in the stack policy:

  • Allow: the operations allowed on all resources.
  • Deny:the operations denied on the resources that have the WebServers logical ID.
  • Principal: the entity to which the policy applies. This element supports only the asterisk (*), which means that the policy applies to all principals.
Note During a stack update, ROS automatically updates the resources that depend on other updated resources. For example, ROS automatically updates a resource that references an updated resource. However, if those resources are associated with a stack policy, you must have permissions to update them.

Define a stack policy

If no stack policy is set when you create a stack, all update operations are allowed on all resources. To protect stack resources from update operations, define a stack policy and configure it for your stack. When you create a stack, you can set the stack policy by typing it out or specifying a text file that contains your stack policy. When you set a stack policy, any updates that are not explicitly allowed are denied by default.

You can define a stack policy with five elements: Effect, Action, Principal, Resource, and Condition. The following pseudo code shows the stack policy syntax:

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

The following elements are included in the stack policy:

  • Effect

    Determines whether the specified operations are denied or allowed on the specified resources. You can specify only Deny or Allow, such as:

    "Effect" : "Deny"
    Note If a stack policy includes overlapping statements that both allow and deny updates on a resource, a Deny statement always overrides an Allow statement. To ensure that a resource is protected, use a Deny statement for the resource.
  • Action

    The update operations that are denied or allowed:

    • Update:Modify

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

    • Update:Delete

      The update operations during which resources are removed. Updates that remove all resources from a stack template require this operation.

    • Update:*

      All update operations. The asterisk (*) is a wildcard that represents all update operations.

    Note You can also specify Update:Replace as a reserved function of Action. However, the replacement feature is not supported.

    The following example shows how to specify only the Modify and Delete operations:

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

    To allow all update operations except one, use NotAction. NotAction is used to allow all update operations except for Update:Delete in the following example:

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

    The entity to which the policy applies. This element supports only the asterisk (*), which means that the policy applies to all principals.

  • Resource

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

    To specify a single resource, use its logical ID. Example:

    "Resource" : ["LogicalResourceId/myECS"]

    You can use an asterisk (*) with logical IDs. For example, if you use a common logical ID prefix for all related resources, you can specify all of them with an asterisk (*).

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

    You can also use a Not element on resources. For example, to allow updates to all resources except for one, use the NotResource element to protect that resource.

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

    When you set a stack policy, any updates that are not explicitly allowed are denied. By allowing updates to all resources except for the WebServers resource, you can deny updates to the WebServers resource.

  • Condition

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

    You can specify a resource type, such as all ECS or ApsaraDB for 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 updates to ECS and ApsaraDB for RDS instances. The Deny statement always overrides Allow operations.

    You can use an asterisk (*) with resource types. For example, you can use an asterisk (*) to deny update permissions on 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 an asterisk (*).

Set a stack policy

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

A stack policy applies to all ROS users who attempt to update the stack. You cannot associate different stack policies with different users.

For more information about how to write a stack policy, see Define a stack policy.

  • Set a stack policy in the console when you create a stack
    1. Log on to the ROS console.
    2. In the left-side navigation pane, click Stacks.
    3. On the Stacks page, click Create Stack.
    4. In the Select Template step of the Create Stack wizard, select a template and click Next.
    5. In the Configure Template Parameters step of the Create Stack wizard, set Stack Name and Parameters, and click Next.
    6. In the Configure Stack step of the Create Stack wizard, set Stack Policy to Input Stack Policy.stack policy
    7. Configure a stack policy.
      • To write a policy in the ROS console, select Input Stack Policy and then enter the stack policy in the text field.
      • To use a policy defined in a separate file, click Upload File to upload the file that contains the stack policy.
    8. Proceed with the stack configuration in the Create Stack wizard to create the stack.
  • Use the CLI to set a stack policy when you create a stack

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

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

  • Set a stack policy on an existing stack (CLI only)
    Use the aliyun ros SetStackPolicy command with the --StackPolicyBody option to enter a modified policy, or use the aliyun ros SetStackPolicy command with the --StackPolicyURL option to specify a file that contains the policy.
    Note To add a policy to an existing stack, you must have permissions to perform the SetStackPolicy operation.

Update protected resources

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

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

Note During a stack update, ROS automatically updates the resources that depend on other updated resources. For example, ROS automatically updates a resource that references an updated resource. However, if those resources are associated with a stack policy, you must have permissions to update them.
  • Update protected resources in the console
    1. Log on to the ROS console.
    2. In the left-side navigation pane, click Stacks.
    3. On the Stacks page, click Update in the Actions column corresponding to the stack that you want to update.
    4. In the Configure Stack step of the Edit Stack wizard, select Specify a temporary stack policy in JSON or YAML format.update stack policy
    5. Configure a temporary stack policy.

      When you specify a temporary stack policy, the policy takes effect only for this update. The override policy must specify an Allow statement for the protected resources that you want to update. For example, to update all protected resources, you can specify a temporary override policy that allows all updates:

      {
        "Statement" : [
          {
            "Effect" : "Allow",
            "Action" : "Update:*",
            "Principal": "*",
            "Resource" : "*"
          }  
        ]
      }
    6. Proceed with the stack configuration in the Edit Stack wizard to update the stack.
  • Use the CLI to update protected resources

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

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

    Note ROS applies the override policy only during this update. The override policy does not permanently change the stack policy. To modify a stack policy, see Modify a stack policy.

Modify a stack policy

To protect additional resources or to remove protection from resources, modify the 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 modify the policy, you must have permissions to perform the SetStackPolicy operation.

  • Modify a stack policy in the console
    1. Log on to the ROS console.
    2. In the left-side navigation pane, click Stacks.
    3. On the Stacks page, click the ID of the stack you want to modify in the Stack Name column.
    4. In the Stack Policy section of the Stack Information tab, click Edit.
    5. In the Modify resource stack policy dialog box that appears, enter the stack policy content.2
    6. Click OK.
  • Use the CLI to modify a stack policy

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

    You cannot delete a stack policy. To remove all protection from all resources, you can modify the policy to explicitly allow all operations on all resources. The following policy allows all updates on all resources:

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

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

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

Stack policy examples

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

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

    You can use a default denial to achieve the same result as the previous example. When you set a stack policy, ROS denies any updates that are not explicitly allowed. The following policy allows updates to all resources except for the WebServers resource, which is denied by default.

    {
      "Statement" : [
        {
          "Effect" : "Allow",
          "Action" : "Update:*",
          "Principal": "*",
          "NotResource" : "LogicalResourceId/WebServers"
        }
      ]
    }
    Note Implementing a default denial policy carries risks. If you have an Allow statement elsewhere in the policy, such as an Allow statement that uses a wildcard, you might unintentionally grant update permissions to some resources. You can use a Deny statement to ensure that a resource is protected, because an explicit denial overrides any Allow operations.
  • Prevent updates to all instances of a resource type

    The following policy denies all update operations on ApsaraDB for RDS instances. It uses an Allow statement to allow all update operations on all other stack resources. The Allow statement does not apply to ApsaraDB for RDS instances, because a Deny statement always overrides Allow operations.

    {
      "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 operations on nested ROS stack resources. It uses an 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 operations.
    {
      "Statement" : [
        {
          "Effect" : "Deny",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*",
          "Condition" : {
            "StringEquals" : {
              "ResourceType" : ["ALIYUN::ROS::Stack"]
            }
          }
        },
        {
          "Effect" : "Allow",
          "Action" : "Update:*",
          "Principal": "*",
          "Resource" : "*"
        }
      ]
    }