Preventing Accidental Deletions: Secure Cloud Management With Terraform
This is a quick guide to prevent accidental deletions in cloud infrastructure in Terraform, secure critical resources, and maintain a stable environment.
Join the DZone community and get the full member experience.
Join For FreeWhen 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:
- Prevention of accidental deletions: Prevents inadvertent deletion of critical resources, such as databases, virtual machines, or networking components.
- Enhanced security: Maintains the availability of essential services, reducing the risk of downtime due to configuration changes.
- Operational efficiency: Minimizes disruptions, enabling teams to focus on building and scaling rather than recovering deleted resources.
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:
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:
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:
- 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. - Review resource dependencies: Resources with dependencies should be carefully managed. Consider how deleting or retaining certain resources may affect dependent components.
- Document protection status: Ensure team members know which resources are protected and why. Documentation can help reduce confusion and prevent accidental overrides.
- Use variables for flexibility: If you need flexibility, consider using a variable to toggle
prevent_destroy
for different environments (e.g., development vs. production) - Plan before deleting: Always run terraform plan before deleting resources to understand the dependency impact.
- 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:
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:
- Checks for deletion: Inspect the Terraform plan for any resources marked for deletion.
- Blocks apply: If any resources are marked for deletion, the policy fails, preventing the Terraform plan from being applied.
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:
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:
- Inspects resource changes: It scans
input.resource_changes
for any deletion actions. - Denies apply if deletion is found: If any resource has a deletion action, the policy denies the apply and outputs a message indicating the resource marked for deletion.
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.
Opinions expressed by DZone contributors are their own.
Comments