237 lines
4.9 KiB
Markdown
237 lines
4.9 KiB
Markdown
|
|
# 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)
|
||
|
|
|