100 Days of Red Team

100 Days of Red Team

Share this post

100 Days of Red Team
100 Days of Red Team
Terraform Fundamentals - Backends
User's avatar
Discover more from 100 Days of Red Team
Learn red team concepts, tools, techniques and tradecraft with me, one day at a time.
Already have an account? Sign in

Terraform Fundamentals - Backends

Learn how to configure and use Terraform backends such as S3 and DynamoDB with encryption and state locking enabled.

Uday Mittal's avatar
Uday Mittal
May 07, 2025
1

Share this post

100 Days of Red Team
100 Days of Red Team
Terraform Fundamentals - Backends
Share

One of the most important aspects of working with Terraform is understanding where and how the Terraform state is stored. This is the job of a backend.

In simple terms, a backend in Terraform is the mechanism that determines where the state file is located and how it is loaded. Every Terraform project uses a backend by default, many don't realize it because Terraform silently uses the local backend unless another is specified. That means the state file is saved to local machine as terraform.tfstate. This works fine for learning and small experiments, but it quickly becomes risky and unmanageable in real-world or team-based infrastructure deployments.

Thanks for reading 100 Days of Red Team! Subscribe for free to receive new posts and support my work.

Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.

Backends are configured using a dedicated block within the terraform configuration. For example, to use AWS S3 as a backend, a typical configuration would look like this:

terraform {
  backend "s3" {
    bucket         = "redteam-terraform-state"
    key            = "global/s3/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "redteam-terraform-locks"
    encrypt        = true
  }
}

Note: Terraform must already have access to the backend resources such as S3, DynamoDB etc. when it initializes. These can be setup manually or via Terraform as a separate project.

After declaring this configuration, it must be initialized with terraform init, which connects Terraform to the specified backend and migrates any existing state if necessary. Once this is done, Terraform will read and write state to that remote location, ensuring that every change is recorded and accessible from anywhere—an essential feature for team collaboration and consistency.

Note: When using a remote backend like S3, Terraform will create a file named .terraform/terraform.tfstate locally — but this is not the real state file. Instead, it stores metadata about the backend configuration (such as the S3 bucket, region, key, and lock table). The actual state of the infrastructure — including all deployed resources — is stored in the remote S3 location defined in your backend block.

If you notice in the above example, I have also used dynamodb_table. This is because remote backends also introduce the concept of state locking.

State locking is a mechanism that prevents multiple people or processes from making changes to the same Terraform state file at the same time. When someone runs a Terraform command like apply, the state is locked, meaning no one else can run conflicting operations until it's finished. Without state locking, if two users try to update the infrastructure simultaneously, they could overwrite each other's changes or corrupt the state file — which can break the entire environment.

We can use DynamoDB for locking when configured with a remote backend like S3. It creates a temporary lock entry before making changes and deletes it afterward. This simple safety check ensures that changes to infrastructure are made one at a time, reducing the risk of conflicts or outages. Without this, we could end up with race conditions or corrupted state files.

Visualization of how Terraform works with remote backend (AWS S3 and DynamoDB in this case)

The choice of backend also impacts security. When using local state, anyone with access to the machine can view or modify the state file, which can contain sensitive data like passwords, cloud credentials, or generated secrets. Remote backends like S3 offer encryption at rest and access control via IAM, which means only authorized users and services can view or modify the state. It's good practice to enable server-side encryption (encrypt = true), use private buckets, and apply least-privilege IAM policies.

Note: Setting encrypt = true in backend configuration enables server-side encryption (SSE-S3) for the Terraform state file in S3. However, when viewing the file in the S3 console or downloading it, you may still see the contents in plain text. This is expected — AWS automatically decrypts the file for authorized users. If stricter controls are needed, consider enabling SSE-KMS with a custom KMS key for fine-grained access and audit logging.

From a red team perspective, backends are a double-edged sword. On one hand, using a remote backend like S3 with locking makes operations safer, more secure, and auditable. On the other hand, if the backend itself is misconfigured or compromised, it becomes a single point of failure—or opportunity. For example, if an attacker gains access to an unprotected S3 bucket containing state files, they might extract credentials or environment structure details that could aid in lateral movement or privilege escalation. Similarly, a misconfigured DynamoDB lock table could allow for simultaneous execution, breaking the expected behavior of the infrastructure deployment.

For red team operators building and tearing down cloud infrastructure for operations, using remote backends is often the right balance of scalability, safety, and control. It allows for multiple campaign environments to be managed reliably. When paired with Terraform workspaces, remote backends allow for environment-specific state management without duplicating code.

Here is the Terraform Hello World project configured to use AWS S3 and DynamoDB. This project also includes a separate Terraform project (bootstrap-backend) to provision the required backend services, S3 and DynamoDB.

Following permissions need to be added to the TerraformEC2Access IAM policy before using the above mentioned projects:

  • s3:PutBucketTagging

    dynamodb:CreateTable

    s3:PutBucketVersioning

    dynamodb:TagResource

    dynamodb:DescribeTable

    s3:PutEncryptionConfiguration

    dynamodb:DescribeTimeToLive

    dynamodb:DescribeContinuousBackups

    dynamodb:ListTagsOfResource

    dynamodb:DeleteTable

    dynamodb:PutItem

    dynamodb:GetItem

    dynamodb:DeleteItem

terraform.state file stored in S3
State locking implemented using DynamoDB
TL;DR
- Terraform backends determine where and how Terraform stores its state file. - - By default, Terraform uses a local backend, but for team collaboration and long-term infrastructure reliability, remote backends like AWS S3 are recommended. 
- Remote backends support features like encryption, access control, and state locking via DynamoDB.
- State locking is a mechanism that prevents multiple people or processes from making changes to the same Terraform state file at the same time.

Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.

Thanks for reading 100 Days of Red Team! Subscribe for free to receive new posts and support my work.

John Grageda's avatar
1 Like
1

Share this post

100 Days of Red Team
100 Days of Red Team
Terraform Fundamentals - Backends
Share

Discussion about this post

User's avatar
Using Havoc C2 to bypass UAC
Demonstration of couple of UAC bypass methods using Havoc C2.
Feb 16 â€¢ 
Uday Mittal
1

Share this post

100 Days of Red Team
100 Days of Red Team
Using Havoc C2 to bypass UAC
Let's write a Beacon Object File for Havoc C2 - Part 1
Learn how to use Windows APIs in a Beacon Object File (BOF).
Feb 27 â€¢ 
Uday Mittal
2

Share this post

100 Days of Red Team
100 Days of Red Team
Let's write a Beacon Object File for Havoc C2 - Part 1
Red Team Infrastructure - Deploying Havoc C2 via Terraform
Learn how to deploy Havoc C2 (team server and client) in AWS via Terraform.
May 17 â€¢ 
Uday Mittal
2

Share this post

100 Days of Red Team
100 Days of Red Team
Red Team Infrastructure - Deploying Havoc C2 via Terraform

Ready for more?

© 2025 Uday Mittal
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share

Create your profile

User's avatar

Only paid subscribers can comment on this post

Already a paid subscriber? Sign in

Check your email

For your security, we need to re-authenticate you.

Click the link we sent to , or click here to sign in.