Sling Academy
Home/DevOps/Terraform: How to prevent accidental deletion of resources

Terraform: How to prevent accidental deletion of resources

Last updated: February 03, 2024

Introduction

Terraform, a widely used Infrastructure as Code (IaC) tool, offers great flexibility and control over infrastructure provisioning and management. However, this power also brings potential risks; among them is the accidental deletion of critical infrastructure components. This article aims to guide you through various strategies to prevent such mishaps, enhancing your Terraform scripts with safeguards.

To start with, Terraform’s lifecycle management capabilities are fundamental in preventing unintentional modifications or deletions. The lifecycle block within resource definitions is crucial. Let’s explore this feature through examples, progressing from basic usage to more advanced practices.

Understanding Lifecycle Block

The lifecycle block within a Terraform resource definition allows you to customize how changes to the resource are applied. The most relevant attributes for preventing accidental deletion are prevent_destroy, create_before_destroy, and ignore_changes.

resource "aws_instance" "example" {
  ami           = "ami-123456"
  instance_type = "t2.micro"

  lifecycle {
    prevent_destroy = true
  }
}

By setting prevent_destroy = true, Terraform will refuse to delete this resource, even if a terraform destroy command is issued. This safeguards your key infrastructure components against accidental deletion but requires manual adjustment to remove this protection when you intend to delete the resource.

Granular Control with Conditional Expressions

As your Terraform projects grow, you might find the need for more granular control over infrastructure changes. Conditional expressions in conjunction with lifecycle block attributes offer a sophisticated way to manage this. Suppose you want to protect production resources but allow clearing test environments:

variable "environment" {
  description = "The deployment environment"
  type        = "string"
}

resource "aws_instance" "example" {
  ami           = "ami-123456"
  instance_type = "t2.micro"

  lifecycle {
    prevent_destroy = var.environment == "production" ? true : false
  }
}

This configuration ensures that resources in a production environment are safeguarded against accidental deletion, while deployment and testing in other environments remain flexible.

Utilizing Terraform State Locking

Terraform state locking is another essential feature to prevent accidental infrastructure changes. When Terraform modifies your infrastructure, it locks the state file. This mechanism prevents concurrent executions that could lead to conflicts or accidental deletions. Most Terraform backends support state locking. To enable it, specify a backend that supports locking in your Terraform configuration:

terraform {
  backend "s3" {
    bucket         = "your-terraform-state-bucket"
    key            = "path/to/your/terraform/state/file"
    region         = "us-east-1"
    dynamodb_table = "your-terraform-state-lock"
    encrypt        = true
  }
}

This configuration stores the Terraform state in an S3 bucket and uses a DynamoDB table for state locking, providing an additional layer of protection.

Backup Strategies

Besides preventing accidental deletion, having a solid backup strategy for your Terraform state files ensures that you can recover from unintended changes. Regular backups, possibly automated through CI/CD pipelines, can provide peace of mind. Consider using cloud storage services for automated, scheduled backups of your Terraform state files.

Advance Practices

As you become more comfortable with these safety mechanisms, exploring advanced practices becomes essential. Delving into custom provider development or employing external tools for monitoring and enforcing policy as code could offer further protection against accidental deletions or changes.

For instance, employing open-source tools like Terraform Cloud or Enterprise versions, which feature policy as code (via Sentinel) and enhanced state management, could introduce increased guardrails for your infrastructure provisioning processes.

Conclusion

Preventing accidental deletion of resources in Terraform is crucial for managing robust and resilient infrastructure. By strategically utilizing the lifecycle block, employing state locking, maintaining diligent backups, and exploring advanced practices, you can significantly mitigate the risks of unintended changes. Protecting your infrastructure begins with thoughtful Terraform script enhancements and extends into comprehensive infrastructure management strategies.

Next Article: How to use Terraform templates

Previous Article: Using Terraform with Kubernetes: A Practical Guide

Series: Terraform Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide