Help! How do I set DeletionPolicy to Retain for production only?
Tags: aws, cdk, sam, serverless
Published: 2023-10-06 17:26:42

---
title: Help! How do I set DeletionPolicy to Retain for production only?
published: true
date: 2023-10-06 12:24:38 UTC
tags: AWS,CDK,SAM,Serverless
canonical_url: https://theburningmonk.com/2023/10/help-how-do-i-set-deletionpolicy-to-retain-for-production-only/
---

It’s a good practice to use CloudFormation’s `DeletionPolicy` to protect stateful resources such as DynamoDB tables or RDS databases from accidental deletions. Such as when someone accidentally deletes a CloudFormation stack!

As I [discussed previously](https://dev.to/theburningmonk/this-is-why-you-should-keep-stateful-and-stateless-resources-together-4bg3-temp-slug-3527587) [1], this is a much better way to guard against these accidental data losses than separating stateful and stateless resources into different stacks. After all, how we think about infrastructure vs. code [needs to evolve in the serverless era](https://dev.to/aws-heroes/are-we-getting-infrastructure-all-wrong-in-the-serverless-era-4kh3) [2]. That separation is no longer so clear-cut.

### The problem with DeletionPolicy

But using `DeletionPolicy` on all your stateful resources causes friction with another common practice in serverless development – the use of [ephemeral (or temporary) environments](https://www.youtube.com/watch?v=JO0arpbkh5w) [3].

If you set `DeletionPolicy` to `retain` on all your stateful resources, then they will all linger when you delete the temporary environment.

In fact, you only need to use `DeletionPolicy` in production. That’s the only environment where it’s necessary.

So, how do we do that?

### The CDK solution

CDK gives you the full power of a general-purpose programming language ([even though it’s often needed](https://dev.to/aws-heroes/are-you-ready-for-this-top-5-earth-shattering-pros-and-cons-of-aws-cdk-5941) [4]). So it’s trivial to do this in a CDK application:

1. Pass the environment name as either a CloudFormation parameter or context variable.
2. Set the `removalPolicy` inside an `if` block like this:

```
if (environment === 'prod') {
  myTable.removalPolicy = cdk.RemovalPolicy.RETAIN
}
```

### The Serverless framework solution

The easiest way to do this with the Serverless framework is to use the `serverless-plugin-ifelse` plugin.

Once you have installed the plugin as a dev dependency, you can use it to remove the `DeletionPolicy` on stateful resources like this:

```
plugins:
  - serverless-plugin-ifelse

custom:
  serverlessIfElse:
    - If: '"${sls:stage}" != "prod"'
      Exclude:
        - resources.Resources.MyTable.DeletionPolicy

resources:
  Resources:
    MyTable:
      Type: AWS::DynamoDB::Table
      DeletionPolicy: Retain
      Properties:
        ...
```

Notice that `DeletionPolicy` is enabled by default and is removed if the current stage (i.e. environment name) is not `prod`?

This is defensive coding. So that if I get anything wrong, the worst that can happen is I have to manually delete the table from temporary environments.

With the reverse approach (i.e. add `DeletionPolicy` only for the `prod` stage), the worst-case scenario is far worse.

If you want to see this solution in action, then check out [this repo](https://github.com/theburningmonk/conditional-deletionpolicy-demo) [5].

### SAM / CloudFormation solution

For SAM or CloudFormation, this is the best solution I have found:

1. Add an `Environment` CloudFormation Parameter to your template.
2. Add a map of `DeletionPolicy` value to use for each environment.
3. Use the `Fn:FindInMap` intrinsic function to find the `DeletionPolicy` value to use for the current environment.

Something like this:

```
Parameters:
  Environment:
    Type: String
    Default: dev
    Description: Environment name, e.g. dev, test, prod

Mappings:
  DeletionPolicyMap: 
   dev: 
     value: Delete
   prod: 
     value: Retain

Resources:
  MyTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: !FindInMap [ DeletionPolicyMap, !Ref Environment, value ]
    Properties:
      ...
```

This solution is not ideal because it requires the environment names to be explicitly configured. You have to update the `DeletionPolicyMap` every time you create a new environment.

As such, it doesn’t work well with ephemeral environments where environment names are usually dynamic. If you know of a better way to do this with SAM and CloudFormation, please let me know!

### DynamoDB DeletionProtectionEnabled attribute

I have used DynamoDB in the examples above. But it’s worth pointing out that `DeletionPolicy` is actually not the most effective protection against data loss for DynamoDB.

For starters, it doesn’t guard against someone deleting a DynamoDB table in the console or programmatically through the AWS CLI or SDK.

Fortunately, DynamoDB also has the `DeletionProtectionEnabled` [6] attribute. When enabled, it protects the table from accidental deletion by any user or process.

Additionally, DynamoDB offers other protection against data loss, such as point-in-time recovery and the ability to export data to S3.

Having said that, `DeletionPolicy` is still a very useful tool for other services such as S3, EventBridge, SQS, SNS and so on.

### Shout out to Hala

I want to give a shout-out to _Hala Al Aali_ for asking me about this in the [Testing Serverless Architectures](https://testserverlessapps.com/?utm_campaign=conditional-deletionpolicy&utm_source=blog&utm_medium=link) [7] course’s forum.

It’s a common problem that many students have come across. I hope this article has helped you. If you want to learn more about building serverless applications for the real world, check out my upcoming [workshops](https://productionreadyserverless.com/?utm_campaign=conditional-deletionpolicy&utm_source=blog&utm_medium=link) [8].

### Links

[1] [This is why you should keep stateful and stateless resources together](https://dev.to/theburningmonk/this-is-why-you-should-keep-stateful-and-stateless-resources-together-4bg3-temp-slug-3527587)

[2] [Are we getting infrastructure all wrong in the Serverless era?](https://dev.to/aws-heroes/are-we-getting-infrastructure-all-wrong-in-the-serverless-era-4kh3)

[3] [Serverless Ephemeral (Temporary) Environments Explained](https://www.youtube.com/watch?v=JO0arpbkh5w)

[4] [Are You Ready for This? Top 5 Earth-Shattering Pros and Cons of AWS CDK](https://dev.to/aws-heroes/are-you-ready-for-this-top-5-earth-shattering-pros-and-cons-of-aws-cdk-5941)

[5] [github.com/theburningmonk/conditional-deletionpolicy-demo](https://github.com/theburningmonk/conditional-deletionpolicy-demo)

[6] [DynamoDB’s DeletionProtectionEnabled attribute](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html#cfn-dynamodb-table-deletionprotectionenabled)

[7] [Testing Serverless Architectures course](https://testserverlessapps.com/?utm_campaign=conditional-deletionpolicy&utm_source=blog&utm_medium=link)

[8] [Production-Ready Serverless workshop](https://productionreadyserverless.com/?utm_campaign=conditional-deletionpolicy&utm_source=blog&utm_medium=link)

The post [Help! How do I set DeletionPolicy to Retain for production only?](https://theburningmonk.com/2023/10/help-how-do-i-set-deletionpolicy-to-retain-for-production-only/) appeared first on [theburningmonk.com](https://theburningmonk.com).