Skip to content

Prevent destroying kms resources where an SCP disables kms deletion to protect against ransomware #39

@nitrocode

Description

@nitrocode

Is your request related to a new offering from AWS?

No

Is your request related to a problem? Please describe.

Yes

Terraform directories need to be applied and destroyed from time to time. Due to ransomware concerns, KMS deletions are now getting denied via an SCP

See https://github.com/primeharbor/aws-organizational-policies/blob/main/Policies/KMS-KeyProtection.md

We'd like to continue to use upstream modules like this kms module but we're finding it difficult.

Describe the solution you'd like.

Since terraform does not support variables in the lifecycle, a duplicate resource would be necessary to allow us to set

resource "aws_kms_key" "this_prevent_destroy" {
  count = var.create && !var.create_external && !var.create_replica && !var.create_replica_external && var.prevent_destroy ? 1 : 0

  # ...

  lifecycle {
    prevent_destroy = true
  }
}

https://developer.hashicorp.com/terraform/tutorials/state/resource-lifecycle#prevent-resource-deletion

This can be a pain to maintain so I'd propose a separate file for the non-lifecycle resources and the lifecycle-resources that are 1:1 with the only difference of the var.prevent_destroy in the count logic and the lifecycle block so if any changes are made, they can be easily diff'ed.

An automation would be fairly simple via hcledit too, if preferable.

Describe alternatives you've considered.

Alternative 1: Removing the key from state by command line before doing a destroy

terraform state rm module.kms.aws_kms_key.this
# ...

This is a bit cumbersome for developers who rely on CICD which may not have this ability.

Alternative 2: Using removed blocks before doing a destroy

Developers could add a temporary migrations.tf file containing removed blocks. I say temporary because we use workspaces and they may need to only remove it from a single workspace and not all workspaces.

removed {
  from = module.kms.aws_kms_key.this
}

# ...

Alternative 3: Use a special tag in the kms resources to allow deletion

This can be done in the SCP using a condition like so

    condition {
      test     = "StringNotEquals"
      variable = "kms:ResourceTag/security-exempt"
      values   = ["true"]
    }

However, this is far from ideal since this will end up resulting in deleted kms keys which, if used to encrypt data, once they are gone, we lose access to the encrypted data.

Alternative 4: Fork

Fork this module and the eks module.

This is the worst alternative but writing here just to have all the options in one place.

Additional context

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions