Preventing Accidental Deletions: Secure Cloud Management With Terraform

When managing cloud infrastructure using Infrastructure as Code (IaC), one of the biggest challenges is balancing efficiency with safeguards against unintentional actions, such as deleting critical resources. Delete resource protection, in Terraform, enables us to prevent accidental deletions of vital cloud resources, providing an essential layer of security and reliability for cloud infrastructure. 

In this article, we’ll explore how to use the delete resource protection feature in Terraform Open Source (Community Edition), enabling you to safeguard critical cloud resources from accidental deletions efficiently and at no cost. We'll also briefly touch on advanced options — like Sentinel policies and Open Policy Agent (OPA) policies — offered in Terraform's paid plans for additional governance and compliance.

Understanding Delete Resource Protection

Delete resource protection in Terraform is a mechanism that prevents specific resources from being deleted, even if they're marked for deletion in your code. It acts as a failsafe, ensuring that critical infrastructure components aren’t accidentally removed due to a configuration error or misstep during the deployment process.

With delete protection enabled, Terraform will block any attempt to delete a protected resource, generating an error message instead. This feature is especially crucial in production environments where infrastructure reliability and continuity are paramount.

Benefits of Delete Resource Protection

Delete resource protection offers several key benefits:

Implementing Delete Resource Protection in Terraform

In Terraform, delete resource protection can be implemented using the prevent_destroy lifecycle rule within the resource block. Here’s a general example:

Plain Text
 
provider "ibm" {
  ibmcloud_api_key = var.ibmcloud_api_key
  region           = "us-south"
}

resource "ibm_is_instance" "web_server" {
  name            = "web-server-instance"
  profile         = "bx2-2x8"
  zone            = "us-south-1"
  image           = "ibm-centos-7-6-minimal-amd64-1"
  primary_network_interface {
    id    = ibm_is_virtual_network_interface.example.id
    security_groups = ["security_group_id"]
  }

  lifecycle {
    prevent_destroy = true
  }
}


In this example, the prevent_destroy = true line within the lifecycle block prevents Terraform from deleting the web_server instance, even if it’s marked for deletion in future plans.

Using a Variable to Control Delete Protection

In certain scenarios, it may be necessary to temporarily disable delete protection, such as when upgrading or decommissioning a resource. Terraform allows you to dynamically manage delete protection using variables, giving you control over whether resources are protected.

By setting up a variable for delete protection, you can easily toggle prevent_destroy on or off based on the environment or situation:

Plain Text
 
provider "ibm" {
  ibmcloud_api_key = var.ibmcloud_api_key
  region           = "us-south"
}

resource "ibm_is_instance" "web_server" {
  name            = "web-server-instance"
  profile         = "bx2-2x8"
  zone            = "us-south-1"
  image           = "ibm-centos-7-6-minimal-amd64-1"
  primary_network_interface {
    id    = ibm_is_virtual_network_interface.example.id
    security_groups = ["security_group_id"]
  }

  lifecycle {
    prevent_destroy = var.deletion_protection
  }
}


With this setup, you can control delete protection at runtime by setting deletion_protection as a variable in the Terraform apply command.

Disabling Delete Protection Temporarily 

To disable delete protection temporarily, you can run the following command:

terraform apply -var="deletion_protection=false"

This command overrides the deletion_protection variable, setting it to false for this specific run. As a result, the prevent_destroy rule is temporarily disabled, allowing resources that normally have delete protection to be destroyed if necessary. Once the process is complete, you can re-enable delete protection by running:

terraform apply -var="deletion_protection=true"

This flexibility allows you to maintain protection in production environments while granting controlled access to make updates or decommission resources in a safe and manageable way.

Steps for Deleting Specific Resources With Dependencies

Dependency Graph Analysis

Terraform analyzes the entire configuration to determine dependencies using an internal dependency graph. Resources referencing each other directly or via depends_on are included in this graph.

Dependencies are preserved until all dependent resources are removed or modified so that they no longer depend on the resource being deleted.

Delete-Only Specific Resource

If you want to delete only a specific resource (not the entire infrastructure), you can use the terraform destroy -target <resource> command to delete just that resource.

For example, terraform destroy -target=ibm_is_instance.example_instance deletes the example_instance resource without affecting the rest of the infrastructure.

Terraform’s Handling of Dependencies

When targeting a specific resource for deletion, Terraform checks if other resources depend on it.

If other resources depend on this targeted resource, Terraform will block the deletion unless you remove those dependent resources or their dependency.

Deleting Dependent Resources

If the targeted resource is part of a larger dependency chain (e.g., an instance within a subnet that belongs to a VPC), Terraform will require that the resource’s dependencies are satisfied (no other resources rely on it) before deleting.

In practice, this means you may need to delete the resources that depend on the targeted resource first or remove references to it within your Terraform configuration.

Best Practices for Delete Resource Protection

Terraform handles dependencies intelligently, ensuring resources are deleted in the correct order based on the dependency graph. By understanding and managing dependencies carefully, you can safely perform deletions without risking unintended side effects on other resources.

 To ensure delete resource protection is effectively integrated into your infrastructure, consider these best practices:

  1. Enable protection for critical resources only: Apply prevent_destroy to crucial resources, like databases, production servers, and network configurations, while leaving it off for resources that are regularly modified or ephemeral.
  2. Review resource dependencies: Resources with dependencies should be carefully managed. Consider how deleting or retaining certain resources may affect dependent components.
  3. Document protection status: Ensure team members know which resources are protected and why. Documentation can help reduce confusion and prevent accidental overrides.
  4. Use variables for flexibility: If you need flexibility, consider using a variable to toggle prevent_destroy for different environments (e.g., development vs. production)
  5. Plan before deleting: Always run terraform plan before deleting resources to understand the dependency impact.
  6. Test your configurations: Regularly test your Terraform configurations to ensure delete protection is set up correctly and won’t interfere with planned updates.

Using Policies to Prevent Resource Deletion in Terraform

Sentinel policies and Open Policy Agent (OPA) policies provide robust guardrails for enforcing compliance and governance in Terraform. Both Sentinel (used in HashiCorp’s ecosystem) and OPA policies help enforce rules around resource management, including preventing the deletion of critical resources. 

Sentinel Policies for Preventing Resource Deletion in Terraform

Sentinel is a policy-as-code framework by HashiCorp integrated into Terraform Enterprise and Terraform Cloud. Sentinel policies allow you to define custom rules that manage and control infrastructure behavior by enforcing specific conditions before Terraform applies changes. With Sentinel, you can create policies that prevent the deletion of critical resources or types of resources.

A Sentinel policy to prevent resource deletion checks the plan for any destroy actions and restricts them based on defined rules. Here’s an example policy that prevents any deletions:

Plain Text
 
import "tfplan/v2" as tfplan

main = rule {
    all tfplan.resource_changes as resource {
        # Allow deletion only if the resource does not have a `critical` tag
        "delete" not in resource.change.actions or
        (resource.before.tags is set and not ("critical" in resource.before.tags))
    }
}

This policy does the following:

OPA Policies for Preventing Resource Deletion

OPA is an open-source, general-purpose policy engine that can also integrate with Terraform via the OPA provider or directly with CI/CD pipelines. OPA policies are written in Rego, a declarative language, and can enforce rules on Terraform plan or apply commands to control infrastructure actions.

To create an OPA policy that prevents deletion, you need to analyze the Terraform plan to check for any deletion actions. Here’s a simple OPA policy in Rego to block all deletions:

Plain Text
 
deny[msg] {
    some resource  # Declares a variable 'resource' to iterate over input.resource_changes
    input.resource_changes[resource].type == "test_vpc"  # Checks if the resource is a VPC
    input.resource_changes[resource].change.actions[_] == "delete"  # Checks if the action is "delete"
    msg := sprintf("Deletion is not allowed for VPC resource: %v", [input.resource_changes[resource].address])
}


This policy:

Conclusion

Delete resource protection in Terraform is a powerful feature that enhances the security and reliability of your cloud infrastructure, safeguarding critical resources against accidental deletion. Configuring prevent_destroy within your Terraform code helps create resilient, secure infrastructure environments.

By following best practices and thoughtfully managing delete resource protection, you can minimize the risk of service disruptions, protect sensitive data, and foster a stable foundation for your applications and services. Implementing delete resource protection not only mitigates risk but also demonstrates a proactive approach to cloud infrastructure management.

 

 

 

 

Top