💾 Archived View for cfdocs.wetterberg.nu › protect-stack-resources.gemini captured on 2023-11-04 at 11:57:17. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-12-03)
-=-=-=-=-=-=-
When you create a stack, all update actions are allowed on all resources. By default, anyone with stack update permissions can update all of the resources in the stack. During an update, some resources might require an interruption or be completely replaced, resulting in new physical IDs or completely new storage. You can prevent stack resources from being unintentionally updated or deleted during a stack update by using a stack policy. A stack policy is a JSON document that defines the update actions that can be performed on designated resources.
After you set a stack policy, all of the resources in the stack are protected by default. To allow updates on specific resources, you specify an explicit `Allow` statement for those resources in your stack policy. You can define only one stack policy per stack, but, you can protect multiple resources within a single policy. A stack policy applies to all AWS CloudFormation users who attempt to update the stack. You can't associate different stack policies with different users.
A stack policy applies only during stack updates. It doesn't provide access controls like an AWS Identity and Access Management (IAM) policy. Use a stack policy only as a fail-safe mechanism to prevent accidental updates to specific stack resources. To control access to AWS resources or actions, use IAM.
The following example stack policy prevents updates to the `ProductionDatabase` resource:
{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" }, { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "LogicalResourceId/ProductionDatabase" } ] }
When you set a stack policy, all resources are protected by default. To allow updates on all resources, we add an `Allow` statement that allows all actions on all resources. Although the `Allow` statement specifies all resources, the explicit `Deny` statement overrides it for the resource with the `ProductionDatabase` logical ID. This `Deny` statement prevents all update actions, such as replacement or deletion, on the `ProductionDatabase` resource.
The `Principal` element is required, but supports only the wild card (`*`), which means that the statement applies to all principals.
During a stack update, AWS CloudFormation automatically updates resources that depend on other updated resources. For example, AWS CloudFormation updates a resource that references an updated resource. AWS CloudFormation makes no physical changes, such as the resource's ID, to automatically updated resources, but if a stack policy is associated with those resources, you must have permission to update them.
When you create a stack, no stack policy is set, so all update actions are allowed on all resources. To protect stack resources from update actions, define a stack policy and then set it on your stack. A stack policy is a JSON document that defines the AWS CloudFormation stack update actions that AWS CloudFormation users can perform and the resources that the actions apply to. You set the stack policy when you create a stack, by specifying a text file that contains your stack policy or typing it out. When you set a stack policy on your stack, any update not explicitly allowed is denied by default.
You define a stack policy with five elements: `Effect`, `Action`, `Principal`, `Resource`, and `Condition`. The following pseudo code shows stack policy syntax.
{ "Statement" : [ { "Effect" : "Deny_or_Allow", "Action" : "update_actions", "Principal" : "*", "Resource" : "LogicalResourceId/resource_logical_ID", "Condition" : { "StringEquals_or_StringLike" : { "ResourceType" : [resource_type, ...] } } }Â Â ] }
`Effect`
Determines whether the actions that you specify are denied or allowed on the resource(s) that you specify. You can specify only `Deny` or `Allow`, such as:
"Effect" : "Deny"
If a stack policy includes overlapping statements (both allowing and denying updates on a resource), a `Deny` statement always overrides an `Allow` statement. To ensure that a resource is protected, use a `Deny` statement for that resource.
Action
Specifies the update actions that are denied or allowed:
Update:Modify
Specifies update actions during which resources might experience no interruptions or some interruptions while changes are being applied. All resources maintain their physical IDs.
Update:Replace
Specifies update actions during which resources are recreated. AWS CloudFormation creates a new resource with the specified updates and then deletes the old resource. Because the resource is recreated, the physical ID of the new resource might be different.
Update:Delete
Specifies update actions during which resources are removed. Updates that completely remove resources from a stack template require this action.
Update:*
Specifies all update actions. The asterisk is a wild card that represents all update actions.
The following example shows how to specify just the replace and delete actions:
"Action"Â : ["Update:Replace", "Update:Delete"]
To allow all update actions except for one, use `NotAction`. For example, to allow all update actions except for `Update:Delete`, use `NotAction`, as shown in this example:
{ "Statement" : [ { "Effect" : "Allow", "NotAction" : "Update:Delete", "Principal": "*", "Resource" : "*" } ] }
For more information about stack updates, see AWS CloudFormation stack updates.
AWS CloudFormation stack updates
Principal
The `Principal` element specifies the entity that the policy applies to. This element is required but supports only the wild card (`*`), which means that the policy applies to all principals.
Resource
Specifies the logical IDs of the resources that the policy applies to. To specify types of resources, use the `Condition` element.
To specify a single resource, use its logical ID. For example:
"Resource" : ["LogicalResourceId/myEC2instance"]
You can use a wild card with logical IDs. For example, if you use a common logical ID prefix for all related resources, you can specify all of them with a wild card:
"Resource" : ["LogicalResourceId/CriticalResource*"]
You can also use a `Not` element with resources. For example, to allow updates to all resources except for one, use a `NotResource` element to protect that resource:
{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "NotResource" : "LogicalResourceId/ProductionDatabase" } ] }
When you set a stack policy, any update not explicitly allowed is denied. By allowing updates to all resources except for the `ProductionDatabase` resource, you deny updates to the `ProductionDatabase` resource.
Conditions
Specifies the resource type that the policy applies to. To specify the logical IDs of specific resources, use the `Resource` element.
You can specify a resource type, such as all EC2 and RDS DB instances, as shown in the following example:
{ "Statement" : [ { "Effect" : "Deny", "Principal" : "*", "Action" : "Update:*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::EC2::Instance", "AWS::RDS::DBInstance"] } } }, { "Effect" : "Allow", "Principal" : "*", "Action" : "Update:*", "Resource" : "*" } ] }
The `Allow` statement grants update permissions to all resources and the `Deny` statement denies updates to EC2 and RDS DB instances. The `Deny` statement always overrides allow actions.
You can use a wild card with resource types. For example, you can deny update permissions to all Amazon EC2 resources—such as instances, security groups, and subnets—by using a wild card, as shown in the following example:
"Condition" : { "StringLike" : { "ResourceType" : ["AWS::EC2::*"] } }
You must use the `StringLike` condition when you use wild cards.
You can use the console or AWS CLI to apply a stack policy when you create a stack. You can also use the AWS CLI to apply a stack policy to an existing stack. After you apply a stack policy, you can't remove it from the stack, but you can use the AWS CLI to modify it.
Stack policies apply to all AWS CloudFormation users who attempt to update the stack. You can't associate different stack policies with different users.
For information about writing stack policies, see Defining a stack policy.
https://console.aws.amazon.com/cloudformation
To update protected resources, create a temporary policy that overrides the stack policy and allows updates on those resources. Specify the override policy when you update the stack. The override policy doesn't permanently change the stack policy.
To update protected resources, you must have permission to use the AWS CloudFormation `SetStackPolicy` action. For information about setting AWS CloudFormation permissions, see Controlling access with AWS Identity and Access Management.
Controlling access with AWS Identity and Access Management
During a stack update, AWS CloudFormation automatically updates resources that depend on other updated resources. For example, AWS CloudFormation updates a resource that references an updated resource. AWS CloudFormation makes no physical changes, such as the resources' ID, to automatically updated resources, but if a stack policy is associated with those resources, you must have permission to update them.
https://console.aws.amazon.com/cloudformation
Managing objects in a versioning-enabled bucket
Do not embed credentials in your templates
AWS CloudFormation applies the override policy only during this update. The override policy doesn't permanently change the stack policy. To modify a stack policy, see Modifying a stack policy .
Controlling access with AWS Identity and Access Management
Updating stacks using change sets
To protect additional resources or to remove protection from resources, modify the stack policy. For example, when you add a database that you want to protect to your stack, add a `Deny` statement for that database to the stack policy. To modify the policy, you must have permission to use the `SetStackPolicy` action.
Use the AWS CLI to modify stack policies.
You can't delete a stack policy. To remove all protection from all resources, you modify the policy to explicitly allow all actions on all resources. The following policy allows all updates on all resources:
{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" }Â Â ] }
The following example policies show how to prevent updates to all stack resources and to specific resources, and prevent specific types of updates.
To prevent updates to all stack resources, the following policy specifies a `Deny` statement for all update actions on all resources.
{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*" }Â Â ] }
The following policy denies all update actions on the database with the `MyDatabase` logical ID. It allows all update actions on all other stack resources with an `Allow` statement. The `Allow` statement doesn't apply to the `MyDatabase` resource because the `Deny` statement always overrides allow actions.
{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "LogicalResourceId/MyDatabase" }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }
You can achieve the same result as the previous example by using a default denial. When you set a stack policy, AWS CloudFormation denies any update that is not explicitly allowed. The following policy allows updates to all resources except for the `ProductionDatabase` resource, which is denied by default.
{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "NotResource" : "LogicalResourceId/ProductionDatabase" } ] }
There is risk in using a default denial. If you have an `Allow` statement elsewhere in the policy (such as an `Allow` statement that uses a wildcard), you might unknowingly grant update permission to resources that you don't intend to. Because an explicit denial overrides any allow actions, you can ensure that a resource is protected by using a `Deny` statement.
The following policy denies all update actions on the RDS DB instance resource type. It allows all update actions on all other stack resources with an `Allow` statement. The `Allow` statement doesn't apply to the RDS DB instance resources because a `Deny` statement always overrides allow actions.
{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::RDS::DBInstance"] } } }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }
The following policy denies updates that would cause a replacement of the instance with the `MyInstance` logical ID. It allows all update actions on all other stack resources with an `Allow` statement. The `Allow` statement doesn't apply to the `MyInstance` resource because the `Deny` statement always overrides allow actions.
{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:Replace", "Principal": "*", "Resource" : "LogicalResourceId/MyInstance" }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }
The following policy denies all update actions on the AWS CloudFormation stack resource type (nested stacks). It allows all update actions on all other stack resources with an `Allow` statement. The `Allow` statement doesn't apply to the AWS CloudFormationstack resources because the `Deny` statement always overrides allow actions.
{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::CloudFormation::Stack"] } } }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }