# Terraform Backend Setup Guide

## Overview

This guide explains how to configure Terraform backend for state management using Azure Storage.

## Prerequisites

- Azure CLI installed and configured
- Terraform >= 1.0
- Azure subscription with appropriate permissions
- Storage account (or create one)

## Step 1: Create Storage Account

### Option 1: Using Azure CLI

```bash
# Set variables
RESOURCE_GROUP="tfstate-rg"
STORAGE_ACCOUNT="tfstate$(openssl rand -hex 4)"
CONTAINER_NAME="tfstate"
LOCATION="eastus"

# Create resource group
az group create --name $RESOURCE_GROUP --location $LOCATION

# Create storage account
az storage account create \
  --resource-group $RESOURCE_GROUP \
  --name $STORAGE_ACCOUNT \
  --sku Standard_LRS \
  --kind StorageV2 \
  --location $LOCATION

# Create container
az storage container create \
  --name $CONTAINER_NAME \
  --account-name $STORAGE_ACCOUNT

# Get access key
ACCESS_KEY=$(az storage account keys list \
  --resource-group $RESOURCE_GROUP \
  --account-name $STORAGE_ACCOUNT \
  --query "[0].value" -o tsv)

echo "Storage Account: $STORAGE_ACCOUNT"
echo "Container: $CONTAINER_NAME"
echo "Access Key: $ACCESS_KEY"
```

### Option 2: Using Terraform

```bash
cd terraform/backend-setup
terraform init
terraform apply
```

## Step 2: Configure Backend

### Option 1: Environment Variables

```bash
export ARM_STORAGE_ACCOUNT_NAME="tfstate<your-random>"
export ARM_CONTAINER_NAME="tfstate"
export ARM_RESOURCE_GROUP_NAME="tfstate-rg"
export ARM_ACCESS_KEY="<your-access-key>"
```

### Option 2: Backend Config File

Create `terraform/backend.hcl`:

```hcl
resource_group_name  = "tfstate-rg"
storage_account_name = "tfstate<random>"
container_name       = "tfstate"
key                  = "defi-oracle-mainnet.terraform.tfstate"
```

Then initialize:

```bash
terraform init -backend-config=backend.hcl
```

### Option 3: Command Line

```bash
terraform init \
  -backend-config="resource_group_name=tfstate-rg" \
  -backend-config="storage_account_name=tfstate<random>" \
  -backend-config="container_name=tfstate" \
  -backend-config="key=defi-oracle-mainnet.terraform.tfstate" \
  -backend-config="access_key=<your-access-key>"
```

## Step 3: Update terraform/main.tf

Uncomment the backend configuration in `terraform/main.tf`:

```hcl
terraform {
  backend "azurerm" {
    resource_group_name  = "tfstate-rg"
    storage_account_name = "tfstate<random>"
    container_name       = "tfstate"
    key                  = "defi-oracle-mainnet.terraform.tfstate"
  }
}
```

## Step 4: Initialize Terraform

```bash
cd terraform
terraform init
```

## Step 5: Verify Backend

```bash
# Check backend configuration
terraform show -backend-config

# List state
terraform state list
```

## Security Best Practices

### 1. Use Azure Key Vault

Store access keys in Azure Key Vault:

```bash
# Store access key in Key Vault
az keyvault secret set \
  --vault-name <key-vault-name> \
  --name "terraform-backend-key" \
  --value $ACCESS_KEY
```

Reference in Terraform:

```hcl
data "azurerm_key_vault_secret" "backend_key" {
  name         = "terraform-backend-key"
  key_vault_id = azurerm_key_vault.main.id
}

terraform {
  backend "azurerm" {
    # Use Key Vault for access key
    access_key = data.azurerm_key_vault_secret.backend_key.value
  }
}
```

### 2. Enable Storage Account Security

- Enable soft delete
- Enable versioning
- Restrict network access
- Enable encryption at rest
- Use managed identity when possible

### 3. State Locking

Terraform automatically uses blob leasing for state locking. Ensure:

- Storage account supports blob leasing
- Network access allows Terraform to access storage

## Troubleshooting

### Backend Initialization Failed

**Error**: "Failed to get existing workspaces"

**Solution**:
1. Verify storage account exists
2. Check access key is correct
3. Verify container exists
4. Check network access rules

### State Lock Error

**Error**: "Error acquiring the state lock"

**Solution**:
1. Check if another Terraform process is running
2. Manually release lock if process crashed:
   ```bash
   az storage blob lease break \
     --account-name $STORAGE_ACCOUNT \
     --container-name $CONTAINER_NAME \
     --blob-name "defi-oracle-mainnet.terraform.tfstate"
   ```

### Access Denied

**Error**: "Access denied to storage account"

**Solution**:
1. Verify access key is correct
2. Check storage account firewall rules
3. Verify network access
4. Check RBAC permissions

## Migration

### Migrate from Local to Remote Backend

```bash
# Initialize with backend
terraform init -migrate-state

# Verify migration
terraform state list
```

### Migrate Between Backends

```bash
# Update backend configuration
terraform init -migrate-state -backend-config=backend.hcl
```

## References

- [Terraform Azure Backend](https://www.terraform.io/docs/language/settings/backends/azurerm.html)
- [Azure Storage Documentation](https://docs.microsoft.com/azure/storage/)
- [Terraform State Management](https://www.terraform.io/docs/language/state/index.html)

