Skip to content

State files

Store state remotely

Storing Terraform state remotely provides greater security, scalability, and flexibility compared to storing it locally. AWS provides several options for remote state storage, including Amazon S3, DynamoDB, and Terraform Cloud.

To implement the best practices for Terraform state storage, here is an example configuration for storing state in an S3 bucket with versioning enabled and locking support using the DynamoDB backend:

terraform {
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "terraform.tfstate"
    region = "us-east-1"
    dynamodb_table = "my-terraform-state-lock"
    encrypt = true
    versioning = {
      enabled = true
    }
  }
}

This configuration stores the Terraform state file in an S3 bucket named "my-terraform-state-bucket" located in the "us-east-1" region. The state file is named "terraform.tfstate". The "dynamodb_table" parameter specifies the name of the DynamoDB table to use for locking. Versioning is enabled for the state file and encryption is also enabled.

This is just an example and the configuration parameters will vary depending on your specific use case and requirements.

Isolate state per environment

It's important to isolate state by environment, such as dev, staging, and production. This can help prevent accidental changes or overwriting of state.

Creating a new Terraform workspace can be done through a CI/CD pipeline by using the terraform workspace new command in your pipeline script.

For example, you could define a pipeline stage that creates a new workspace for each environment, like this:

stages:
  - name: create-workspaces
    steps:
      - name: create-dev-workspace
        command: terraform workspace new dev
      - name: create-staging-workspace
        command: terraform workspace new staging
      - name: create-prod-workspace
        command: terraform workspace new prod

This pipeline stage would run the terraform workspace new command for each environment, creating a new workspace and state file in the S3 bucket and DynamoDB table specified in your backend configuration for each environment.

Once the workspaces are created, you can use the terraform workspace select command to switch between them and apply changes to the correct environment.

It's important to note that you should ensure that only authorized users have access to create new workspaces and that your backend configuration is set up correctly to prevent unauthorized access to your infrastructure state.

Enable versioning and backups

Enabling versioning and backups for state files can help ensure data integrity and provide a recovery mechanism in case of accidental deletions or corruption.

To enable versioning and backups for Terraform state in AWS, you can use Amazon S3 and configure versioning for your S3 bucket. Here are the steps to enable versioning and backups for Terraform state in AWS:

  • Create an S3 bucket to store your Terraform state file.
  • Enable versioning for the S3 bucket by adding the following configuration to your bucket policy:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EnableVersioning",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetBucketVersioning",
                "s3:PutBucketVersioning"
            ],
            "Resource": "arn:aws:s3:::my-terraform-state-bucket"
        }
    ]
}
  • Verify that versioning is enabled for your S3 bucket by running the following command:
aws s3api get-bucket-versioning --bucket my-terraform-state-bucket

This will return the versioning configuration for your S3 bucket.

With versioning enabled, you can now view and restore previous versions of your Terraform state file if needed.

To enable backups, you can configure lifecycle rules for your S3 bucket to automatically archive or delete old versions of your Terraform state file.

Use a backend that supports locking

When multiple users or processes are working with the same Terraform state, it's important to use a backend that supports locking to prevent conflicts and data corruption.

To use a backend that supports locking in AWS, you can use the DynamoDB backend with the S3 backend for remote state storage. Here are the steps:

  • Create a DynamoDB table to use for locking
  • Verify that locking is working by running a terraform apply command and checking that the lock is acquired and released correctly

Use CI/CD pipelines

Incorporating Terraform into a CI/CD pipeline can help ensure that infrastructure changes are tested, reviewed, and deployed in a controlled and consistent manner.