|
| 1 | +# Terraform Backend |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +Remote state backend infrastructure for Terraform using AWS S3 and DynamoDB. This module creates the necessary infrastructure to store Terraform state remotely and securely, including state locking to prevent concurrent modifications. |
| 6 | + |
| 7 | +> [!IMPORTANT] |
| 8 | +> This is a foundational component that should be created before other infrastructure resources. This module must be run with local state initially, as it's creating its own backend. |
| 9 | +
|
| 10 | +## Stack |
| 11 | + |
| 12 | +- S3 Bucket (state storage) |
| 13 | +- DynamoDB Table (state locking) |
| 14 | +- Amazon Certificate Manager |
| 15 | + |
| 16 | +### S3 Bucket |
| 17 | +- **Name**: `${service_name}-${stage}-terraform-state` |
| 18 | +- **Versioning**: Enabled to maintain state history |
| 19 | +- **Encryption**: AES256 by default |
| 20 | +- **Public Access**: Completely blocked |
| 21 | +- **Deletion Protection**: Enabled via `prevent_destroy` |
| 22 | + |
| 23 | +### DynamoDB Table |
| 24 | +- **Name**: `${service_name}-${stage}-terraform-state-lock` |
| 25 | +- **Billing Mode**: Pay per request |
| 26 | +- **Hash Key**: `LockID` |
| 27 | +- **Purpose**: State locking concurrency control |
| 28 | + |
| 29 | +## Pricing |
| 30 | + |
| 31 | +In most cases, the price will be near to zero for small projects. |
| 32 | + |
| 33 | +The pricing is based on: |
| 34 | +- S3: Storage ($0.023 per GB) and requests |
| 35 | +- DynamoDB: Pay-per-request pricing ($1.25 per million writes, $0.25 per million reads) |
| 36 | + |
| 37 | +See [AWS S3 Pricing](https://aws.amazon.com/s3/pricing/) and [AWS DynamoDB Pricing](https://aws.amazon.com/dynamodb/pricing/) for more details. |
| 38 | + |
| 39 | +> [!NOTE] |
| 40 | +> For production workloads, monitor your usage. Versioning enabled on S3 will increase storage costs over time. |
| 41 | +
|
| 42 | +## Requirements |
| 43 | + |
| 44 | +- AWS CLI configured |
| 45 | +- Terraform >= 1.0 |
| 46 | +- AWS credentials with permissions for: |
| 47 | + - S3 (CreateBucket, PutBucketPolicy, PutBucketVersioning, etc.) |
| 48 | + - DynamoDB (CreateTable, DescribeTable, etc.) |
| 49 | + |
| 50 | +## Supported variables |
| 51 | + |
| 52 | +| Name | Type | Default | Description | |
| 53 | +| -------------- | -------- | ----------- | ------------------------------------------ | |
| 54 | +| `region` | `string` | `us-east-1` | AWS region where resources will be created | |
| 55 | +| `service_name` | `string` | `cluster` | Service name (used in resource naming) | |
| 56 | +| `stage` | `string` | `dev` | Environment (dev, test, prod, etc.) | |
| 57 | + |
| 58 | +## Usage |
| 59 | + |
| 60 | +### 1. Configure variables |
| 61 | + |
| 62 | +Copy the example file and configure your variables: |
| 63 | + |
| 64 | +```bash |
| 65 | +cp terraform.tfvars.example terraform.tfvars |
| 66 | +``` |
| 67 | + |
| 68 | +Edit the `terraform.tfvars` file: |
| 69 | + |
| 70 | +```hcl |
| 71 | +service_name = "your-service-name" |
| 72 | +stage = "prod" |
| 73 | +``` |
| 74 | + |
| 75 | +### 2. Deploy the backend infrastructure |
| 76 | + |
| 77 | +```bash |
| 78 | +# Initialize Terraform |
| 79 | +terraform init |
| 80 | + |
| 81 | +# Review the plan |
| 82 | +terraform plan |
| 83 | + |
| 84 | +# Apply changes |
| 85 | +terraform apply |
| 86 | +``` |
| 87 | + |
| 88 | +### 3. Configure remote backend in other modules |
| 89 | + |
| 90 | +After creating the infrastructure, configure other modules to use this backend: |
| 91 | + |
| 92 | +```hcl |
| 93 | +terraform { |
| 94 | + backend "s3" { |
| 95 | + bucket = "your-service-name-prod-terraform-state" |
| 96 | + key = "path/to/your/terraform.tfstate" |
| 97 | + region = "us-east-1" |
| 98 | + dynamodb_table = "your-service-name-prod-terraform-state-lock" |
| 99 | + encrypt = true |
| 100 | + } |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +### 4. Migrate existing state (if needed) |
| 105 | + |
| 106 | +If you already have local state and want to migrate to this backend: |
| 107 | + |
| 108 | +```bash |
| 109 | +# 1. Create the backend infrastructure (this module) |
| 110 | +terraform apply |
| 111 | + |
| 112 | +# 2. Add backend configuration to other modules |
| 113 | +# 3. Run migration |
| 114 | +terraform init -migrate-state |
| 115 | +``` |
| 116 | + |
| 117 | +## Outputs |
| 118 | + |
| 119 | +| Name | Description | |
| 120 | +| --------------------- | -------------------------------------------- | |
| 121 | +| `s3_bucket_name` | Name of the S3 bucket | |
| 122 | +| `s3_bucket_arn` | ARN of the S3 bucket | |
| 123 | +| `s3_bucket_region` | Region of the S3 bucket | |
| 124 | +| `dynamodb_table_name` | Name of the DynamoDB table for state locking | |
| 125 | +| `dynamodb_table_arn` | ARN of the DynamoDB table | |
| 126 | + |
| 127 | +## Security |
| 128 | + |
| 129 | +This module implements the following security best practices: |
| 130 | + |
| 131 | +- ✅ **Encryption**: State encrypted at rest (AES256) |
| 132 | +- ✅ **Versioning**: State version history |
| 133 | +- ✅ **Public Access Blocked**: No public access to the bucket |
| 134 | +- ✅ **State Locking**: Prevents concurrent modifications |
| 135 | +- ✅ **Deletion Protection**: Bucket protected against accidental deletion |
| 136 | +- ✅ **Tagging**: Default tags applied for governance |
| 137 | + |
| 138 | +## Troubleshooting |
| 139 | + |
| 140 | +### Permission Errors |
| 141 | +If you receive permission errors, verify that your AWS credentials have the necessary permissions listed in the requirements. |
| 142 | + |
| 143 | +### Name Conflict |
| 144 | +If the S3 bucket already exists, change the `service_name` or `stage` to generate a unique name. |
| 145 | + |
| 146 | +### Corrupted State |
| 147 | +S3 versioning allows you to recover previous versions of the state in case of issues. |
| 148 | + |
| 149 | +### Destroying the Infrastructure |
| 150 | + |
| 151 | +The S3 bucket has deletion protection enabled. To completely destroy the infrastructure: |
| 152 | + |
| 153 | +1. Remove the `prevent_destroy` lifecycle rule from the S3 bucket in `main.tf` |
| 154 | +2. Run `terraform apply` to update the configuration |
| 155 | +3. Run `terraform destroy` |
0 commit comments