feat: implement naming convention, deployment automation, and infrastructure updates
- Add comprehensive naming convention (provider-region-resource-env-purpose) - Implement Terraform locals for centralized naming - Update all Terraform resources to use new naming convention - Create deployment automation framework (18 phase scripts) - Add Azure setup scripts (provider registration, quota checks) - Update deployment scripts config with naming functions - Create complete deployment documentation (guide, steps, quick reference) - Add frontend portal implementations (public and internal) - Add UI component library (18 components) - Enhance Entra VerifiedID integration with file utilities - Add API client package for all services - Create comprehensive documentation (naming, deployment, next steps) Infrastructure: - Resource groups, storage accounts with new naming - Terraform configuration updates - Outputs with naming convention examples Deployment: - Automated deployment scripts for all 15 phases - State management and logging - Error handling and validation Documentation: - Naming convention guide and implementation summary - Complete deployment guide (296 steps) - Next steps and quick start guides - Azure prerequisites and setup completion docs Note: ESLint warnings present - will be addressed in follow-up commit
This commit is contained in:
130
infra/scripts/README.md
Normal file
130
infra/scripts/README.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Azure Setup Scripts
|
||||
|
||||
This directory contains scripts for setting up Azure infrastructure prerequisites for The Order.
|
||||
|
||||
## Scripts
|
||||
|
||||
### 1. `azure-setup.sh` - Complete Azure Setup
|
||||
|
||||
Comprehensive setup script that:
|
||||
- Lists all available Azure Commercial regions (excluding US)
|
||||
- Sets default region to West Europe
|
||||
- Checks and registers required resource providers
|
||||
- Checks quotas for primary regions
|
||||
- Generates reports
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./infra/scripts/azure-setup.sh
|
||||
```
|
||||
|
||||
**Output Files:**
|
||||
- `azure-regions.txt` - List of all non-US regions
|
||||
- `azure-quotas.txt` - Quota information for primary regions
|
||||
|
||||
### 2. `azure-register-providers.sh` - Register Resource Providers
|
||||
|
||||
Registers all required Azure Resource Providers for The Order.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
- Checks registration status of all required providers
|
||||
- Registers unregistered providers
|
||||
- Waits for registration to complete
|
||||
- Reports final status
|
||||
|
||||
### 3. `azure-check-quotas.sh` - Check Quotas for All Regions
|
||||
|
||||
Checks quotas for all non-US Azure regions.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./infra/scripts/azure-check-quotas.sh
|
||||
```
|
||||
|
||||
**Output:**
|
||||
- `azure-quotas-all-regions.txt` - Detailed quota information for all regions
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Azure CLI installed**
|
||||
```bash
|
||||
# Check if installed
|
||||
az --version
|
||||
|
||||
# Install if needed
|
||||
# https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
|
||||
```
|
||||
|
||||
2. **Azure CLI logged in**
|
||||
```bash
|
||||
az login
|
||||
az account show
|
||||
```
|
||||
|
||||
3. **Required permissions**
|
||||
- Subscription Contributor or Owner role
|
||||
- Ability to register resource providers
|
||||
- Ability to check quotas
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Login to Azure**
|
||||
```bash
|
||||
az login
|
||||
```
|
||||
|
||||
2. **Run complete setup**
|
||||
```bash
|
||||
./infra/scripts/azure-setup.sh
|
||||
```
|
||||
|
||||
3. **Verify providers are registered**
|
||||
```bash
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
```
|
||||
|
||||
4. **Check quotas**
|
||||
```bash
|
||||
./infra/scripts/azure-check-quotas.sh
|
||||
```
|
||||
|
||||
## Required Resource Providers
|
||||
|
||||
See `infra/terraform/AZURE_RESOURCE_PROVIDERS.md` for complete list.
|
||||
|
||||
## Default Region
|
||||
|
||||
**West Europe (westeurope)** is the default region. US Commercial and Government regions are **not used**.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Script fails with "not logged in"
|
||||
```bash
|
||||
az login
|
||||
az account set --subscription <subscription-id>
|
||||
```
|
||||
|
||||
### Provider registration fails
|
||||
- Check subscription permissions
|
||||
- Verify subscription is active
|
||||
- Wait 5-10 minutes and retry
|
||||
|
||||
### Quota check fails
|
||||
- Some regions may not support all quota types
|
||||
- Check individual regions manually if needed
|
||||
|
||||
## Output Files
|
||||
|
||||
All scripts generate output files in the current directory:
|
||||
|
||||
- `azure-regions.txt` - List of available regions
|
||||
- `azure-quotas.txt` - Quotas for primary regions
|
||||
- `azure-quotas-all-regions.txt` - Quotas for all regions
|
||||
|
||||
Review these files to understand available resources and limits.
|
||||
|
||||
84
infra/scripts/azure-check-quotas.sh
Executable file
84
infra/scripts/azure-check-quotas.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Azure Quota Check Script
|
||||
# Checks quotas for all non-US Azure regions
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Check if Azure CLI is installed
|
||||
if ! command -v az &> /dev/null; then
|
||||
echo -e "${RED}Error: Azure CLI is not installed.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if logged in
|
||||
if ! az account show &> /dev/null; then
|
||||
echo -e "${YELLOW}Please log in to Azure...${NC}"
|
||||
az login
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Azure Quota Check - All Non-US Regions${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Get all non-US regions
|
||||
echo -e "${YELLOW}Fetching non-US regions...${NC}"
|
||||
REGIONS=$(az account list-locations \
|
||||
--query "[?metadata.regionType=='Physical' && !contains(name, 'us')].name" \
|
||||
-o tsv)
|
||||
|
||||
REGION_COUNT=$(echo "${REGIONS}" | wc -l)
|
||||
echo -e "${GREEN}Found ${REGION_COUNT} non-US regions${NC}"
|
||||
echo ""
|
||||
|
||||
# Output file
|
||||
QUOTA_FILE="azure-quotas-all-regions.txt"
|
||||
> "${QUOTA_FILE}"
|
||||
|
||||
echo "Azure Quota Report - All Non-US Regions" >> "${QUOTA_FILE}"
|
||||
echo "Generated: $(date)" >> "${QUOTA_FILE}"
|
||||
echo "Subscription: $(az account show --query name -o tsv)" >> "${QUOTA_FILE}"
|
||||
echo "========================================" >> "${QUOTA_FILE}"
|
||||
echo "" >> "${QUOTA_FILE}"
|
||||
|
||||
# Check quotas for each region
|
||||
REGION_INDEX=0
|
||||
for region in ${REGIONS}; do
|
||||
REGION_INDEX=$((REGION_INDEX + 1))
|
||||
echo -e "${BLUE}[${REGION_INDEX}/${REGION_COUNT}] Checking ${region}...${NC}"
|
||||
|
||||
echo "" >> "${QUOTA_FILE}"
|
||||
echo "========================================" >> "${QUOTA_FILE}"
|
||||
echo "Region: ${region}" >> "${QUOTA_FILE}"
|
||||
echo "========================================" >> "${QUOTA_FILE}"
|
||||
|
||||
# VM quotas
|
||||
echo "VM Family Quotas:" >> "${QUOTA_FILE}"
|
||||
az vm list-usage --location "${region}" -o table >> "${QUOTA_FILE}" 2>/dev/null || echo " Unable to fetch VM quotas" >> "${QUOTA_FILE}"
|
||||
echo "" >> "${QUOTA_FILE}"
|
||||
|
||||
# Storage quotas
|
||||
echo "Storage Account Quota:" >> "${QUOTA_FILE}"
|
||||
az storage account show-usage --location "${region}" -o json >> "${QUOTA_FILE}" 2>/dev/null || echo " Unable to fetch storage quotas" >> "${QUOTA_FILE}"
|
||||
echo "" >> "${QUOTA_FILE}"
|
||||
|
||||
# Network quotas
|
||||
echo "Network Quotas:" >> "${QUOTA_FILE}"
|
||||
az network list-usages --location "${region}" -o table >> "${QUOTA_FILE}" 2>/dev/null || echo " Unable to fetch network quotas" >> "${QUOTA_FILE}"
|
||||
echo "" >> "${QUOTA_FILE}"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Quota check complete${NC}"
|
||||
echo -e "${GREEN}✓ Results saved to: ${QUOTA_FILE}${NC}"
|
||||
echo ""
|
||||
|
||||
133
infra/scripts/azure-register-providers.sh
Executable file
133
infra/scripts/azure-register-providers.sh
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Azure Resource Provider Registration Script
|
||||
# Registers all required resource providers for The Order
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Required Resource Providers
|
||||
REQUIRED_PROVIDERS=(
|
||||
"Microsoft.ContainerService" # AKS
|
||||
"Microsoft.KeyVault" # Key Vault
|
||||
"Microsoft.Storage" # Storage Accounts
|
||||
"Microsoft.Network" # Networking
|
||||
"Microsoft.Compute" # Compute resources
|
||||
"Microsoft.DBforPostgreSQL" # PostgreSQL
|
||||
"Microsoft.ContainerRegistry" # ACR
|
||||
"Microsoft.ManagedIdentity" # Managed Identities
|
||||
"Microsoft.Insights" # Application Insights, Monitor
|
||||
"Microsoft.Logic" # Logic Apps
|
||||
"Microsoft.OperationalInsights" # Log Analytics
|
||||
"Microsoft.Authorization" # RBAC
|
||||
"Microsoft.Resources" # Resource Manager
|
||||
)
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Azure Resource Provider Registration${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if Azure CLI is installed
|
||||
if ! command -v az &> /dev/null; then
|
||||
echo -e "${RED}Error: Azure CLI is not installed.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if logged in
|
||||
if ! az account show &> /dev/null; then
|
||||
echo -e "${YELLOW}Please log in to Azure...${NC}"
|
||||
az login
|
||||
fi
|
||||
|
||||
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
|
||||
SUBSCRIPTION_NAME=$(az account show --query name -o tsv)
|
||||
echo -e "${GREEN}Subscription: ${SUBSCRIPTION_NAME} (${SUBSCRIPTION_ID})${NC}"
|
||||
echo ""
|
||||
|
||||
# Check current registration status
|
||||
echo -e "${YELLOW}Checking current registration status...${NC}"
|
||||
echo ""
|
||||
|
||||
UNREGISTERED=()
|
||||
ALREADY_REGISTERED=()
|
||||
REGISTERING=()
|
||||
|
||||
for provider in "${REQUIRED_PROVIDERS[@]}"; do
|
||||
STATUS=$(az provider show --namespace "${provider}" --query "registrationState" -o tsv 2>/dev/null || echo "NotRegistered")
|
||||
|
||||
if [ "${STATUS}" == "Registered" ]; then
|
||||
echo -e "${GREEN}✓ ${provider} - Already Registered${NC}"
|
||||
ALREADY_REGISTERED+=("${provider}")
|
||||
elif [ "${STATUS}" == "Registering" ]; then
|
||||
echo -e "${YELLOW}⏳ ${provider} - Currently Registering${NC}"
|
||||
REGISTERING+=("${provider}")
|
||||
else
|
||||
echo -e "${RED}✗ ${provider} - Not Registered${NC}"
|
||||
UNREGISTERED+=("${provider}")
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
# Register unregistered providers
|
||||
if [ ${#UNREGISTERED[@]} -gt 0 ]; then
|
||||
echo -e "${YELLOW}Registering ${#UNREGISTERED[@]} unregistered provider(s)...${NC}"
|
||||
echo ""
|
||||
|
||||
for provider in "${UNREGISTERED[@]}"; do
|
||||
echo -n "Registering ${provider}... "
|
||||
az provider register --namespace "${provider}" --wait
|
||||
echo -e "${GREEN}✓ Registered${NC}"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Wait for providers that are currently registering
|
||||
if [ ${#REGISTERING[@]} -gt 0 ]; then
|
||||
echo -e "${YELLOW}Waiting for ${#REGISTERING[@]} provider(s) to finish registering...${NC}"
|
||||
echo ""
|
||||
|
||||
for provider in "${REGISTERING[@]}"; do
|
||||
echo -n "Waiting for ${provider}... "
|
||||
az provider register --namespace "${provider}" --wait
|
||||
echo -e "${GREEN}✓ Registered${NC}"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Final status check
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Final Registration Status${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
ALL_REGISTERED=true
|
||||
for provider in "${REQUIRED_PROVIDERS[@]}"; do
|
||||
STATUS=$(az provider show --namespace "${provider}" --query "registrationState" -o tsv)
|
||||
|
||||
if [ "${STATUS}" == "Registered" ]; then
|
||||
echo -e "${GREEN}✓ ${provider}${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ ${provider} - Status: ${STATUS}${NC}"
|
||||
ALL_REGISTERED=false
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
if [ "${ALL_REGISTERED}" = true ]; then
|
||||
echo -e "${GREEN}✓ All required resource providers are registered!${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Some providers are not yet registered. Please wait and run this script again.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
254
infra/scripts/azure-setup.sh
Executable file
254
infra/scripts/azure-setup.sh
Executable file
@@ -0,0 +1,254 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Azure Setup Script for The Order
|
||||
# This script sets up Azure prerequisites including:
|
||||
# - Listing available regions (excluding US)
|
||||
# - Checking and registering required resource providers
|
||||
# - Checking quotas for all regions
|
||||
# - Setting default region to West Europe
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default region
|
||||
DEFAULT_REGION="westeurope"
|
||||
|
||||
# Required Resource Providers
|
||||
REQUIRED_PROVIDERS=(
|
||||
"Microsoft.ContainerService" # AKS
|
||||
"Microsoft.KeyVault" # Key Vault
|
||||
"Microsoft.Storage" # Storage Accounts
|
||||
"Microsoft.Network" # Networking
|
||||
"Microsoft.Compute" # Compute resources
|
||||
"Microsoft.DBforPostgreSQL" # PostgreSQL
|
||||
"Microsoft.ContainerRegistry" # ACR
|
||||
"Microsoft.ManagedIdentity" # Managed Identities
|
||||
"Microsoft.Insights" # Application Insights, Monitor
|
||||
"Microsoft.Logic" # Logic Apps
|
||||
"Microsoft.OperationalInsights" # Log Analytics
|
||||
"Microsoft.Authorization" # RBAC
|
||||
"Microsoft.Resources" # Resource Manager
|
||||
)
|
||||
|
||||
# Preview Features (if needed)
|
||||
PREVIEW_FEATURES=(
|
||||
# Add preview features here if needed
|
||||
# Example: "Microsoft.ContainerService/EnableWorkloadIdentityPreview"
|
||||
)
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Azure Setup for The Order${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if Azure CLI is installed
|
||||
if ! command -v az &> /dev/null; then
|
||||
echo -e "${RED}Error: Azure CLI is not installed.${NC}"
|
||||
echo "Please install it from: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if logged in
|
||||
echo -e "${YELLOW}Checking Azure CLI login status...${NC}"
|
||||
if ! az account show &> /dev/null; then
|
||||
echo -e "${YELLOW}Not logged in. Please log in...${NC}"
|
||||
az login
|
||||
fi
|
||||
|
||||
# Get current subscription
|
||||
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
|
||||
SUBSCRIPTION_NAME=$(az account show --query name -o tsv)
|
||||
echo -e "${GREEN}Current Subscription: ${SUBSCRIPTION_NAME} (${SUBSCRIPTION_ID})${NC}"
|
||||
echo ""
|
||||
|
||||
# Set default region
|
||||
echo -e "${BLUE}Setting default region to: ${DEFAULT_REGION}${NC}"
|
||||
export AZURE_DEFAULT_REGION=${DEFAULT_REGION}
|
||||
echo ""
|
||||
|
||||
# ============================================
|
||||
# 1. List All Azure Commercial Regions (Excluding US)
|
||||
# ============================================
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}1. Available Azure Commercial Regions${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Get all locations and filter out US regions
|
||||
echo -e "${YELLOW}Fetching available regions (excluding US)...${NC}"
|
||||
az account list-locations \
|
||||
--query "[?metadata.regionType=='Physical' && !contains(name, 'us')].{Name:name, DisplayName:displayName, RegionalDisplayName:regionalDisplayName}" \
|
||||
-o table
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}Recommended regions for The Order:${NC}"
|
||||
echo " - westeurope (Primary - Default)"
|
||||
echo " - northeurope (Secondary)"
|
||||
echo " - uksouth (UK)"
|
||||
echo " - switzerlandnorth (Switzerland)"
|
||||
echo " - norwayeast (Norway)"
|
||||
echo ""
|
||||
|
||||
# Save regions to file
|
||||
REGIONS_FILE="azure-regions.txt"
|
||||
az account list-locations \
|
||||
--query "[?metadata.regionType=='Physical' && !contains(name, 'us')].name" \
|
||||
-o tsv > "${REGIONS_FILE}"
|
||||
echo -e "${GREEN}Regions list saved to: ${REGIONS_FILE}${NC}"
|
||||
echo ""
|
||||
|
||||
# ============================================
|
||||
# 2. List Required Resource Providers
|
||||
# ============================================
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}2. Required Resource Providers${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}Required Resource Providers:${NC}"
|
||||
for provider in "${REQUIRED_PROVIDERS[@]}"; do
|
||||
echo " - ${provider}"
|
||||
done
|
||||
echo ""
|
||||
|
||||
# ============================================
|
||||
# 3. Check and Register Resource Providers
|
||||
# ============================================
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}3. Checking Resource Provider Registration${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
UNREGISTERED_PROVIDERS=()
|
||||
|
||||
for provider in "${REQUIRED_PROVIDERS[@]}"; do
|
||||
echo -n "Checking ${provider}... "
|
||||
STATUS=$(az provider show --namespace "${provider}" --query "registrationState" -o tsv 2>/dev/null || echo "NotRegistered")
|
||||
|
||||
if [ "${STATUS}" == "Registered" ]; then
|
||||
echo -e "${GREEN}✓ Registered${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}✗ Not Registered${NC}"
|
||||
UNREGISTERED_PROVIDERS+=("${provider}")
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# Register unregistered providers
|
||||
if [ ${#UNREGISTERED_PROVIDERS[@]} -gt 0 ]; then
|
||||
echo -e "${YELLOW}Registering unregistered providers...${NC}"
|
||||
for provider in "${UNREGISTERED_PROVIDERS[@]}"; do
|
||||
echo -n "Registering ${provider}... "
|
||||
az provider register --namespace "${provider}" --wait
|
||||
echo -e "${GREEN}✓ Registered${NC}"
|
||||
done
|
||||
echo ""
|
||||
else
|
||||
echo -e "${GREEN}All required providers are already registered!${NC}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# 4. Check Preview Features
|
||||
# ============================================
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}4. Preview Features${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
if [ ${#PREVIEW_FEATURES[@]} -gt 0 ]; then
|
||||
echo -e "${YELLOW}Required Preview Features:${NC}"
|
||||
for feature in "${PREVIEW_FEATURES[@]}"; do
|
||||
echo " - ${feature}"
|
||||
done
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}Note: Preview features may need to be enabled manually in Azure Portal${NC}"
|
||||
echo ""
|
||||
else
|
||||
echo -e "${GREEN}No preview features required.${NC}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# 5. Check Quotas for All Regions
|
||||
# ============================================
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}5. Checking Quotas for All Regions${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Read regions from file
|
||||
REGIONS=$(cat "${REGIONS_FILE}")
|
||||
|
||||
# Quota types to check
|
||||
QUOTA_TYPES=(
|
||||
"cores" # VM cores
|
||||
"virtualMachines" # VM instances
|
||||
)
|
||||
|
||||
# Primary regions to check in detail
|
||||
PRIMARY_REGIONS=("westeurope" "northeurope" "uksouth")
|
||||
|
||||
echo -e "${YELLOW}Checking quotas for primary regions...${NC}"
|
||||
echo ""
|
||||
|
||||
QUOTA_FILE="azure-quotas.txt"
|
||||
> "${QUOTA_FILE}" # Clear file
|
||||
|
||||
for region in "${PRIMARY_REGIONS[@]}"; do
|
||||
echo -e "${BLUE}Region: ${region}${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Get VM family quotas
|
||||
echo "VM Family Quotas:"
|
||||
az vm list-usage \
|
||||
--location "${region}" \
|
||||
--query "[].{Name:name.value, CurrentValue:currentValue, Limit:limit}" \
|
||||
-o table 2>/dev/null || echo " Unable to fetch VM quotas"
|
||||
|
||||
echo "" >> "${QUOTA_FILE}"
|
||||
echo "Region: ${region}" >> "${QUOTA_FILE}"
|
||||
echo "----------------------------------------" >> "${QUOTA_FILE}"
|
||||
az vm list-usage --location "${region}" -o table >> "${QUOTA_FILE}" 2>/dev/null || true
|
||||
echo "" >> "${QUOTA_FILE}"
|
||||
|
||||
# Get storage account quota
|
||||
echo "Storage Account Quota:"
|
||||
STORAGE_QUOTA=$(az storage account show-usage \
|
||||
--location "${region}" \
|
||||
--query "{CurrentValue:currentValue, Limit:limit}" \
|
||||
-o json 2>/dev/null || echo '{"CurrentValue": "N/A", "Limit": "N/A"}')
|
||||
echo "${STORAGE_QUOTA}" | jq '.' 2>/dev/null || echo "${STORAGE_QUOTA}"
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo -e "${GREEN}Detailed quota information saved to: ${QUOTA_FILE}${NC}"
|
||||
echo ""
|
||||
|
||||
# ============================================
|
||||
# 6. Summary
|
||||
# ============================================
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}Setup Summary${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Default region set to: ${DEFAULT_REGION}${NC}"
|
||||
echo -e "${GREEN}✓ Available regions listed (excluding US)${NC}"
|
||||
echo -e "${GREEN}✓ Resource providers checked and registered${NC}"
|
||||
echo -e "${GREEN}✓ Quotas checked for primary regions${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Next Steps:${NC}"
|
||||
echo " 1. Review quota limits in ${QUOTA_FILE}"
|
||||
echo " 2. Update Terraform variables with region: ${DEFAULT_REGION}"
|
||||
echo " 3. Proceed with infrastructure deployment"
|
||||
echo ""
|
||||
|
||||
41
infra/terraform/.gitignore
vendored
Normal file
41
infra/terraform/.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# Local .terraform directories
|
||||
**/.terraform/*
|
||||
|
||||
# .tfstate files
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
|
||||
# Crash log files
|
||||
crash.log
|
||||
crash.*.log
|
||||
|
||||
# Exclude all .tfvars files, which are likely to contain sensitive data
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
|
||||
# Ignore override files as they are usually used to override resources locally
|
||||
override.tf
|
||||
override.tf.json
|
||||
*_override.tf
|
||||
*_override.tf.json
|
||||
|
||||
# Ignore CLI configuration files
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# Ignore plan files
|
||||
*.tfplan
|
||||
tfplan
|
||||
|
||||
# Ignore lock files (optional - some teams prefer to commit these)
|
||||
# .terraform.lock.hcl
|
||||
|
||||
# Ignore backup files
|
||||
*.backup
|
||||
*.bak
|
||||
|
||||
# Ignore Azure CLI output files
|
||||
azure-regions.txt
|
||||
azure-quotas.txt
|
||||
azure-quotas-all-regions.txt
|
||||
|
||||
245
infra/terraform/AZURE_RESOURCE_PROVIDERS.md
Normal file
245
infra/terraform/AZURE_RESOURCE_PROVIDERS.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# Azure Resource Providers - Required for The Order
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Default Region**: West Europe (westeurope)
|
||||
**Policy**: No US Commercial or Government regions
|
||||
|
||||
---
|
||||
|
||||
## Required Resource Providers
|
||||
|
||||
The following Azure Resource Providers must be registered in your subscription before deploying The Order infrastructure:
|
||||
|
||||
### Core Infrastructure Providers
|
||||
|
||||
1. **Microsoft.ContainerService**
|
||||
- **Purpose**: Azure Kubernetes Service (AKS)
|
||||
- **Required For**: Kubernetes cluster deployment
|
||||
- **Registration**: Required
|
||||
|
||||
2. **Microsoft.KeyVault**
|
||||
- **Purpose**: Azure Key Vault for secrets management
|
||||
- **Required For**: Secure storage of secrets, certificates, keys
|
||||
- **Registration**: Required
|
||||
|
||||
3. **Microsoft.Storage**
|
||||
- **Purpose**: Azure Storage Accounts
|
||||
- **Required For**: Object storage, Terraform state backend
|
||||
- **Registration**: Required
|
||||
|
||||
4. **Microsoft.Network**
|
||||
- **Purpose**: Virtual Networks, Load Balancers, Application Gateway
|
||||
- **Required For**: Networking infrastructure
|
||||
- **Registration**: Required
|
||||
|
||||
5. **Microsoft.Compute**
|
||||
- **Purpose**: Virtual Machines, VM Scale Sets
|
||||
- **Required For**: AKS node pools, compute resources
|
||||
- **Registration**: Required
|
||||
|
||||
### Database & Storage Providers
|
||||
|
||||
6. **Microsoft.DBforPostgreSQL**
|
||||
- **Purpose**: Azure Database for PostgreSQL
|
||||
- **Required For**: Primary database service
|
||||
- **Registration**: Required
|
||||
|
||||
7. **Microsoft.ContainerRegistry**
|
||||
- **Purpose**: Azure Container Registry (ACR)
|
||||
- **Required For**: Container image storage and management
|
||||
- **Registration**: Required
|
||||
|
||||
### Identity & Access Providers
|
||||
|
||||
8. **Microsoft.ManagedIdentity**
|
||||
- **Purpose**: Azure Managed Identities
|
||||
- **Required For**: Service-to-service authentication without secrets
|
||||
- **Registration**: Required
|
||||
|
||||
9. **Microsoft.Authorization**
|
||||
- **Purpose**: Role-Based Access Control (RBAC)
|
||||
- **Required For**: Access control and permissions
|
||||
- **Registration**: Required
|
||||
|
||||
### Monitoring & Observability Providers
|
||||
|
||||
10. **Microsoft.Insights**
|
||||
- **Purpose**: Application Insights, Azure Monitor
|
||||
- **Required For**: Application monitoring and metrics
|
||||
- **Registration**: Required
|
||||
|
||||
11. **Microsoft.OperationalInsights**
|
||||
- **Purpose**: Log Analytics Workspaces
|
||||
- **Required For**: Centralized logging and log analysis
|
||||
- **Registration**: Required
|
||||
|
||||
### Workflow & Integration Providers
|
||||
|
||||
12. **Microsoft.Logic**
|
||||
- **Purpose**: Azure Logic Apps
|
||||
- **Required For**: Workflow orchestration (optional but recommended)
|
||||
- **Registration**: Required if using Logic Apps
|
||||
|
||||
### Resource Management Providers
|
||||
|
||||
13. **Microsoft.Resources**
|
||||
- **Purpose**: Azure Resource Manager
|
||||
- **Required For**: Resource group management, deployments
|
||||
- **Registration**: Required (usually pre-registered)
|
||||
|
||||
---
|
||||
|
||||
## Preview Features
|
||||
|
||||
Currently, no preview features are required. If Microsoft Entra VerifiedID requires preview features, they will be documented here.
|
||||
|
||||
---
|
||||
|
||||
## Registration Status
|
||||
|
||||
### Check Registration Status
|
||||
|
||||
```bash
|
||||
# Check all required providers
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
|
||||
# Or check individually
|
||||
az provider show --namespace Microsoft.ContainerService
|
||||
```
|
||||
|
||||
### Register All Providers
|
||||
|
||||
```bash
|
||||
# Run the registration script
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
```
|
||||
|
||||
### Manual Registration
|
||||
|
||||
If you need to register providers manually:
|
||||
|
||||
```bash
|
||||
# Register a single provider
|
||||
az provider register --namespace Microsoft.ContainerService
|
||||
|
||||
# Register all providers
|
||||
for provider in \
|
||||
Microsoft.ContainerService \
|
||||
Microsoft.KeyVault \
|
||||
Microsoft.Storage \
|
||||
Microsoft.Network \
|
||||
Microsoft.Compute \
|
||||
Microsoft.DBforPostgreSQL \
|
||||
Microsoft.ContainerRegistry \
|
||||
Microsoft.ManagedIdentity \
|
||||
Microsoft.Insights \
|
||||
Microsoft.Logic \
|
||||
Microsoft.OperationalInsights \
|
||||
Microsoft.Authorization \
|
||||
Microsoft.Resources; do
|
||||
az provider register --namespace "${provider}" --wait
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Registration Verification
|
||||
|
||||
After registration, verify all providers are registered:
|
||||
|
||||
```bash
|
||||
# Check registration status
|
||||
az provider list --query "[?contains(namespace, 'Microsoft')].{Namespace:namespace, Status:registrationState}" -o table
|
||||
```
|
||||
|
||||
All providers should show `Registered` status.
|
||||
|
||||
---
|
||||
|
||||
## Regional Availability
|
||||
|
||||
**Important**: The Order uses **West Europe (westeurope)** as the default region. US Commercial and Government regions are **not used**.
|
||||
|
||||
### Recommended Regions
|
||||
|
||||
- **Primary**: `westeurope` (West Europe)
|
||||
- **Secondary**: `northeurope` (North Europe)
|
||||
- **UK**: `uksouth` (UK South)
|
||||
- **Switzerland**: `switzerlandnorth` (Switzerland North)
|
||||
- **Norway**: `norwayeast` (Norway East)
|
||||
|
||||
### Check Regional Availability
|
||||
|
||||
Some resource providers may not be available in all regions. Check availability:
|
||||
|
||||
```bash
|
||||
# Check AKS availability
|
||||
az provider show --namespace Microsoft.ContainerService --query "resourceTypes[?resourceType=='managedClusters'].locations" -o table
|
||||
|
||||
# Check PostgreSQL availability
|
||||
az provider show --namespace Microsoft.DBforPostgreSQL --query "resourceTypes[?resourceType=='servers'].locations" -o table
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Provider Registration Fails
|
||||
|
||||
1. **Check Subscription Permissions**
|
||||
```bash
|
||||
az account show
|
||||
az role assignment list --assignee $(az account show --query user.name -o tsv)
|
||||
```
|
||||
|
||||
2. **Check Subscription State**
|
||||
```bash
|
||||
az account show --query state
|
||||
```
|
||||
Must be `Enabled`
|
||||
|
||||
3. **Wait for Registration**
|
||||
- Some providers take 5-10 minutes to register
|
||||
- Use `--wait` flag or check status periodically
|
||||
|
||||
### Provider Not Available in Region
|
||||
|
||||
1. **Check Regional Availability**
|
||||
```bash
|
||||
az provider show --namespace <ProviderName> --query "resourceTypes[?resourceType=='<ResourceType>'].locations"
|
||||
```
|
||||
|
||||
2. **Use Alternative Region**
|
||||
- Consider using `northeurope` or `uksouth` as alternatives
|
||||
|
||||
### Quota Issues
|
||||
|
||||
1. **Check Quotas**
|
||||
```bash
|
||||
./infra/scripts/azure-check-quotas.sh
|
||||
```
|
||||
|
||||
2. **Request Quota Increase**
|
||||
- Go to Azure Portal → Subscriptions → Usage + quotas
|
||||
- Request increase for required resources
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
After registering all resource providers:
|
||||
|
||||
1. ✅ Run `./infra/scripts/azure-setup.sh` to complete Azure setup
|
||||
2. ✅ Check quotas: `./infra/scripts/azure-check-quotas.sh`
|
||||
3. ✅ Proceed with Terraform initialization: `terraform init`
|
||||
4. ✅ Plan infrastructure: `terraform plan`
|
||||
5. ✅ Deploy infrastructure: `terraform apply`
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Azure Resource Provider Registration](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types)
|
||||
- [Azure CLI Provider Commands](https://docs.microsoft.com/en-us/cli/azure/provider)
|
||||
- [Azure Regional Availability](https://azure.microsoft.com/en-us/global-infrastructure/services/)
|
||||
|
||||
391
infra/terraform/EXECUTION_GUIDE.md
Normal file
391
infra/terraform/EXECUTION_GUIDE.md
Normal file
@@ -0,0 +1,391 @@
|
||||
# Azure Infrastructure - Execution Guide
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Default Region**: West Europe (westeurope)
|
||||
**Policy**: No US Commercial or Government regions
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before executing Terraform, ensure you have:
|
||||
|
||||
1. ✅ **Azure CLI installed**
|
||||
```bash
|
||||
az --version
|
||||
```
|
||||
|
||||
2. ✅ **Logged into Azure**
|
||||
```bash
|
||||
az login
|
||||
az account show
|
||||
```
|
||||
|
||||
3. ✅ **Required permissions**
|
||||
- Subscription Contributor or Owner role
|
||||
- Ability to create resource groups
|
||||
- Ability to register resource providers
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Execution
|
||||
|
||||
### Step 1: Run Azure Setup Scripts
|
||||
|
||||
Execute the setup scripts to prepare your Azure subscription:
|
||||
|
||||
```bash
|
||||
# Navigate to project root
|
||||
cd /home/intlc/projects/the_order
|
||||
|
||||
# Run complete setup (recommended)
|
||||
./infra/scripts/azure-setup.sh
|
||||
```
|
||||
|
||||
This will:
|
||||
- List all non-US Azure regions
|
||||
- Register all 13 required resource providers
|
||||
- Check quotas for primary regions
|
||||
- Generate reports
|
||||
|
||||
**Expected Output Files:**
|
||||
- `azure-regions.txt` - List of available regions
|
||||
- `azure-quotas.txt` - Quota information for primary regions
|
||||
|
||||
### Step 2: Verify Resource Provider Registration
|
||||
|
||||
```bash
|
||||
# Run provider registration script
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
```
|
||||
|
||||
**Expected Output:**
|
||||
```
|
||||
✓ Microsoft.ContainerService - Registered
|
||||
✓ Microsoft.KeyVault - Registered
|
||||
✓ Microsoft.Storage - Registered
|
||||
...
|
||||
✓ All required resource providers are registered!
|
||||
```
|
||||
|
||||
If any providers are not registered, the script will register them automatically.
|
||||
|
||||
### Step 3: Review Quotas
|
||||
|
||||
```bash
|
||||
# Check quotas for all regions
|
||||
./infra/scripts/azure-check-quotas.sh
|
||||
```
|
||||
|
||||
**Review the output file:**
|
||||
```bash
|
||||
cat azure-quotas-all-regions.txt
|
||||
```
|
||||
|
||||
Ensure you have sufficient quotas for:
|
||||
- VM cores (for AKS nodes)
|
||||
- Storage accounts
|
||||
- Network resources
|
||||
|
||||
### Step 4: Initialize Terraform
|
||||
|
||||
```bash
|
||||
# Navigate to Terraform directory
|
||||
cd infra/terraform
|
||||
|
||||
# Initialize Terraform (downloads providers)
|
||||
terraform init
|
||||
```
|
||||
|
||||
**Expected Output:**
|
||||
```
|
||||
Initializing the backend...
|
||||
Initializing provider plugins...
|
||||
- Finding hashicorp/azurerm versions matching "~> 3.0"...
|
||||
- Installing hashicorp/azurerm v3.x.x...
|
||||
Terraform has been successfully initialized!
|
||||
```
|
||||
|
||||
### Step 5: Create Initial Infrastructure (State Storage)
|
||||
|
||||
Before using remote state, create the storage account locally:
|
||||
|
||||
```bash
|
||||
# Review the plan
|
||||
terraform plan -target=azurerm_resource_group.terraform_state -target=azurerm_storage_account.terraform_state -target=azurerm_storage_container.terraform_state
|
||||
|
||||
# Apply to create state storage
|
||||
terraform apply -target=azurerm_resource_group.terraform_state -target=azurerm_storage_account.terraform_state -target=azurerm_storage_container.terraform_state
|
||||
```
|
||||
|
||||
**Note**: This creates the storage account needed for remote state backend.
|
||||
|
||||
### Step 6: Configure Remote State Backend
|
||||
|
||||
After the storage account is created:
|
||||
|
||||
1. **Get the storage account name:**
|
||||
```bash
|
||||
terraform output -raw storage_account_name
|
||||
# Or check the Terraform state
|
||||
terraform show | grep storage_account_name
|
||||
```
|
||||
|
||||
2. **Update `versions.tf`** - Uncomment and configure the backend block:
|
||||
```hcl
|
||||
backend "azurerm" {
|
||||
resource_group_name = "the-order-terraform-state-rg"
|
||||
storage_account_name = "<output-from-above>"
|
||||
container_name = "terraform-state"
|
||||
key = "terraform.tfstate"
|
||||
}
|
||||
```
|
||||
|
||||
3. **Re-initialize with backend:**
|
||||
```bash
|
||||
terraform init -migrate-state
|
||||
```
|
||||
|
||||
### Step 7: Plan Full Infrastructure
|
||||
|
||||
```bash
|
||||
# Review what will be created
|
||||
terraform plan
|
||||
|
||||
# Save plan to file for review
|
||||
terraform plan -out=tfplan
|
||||
```
|
||||
|
||||
**Review the plan carefully** to ensure:
|
||||
- Correct resource names
|
||||
- Correct region (should be `westeurope`)
|
||||
- No US regions are being used
|
||||
- Appropriate resource sizes
|
||||
|
||||
### Step 8: Apply Infrastructure
|
||||
|
||||
```bash
|
||||
# Apply the plan
|
||||
terraform apply
|
||||
|
||||
# Or use the saved plan
|
||||
terraform apply tfplan
|
||||
```
|
||||
|
||||
**Expected Resources Created:**
|
||||
- Resource groups
|
||||
- Storage accounts
|
||||
- (Additional resources as you add them)
|
||||
|
||||
### Step 9: Verify Deployment
|
||||
|
||||
```bash
|
||||
# List created resources
|
||||
az resource list --resource-group the-order-dev-rg --output table
|
||||
|
||||
# Check resource group
|
||||
az group show --name the-order-dev-rg
|
||||
|
||||
# Verify region
|
||||
az group show --name the-order-dev-rg --query location
|
||||
# Should output: "westeurope"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment-Specific Deployment
|
||||
|
||||
### Development Environment
|
||||
|
||||
```bash
|
||||
# Set environment variable
|
||||
export TF_VAR_environment=dev
|
||||
|
||||
# Or use -var flag
|
||||
terraform plan -var="environment=dev"
|
||||
terraform apply -var="environment=dev"
|
||||
```
|
||||
|
||||
### Staging Environment
|
||||
|
||||
```bash
|
||||
terraform plan -var="environment=stage"
|
||||
terraform apply -var="environment=stage"
|
||||
```
|
||||
|
||||
### Production Environment
|
||||
|
||||
```bash
|
||||
# Production requires extra caution
|
||||
terraform plan -var="environment=prod" -detailed-exitcode
|
||||
terraform apply -var="environment=prod"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: Resource Provider Not Registered
|
||||
|
||||
**Symptom:**
|
||||
```
|
||||
Error: creating Resource Group: resources.ResourcesClient#CreateOrUpdate:
|
||||
Failure sending request: StatusCode=400 -- Original Error:
|
||||
Code="MissingSubscriptionRegistration"
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Register the provider
|
||||
az provider register --namespace Microsoft.Resources --wait
|
||||
|
||||
# Or run the registration script
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
```
|
||||
|
||||
### Error: Quota Exceeded
|
||||
|
||||
**Symptom:**
|
||||
```
|
||||
Error: creating Storage Account: storage.AccountsClient#Create:
|
||||
Failure sending request: StatusCode=400 -- Original Error:
|
||||
Code="SubscriptionQuotaExceeded"
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
1. Check quotas: `./infra/scripts/azure-check-quotas.sh`
|
||||
2. Request quota increase in Azure Portal
|
||||
3. Or use a different region
|
||||
|
||||
### Error: Invalid Region
|
||||
|
||||
**Symptom:**
|
||||
```
|
||||
Error: invalid location "us-east-1"
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
- Ensure you're using `westeurope` or another non-US region
|
||||
- Check `variables.tf` - default should be `westeurope`
|
||||
- Terraform validation should prevent US regions
|
||||
|
||||
### Error: Storage Account Name Already Exists
|
||||
|
||||
**Symptom:**
|
||||
```
|
||||
Error: creating Storage Account: storage.AccountsClient#Create:
|
||||
Failure sending request: StatusCode=409 -- Original Error:
|
||||
Code="StorageAccountAlreadyTaken"
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
- Storage account names must be globally unique
|
||||
- Modify the name in `storage.tf` or use a different project name
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Always Review Plans
|
||||
|
||||
```bash
|
||||
# Always review before applying
|
||||
terraform plan -out=tfplan
|
||||
terraform show tfplan
|
||||
```
|
||||
|
||||
### 2. Use Workspaces for Multiple Environments
|
||||
|
||||
```bash
|
||||
# Create workspace for dev
|
||||
terraform workspace new dev
|
||||
|
||||
# Create workspace for prod
|
||||
terraform workspace new prod
|
||||
|
||||
# Switch between workspaces
|
||||
terraform workspace select dev
|
||||
```
|
||||
|
||||
### 3. Version Control
|
||||
|
||||
- ✅ Commit Terraform files to version control
|
||||
- ❌ Never commit `.tfstate` files
|
||||
- ✅ Use remote state backend (Azure Storage)
|
||||
- ✅ Use `.tfvars` files for environment-specific values (add to `.gitignore`)
|
||||
|
||||
### 4. State Management
|
||||
|
||||
- ✅ Use remote state backend
|
||||
- ✅ Enable state locking (automatic with Azure Storage)
|
||||
- ✅ Enable versioning on storage account
|
||||
- ✅ Regular backups of state
|
||||
|
||||
### 5. Security
|
||||
|
||||
- ✅ Use Azure Key Vault for secrets
|
||||
- ✅ Use Managed Identities where possible
|
||||
- ✅ Enable soft delete on Key Vault
|
||||
- ✅ Enable versioning on storage accounts
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
After initial infrastructure is created:
|
||||
|
||||
1. **Create Azure Key Vault**
|
||||
- For secrets management
|
||||
- See `key-vault.tf` (to be created)
|
||||
|
||||
2. **Create AKS Cluster**
|
||||
- For Kubernetes deployment
|
||||
- See `aks.tf` (to be created)
|
||||
|
||||
3. **Create PostgreSQL Database**
|
||||
- For application database
|
||||
- See `database.tf` (to be created)
|
||||
|
||||
4. **Create Container Registry**
|
||||
- For container images
|
||||
- See `container-registry.tf` (to be created)
|
||||
|
||||
5. **Configure Networking**
|
||||
- Virtual networks, subnets, NSGs
|
||||
- See `network.tf` (to be created)
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Commands
|
||||
|
||||
```bash
|
||||
# Setup
|
||||
./infra/scripts/azure-setup.sh
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
|
||||
# Terraform
|
||||
cd infra/terraform
|
||||
terraform init
|
||||
terraform plan
|
||||
terraform apply
|
||||
terraform destroy
|
||||
|
||||
# Verification
|
||||
az resource list --resource-group the-order-dev-rg
|
||||
az group show --name the-order-dev-rg
|
||||
terraform output
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
- **Resource Providers**: See `AZURE_RESOURCE_PROVIDERS.md`
|
||||
- **Scripts**: See `infra/scripts/README.md`
|
||||
- **Troubleshooting**: See sections above
|
||||
- **Azure CLI Docs**: https://docs.microsoft.com/en-us/cli/azure/
|
||||
|
||||
---
|
||||
|
||||
**Ready to deploy!** 🚀
|
||||
|
||||
55
infra/terraform/NAMING_VALIDATION.md
Normal file
55
infra/terraform/NAMING_VALIDATION.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Naming Validation
|
||||
|
||||
This document provides validation rules and examples for the naming convention.
|
||||
|
||||
## Validation Rules
|
||||
|
||||
### Resource Group Names
|
||||
- **Pattern**: `az-{region}-rg-{env}-{purpose}`
|
||||
- **Example**: `az-we-rg-dev-main`
|
||||
- **Validation**: `^az-[a-z]{2}-rg-(dev|stg|prd|mgmt)-[a-z]{3,15}$`
|
||||
|
||||
### Storage Account Names
|
||||
- **Pattern**: `az{region}sa{env}{purpose}`
|
||||
- **Example**: `azwesadevdata`
|
||||
- **Max Length**: 24 characters
|
||||
- **Validation**: `^az[a-z]{2}sa(dev|stg|prd|mgmt)[a-z]{3,10}$`
|
||||
|
||||
### Key Vault Names
|
||||
- **Pattern**: `az-{region}-kv-{env}-{purpose}`
|
||||
- **Example**: `az-we-kv-dev-main`
|
||||
- **Max Length**: 24 characters
|
||||
- **Validation**: `^az-[a-z]{2}-kv-(dev|stg|prd|mgmt)-[a-z]{3,10}$`
|
||||
|
||||
### AKS Cluster Names
|
||||
- **Pattern**: `az-{region}-aks-{env}-{purpose}`
|
||||
- **Example**: `az-we-aks-dev-main`
|
||||
- **Max Length**: 63 characters
|
||||
- **Validation**: `^az-[a-z]{2}-aks-(dev|stg|prd|mgmt)-[a-z]{3,15}$`
|
||||
|
||||
### Container Registry Names
|
||||
- **Pattern**: `az{region}acr{env}`
|
||||
- **Example**: `azweacrdev`
|
||||
- **Max Length**: 50 characters
|
||||
- **Validation**: `^az[a-z]{2}acr(dev|stg|prd|mgmt)$`
|
||||
|
||||
## Testing
|
||||
|
||||
Run Terraform validation:
|
||||
|
||||
```bash
|
||||
cd infra/terraform
|
||||
terraform validate
|
||||
terraform plan
|
||||
```
|
||||
|
||||
Check name lengths:
|
||||
|
||||
```bash
|
||||
# Storage accounts must be <= 24 chars
|
||||
echo "azwesadevdata" | wc -c # Should be <= 24
|
||||
|
||||
# Key Vaults must be <= 24 chars
|
||||
echo "az-we-kv-dev-main" | wc -c # Should be <= 24
|
||||
```
|
||||
|
||||
@@ -1,49 +1,190 @@
|
||||
# Terraform Infrastructure
|
||||
|
||||
Terraform configuration for The Order infrastructure.
|
||||
Terraform configuration for The Order infrastructure on Azure.
|
||||
|
||||
**Default Region**: West Europe (westeurope)
|
||||
**Policy**: No US Commercial or Government regions
|
||||
|
||||
## Structure
|
||||
|
||||
- `main.tf` - Main Terraform configuration
|
||||
- `versions.tf` - Terraform and provider version constraints
|
||||
- `main.tf` - Azure provider configuration
|
||||
- `variables.tf` - Variable definitions
|
||||
- `outputs.tf` - Output definitions
|
||||
- `modules/` - Reusable Terraform modules
|
||||
- `resource-groups.tf` - Resource group definitions
|
||||
- `storage.tf` - Storage account definitions
|
||||
- `modules/` - Reusable Terraform modules (to be created)
|
||||
- `AZURE_RESOURCE_PROVIDERS.md` - Required resource providers documentation
|
||||
- `EXECUTION_GUIDE.md` - Step-by-step execution guide
|
||||
|
||||
## Usage
|
||||
## Prerequisites
|
||||
|
||||
Before using Terraform:
|
||||
|
||||
1. **Run Azure setup scripts** (from project root):
|
||||
```bash
|
||||
./infra/scripts/azure-setup.sh
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
```
|
||||
|
||||
2. **Verify Azure CLI is installed and logged in**:
|
||||
```bash
|
||||
az --version
|
||||
az account show
|
||||
```
|
||||
|
||||
3. **Ensure required resource providers are registered**:
|
||||
See `AZURE_RESOURCE_PROVIDERS.md` for complete list.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Navigate to Terraform directory
|
||||
cd infra/terraform
|
||||
|
||||
# Initialize Terraform
|
||||
terraform init
|
||||
|
||||
# Plan changes
|
||||
# Review what will be created
|
||||
terraform plan
|
||||
|
||||
# Apply changes
|
||||
terraform apply
|
||||
|
||||
# Destroy infrastructure
|
||||
terraform destroy
|
||||
```
|
||||
|
||||
## Detailed Execution
|
||||
|
||||
See `EXECUTION_GUIDE.md` for comprehensive step-by-step instructions.
|
||||
|
||||
## Environments
|
||||
|
||||
- `dev/` - Development environment
|
||||
- `stage/` - Staging environment
|
||||
- `prod/` - Production environment
|
||||
Environments are managed via the `environment` variable:
|
||||
|
||||
- `dev` - Development environment
|
||||
- `stage` - Staging environment
|
||||
- `prod` - Production environment
|
||||
|
||||
```bash
|
||||
# Deploy to specific environment
|
||||
terraform plan -var="environment=dev"
|
||||
terraform apply -var="environment=dev"
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Kubernetes cluster
|
||||
- Database (PostgreSQL)
|
||||
- Object storage (S3/GCS)
|
||||
- KMS/HSM for key management
|
||||
- Load balancers
|
||||
- Network configuration
|
||||
### Currently Defined
|
||||
|
||||
- ✅ Resource Groups
|
||||
- ✅ Storage Accounts (application data and Terraform state)
|
||||
- ✅ Storage Containers
|
||||
|
||||
### To Be Created
|
||||
|
||||
- ⏳ Azure Kubernetes Service (AKS) cluster
|
||||
- ⏳ Azure Database for PostgreSQL
|
||||
- ⏳ Azure Key Vault
|
||||
- ⏳ Azure Container Registry (ACR)
|
||||
- ⏳ Virtual Networks and Subnets
|
||||
- ⏳ Application Gateway / Load Balancer
|
||||
- ⏳ Azure Monitor and Log Analytics
|
||||
|
||||
## Configuration
|
||||
|
||||
### Default Region
|
||||
|
||||
Default region is **West Europe (westeurope)**. US regions are not allowed.
|
||||
|
||||
To use a different region:
|
||||
```bash
|
||||
terraform plan -var="azure_region=northeurope"
|
||||
```
|
||||
|
||||
### Variables
|
||||
|
||||
Key variables (see `variables.tf` for complete list):
|
||||
|
||||
- `azure_region` - Azure region (default: `westeurope`)
|
||||
- `environment` - Environment name (`dev`, `stage`, `prod`)
|
||||
- `project_name` - Project name (default: `the-order`)
|
||||
- `create_terraform_state_storage` - Create state storage (default: `true`)
|
||||
|
||||
## Secrets Management
|
||||
|
||||
Secrets are managed using:
|
||||
- SOPS for encrypted secrets
|
||||
- Cloud KMS for key management
|
||||
- External Secrets Operator for Kubernetes
|
||||
- Azure Key Vault (to be configured)
|
||||
- External Secrets Operator for Kubernetes (to be configured)
|
||||
- SOPS for local development (optional)
|
||||
|
||||
## State Management
|
||||
|
||||
Terraform state is stored in Azure Storage Account:
|
||||
|
||||
1. First deployment creates storage account locally
|
||||
2. After creation, configure remote backend in `versions.tf`
|
||||
3. Re-initialize with `terraform init -migrate-state`
|
||||
|
||||
See `EXECUTION_GUIDE.md` for detailed instructions.
|
||||
|
||||
## Outputs
|
||||
|
||||
Key outputs (see `outputs.tf` for complete list):
|
||||
|
||||
- `resource_group_name` - Main resource group name
|
||||
- `storage_account_name` - Application data storage account
|
||||
- `azure_region` - Azure region being used
|
||||
|
||||
View outputs:
|
||||
```bash
|
||||
terraform output
|
||||
terraform output resource_group_name
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. ✅ Always review `terraform plan` before applying
|
||||
2. ✅ Use workspaces for multiple environments
|
||||
3. ✅ Never commit `.tfstate` files
|
||||
4. ✅ Use remote state backend
|
||||
5. ✅ Enable versioning on storage accounts
|
||||
6. ✅ Use `.tfvars` files for environment-specific values
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Common issues and solutions:
|
||||
|
||||
### Resource Provider Not Registered
|
||||
```bash
|
||||
./infra/scripts/azure-register-providers.sh
|
||||
```
|
||||
|
||||
### Quota Exceeded
|
||||
```bash
|
||||
./infra/scripts/azure-check-quotas.sh
|
||||
# Request quota increase in Azure Portal
|
||||
```
|
||||
|
||||
### Invalid Region
|
||||
- Ensure region doesn't start with `us`
|
||||
- Default is `westeurope`
|
||||
- See validation in `variables.tf`
|
||||
|
||||
See `EXECUTION_GUIDE.md` for more troubleshooting tips.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **Execution Guide**: `EXECUTION_GUIDE.md` - Step-by-step deployment instructions
|
||||
- **Resource Providers**: `AZURE_RESOURCE_PROVIDERS.md` - Required providers and registration
|
||||
- **Setup Scripts**: `../scripts/README.md` - Azure CLI setup scripts
|
||||
- **Deployment Review**: `../../docs/reports/DEPLOYMENT_READINESS_REVIEW.md` - Overall deployment status
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Run setup scripts to register providers
|
||||
2. ✅ Initialize Terraform
|
||||
3. ✅ Create initial infrastructure (resource groups, storage)
|
||||
4. ⏳ Configure remote state backend
|
||||
5. ⏳ Add additional resources (AKS, PostgreSQL, Key Vault, etc.)
|
||||
|
||||
---
|
||||
|
||||
**See `EXECUTION_GUIDE.md` for detailed step-by-step instructions.**
|
||||
|
||||
92
infra/terraform/locals.tf
Normal file
92
infra/terraform/locals.tf
Normal file
@@ -0,0 +1,92 @@
|
||||
# Local values for naming conventions and common configurations
|
||||
# Follows standard naming pattern: {provider}-{region}-{resource}-{env}-{purpose}
|
||||
|
||||
locals {
|
||||
# Provider identifier
|
||||
provider = "az"
|
||||
|
||||
# Region abbreviation mapping
|
||||
region_abbrev = {
|
||||
westeurope = "we"
|
||||
northeurope = "ne"
|
||||
uksouth = "uk"
|
||||
switzerlandnorth = "ch"
|
||||
norwayeast = "no"
|
||||
francecentral = "fr"
|
||||
germanywestcentral = "de"
|
||||
}
|
||||
|
||||
# Current region abbreviation
|
||||
region_short = lookup(local.region_abbrev, var.azure_region, "we")
|
||||
|
||||
# Environment abbreviations
|
||||
env_abbrev = {
|
||||
dev = "dev"
|
||||
stage = "stg"
|
||||
prod = "prd"
|
||||
mgmt = "mgmt"
|
||||
}
|
||||
|
||||
# Current environment abbreviation
|
||||
env_short = lookup(local.env_abbrev, var.environment, "dev")
|
||||
|
||||
# Project name (shortened for resource names)
|
||||
project_short = "ord"
|
||||
|
||||
# Naming functions
|
||||
# Format: {provider}-{region}-{resource}-{env}-{purpose}
|
||||
name_prefix = "${local.provider}-${local.region_short}"
|
||||
|
||||
# Resource Group naming
|
||||
# Pattern: az-we-rg-dev-main
|
||||
rg_name = "${local.name_prefix}-rg-${local.env_short}-main"
|
||||
rg_state_name = "${local.name_prefix}-rg-${local.env_short}-state"
|
||||
|
||||
# Storage Account naming (alphanumeric only, max 24 chars)
|
||||
# Pattern: azwesadevdata (az + we + sa + dev + data)
|
||||
sa_data_name = "${local.provider}${local.region_short}sa${local.env_short}data"
|
||||
sa_state_name = "${local.provider}${local.region_short}sa${local.env_short}state"
|
||||
|
||||
# Key Vault naming (alphanumeric and hyphens, max 24 chars)
|
||||
# Pattern: az-we-kv-dev-main
|
||||
kv_name = "${local.name_prefix}-kv-${local.env_short}-main"
|
||||
|
||||
# AKS Cluster naming (max 63 chars)
|
||||
# Pattern: az-we-aks-dev-main
|
||||
aks_name = "${local.name_prefix}-aks-${local.env_short}-main"
|
||||
|
||||
# Container Registry naming (alphanumeric only, max 50 chars)
|
||||
# Pattern: azweacrdev (az + we + acr + dev)
|
||||
acr_name = "${local.provider}${local.region_short}acr${local.env_short}"
|
||||
|
||||
# PostgreSQL Server naming (max 63 chars)
|
||||
# Pattern: az-we-psql-dev-main
|
||||
psql_name = "${local.name_prefix}-psql-${local.env_short}-main"
|
||||
|
||||
# Database naming (max 63 chars)
|
||||
# Pattern: az-we-db-dev-main
|
||||
db_name = "${local.name_prefix}-db-${local.env_short}-main"
|
||||
|
||||
# Virtual Network naming (max 64 chars)
|
||||
# Pattern: az-we-vnet-dev-main
|
||||
vnet_name = "${local.name_prefix}-vnet-${local.env_short}-main"
|
||||
|
||||
# Application Insights naming (max 255 chars)
|
||||
# Pattern: az-we-appi-dev-main
|
||||
appi_name = "${local.name_prefix}-appi-${local.env_short}-main"
|
||||
|
||||
# Log Analytics Workspace naming (max 63 chars)
|
||||
# Pattern: az-we-law-dev-main
|
||||
law_name = "${local.name_prefix}-law-${local.env_short}-main"
|
||||
|
||||
# Common tags
|
||||
common_tags = {
|
||||
Environment = var.environment
|
||||
Project = var.project_name
|
||||
Region = var.azure_region
|
||||
ManagedBy = "Terraform"
|
||||
CostCenter = "engineering"
|
||||
Owner = "platform-team"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +1,54 @@
|
||||
# Terraform configuration for The Order infrastructure
|
||||
# This is a template - customize for your cloud provider
|
||||
# Azure provider configuration - No US Commercial or Government regions
|
||||
# Version constraints are in versions.tf
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.5.0"
|
||||
|
||||
required_providers {
|
||||
# Add your cloud provider(s) here
|
||||
# Example for AWS:
|
||||
# aws = {
|
||||
# source = "hashicorp/aws"
|
||||
# version = "~> 5.0"
|
||||
# }
|
||||
# Configure the Azure Provider
|
||||
provider "azurerm" {
|
||||
features {
|
||||
resource_group {
|
||||
prevent_deletion_if_contains_resources = false
|
||||
}
|
||||
key_vault {
|
||||
purge_soft_delete_on_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
# Configure backend for state management
|
||||
# backend "s3" {
|
||||
# bucket = "the-order-terraform-state"
|
||||
# key = "terraform.tfstate"
|
||||
# region = "us-east-1"
|
||||
# }
|
||||
|
||||
# Default location - West Europe (no US regions)
|
||||
# This can be overridden per resource if needed
|
||||
location = var.azure_region
|
||||
}
|
||||
|
||||
# Provider configuration
|
||||
# provider "aws" {
|
||||
# region = var.aws_region
|
||||
# }
|
||||
|
||||
# Variables
|
||||
variable "aws_region" {
|
||||
description = "AWS region"
|
||||
variable "azure_region" {
|
||||
description = "Azure region (default: westeurope, no US regions allowed)"
|
||||
type = string
|
||||
default = "us-east-1"
|
||||
default = "westeurope"
|
||||
|
||||
validation {
|
||||
condition = !can(regex("^us", var.azure_region))
|
||||
error_message = "US Commercial and Government regions are not allowed. Use European or other non-US regions."
|
||||
}
|
||||
}
|
||||
|
||||
variable "environment" {
|
||||
description = "Environment name (dev, stage, prod)"
|
||||
type = string
|
||||
default = "dev"
|
||||
|
||||
validation {
|
||||
condition = contains(["dev", "stage", "prod"], var.environment)
|
||||
error_message = "Environment must be dev, stage, or prod."
|
||||
}
|
||||
}
|
||||
|
||||
# Outputs
|
||||
output "environment" {
|
||||
value = var.environment
|
||||
description = "Environment name"
|
||||
value = var.environment
|
||||
}
|
||||
|
||||
output "azure_region" {
|
||||
description = "Azure region being used"
|
||||
value = var.azure_region
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,65 @@ output "project_name" {
|
||||
value = var.project_name
|
||||
}
|
||||
|
||||
# Add more outputs as needed
|
||||
# Example:
|
||||
# output "kubernetes_cluster_endpoint" {
|
||||
# description = "Kubernetes cluster endpoint"
|
||||
# value = module.kubernetes.cluster_endpoint
|
||||
# }
|
||||
output "azure_region" {
|
||||
description = "Azure region being used"
|
||||
value = var.azure_region
|
||||
}
|
||||
|
||||
# output "database_endpoint" {
|
||||
# description = "Database endpoint"
|
||||
# value = module.database.endpoint
|
||||
# }
|
||||
output "region_abbreviation" {
|
||||
description = "Region abbreviation used in naming"
|
||||
value = local.region_short
|
||||
}
|
||||
|
||||
output "resource_group_name" {
|
||||
description = "Main resource group name (az-we-rg-dev-main)"
|
||||
value = azurerm_resource_group.main.name
|
||||
}
|
||||
|
||||
output "resource_group_id" {
|
||||
description = "Main resource group ID"
|
||||
value = azurerm_resource_group.main.id
|
||||
}
|
||||
|
||||
output "storage_account_name" {
|
||||
description = "Application data storage account name (azwesadevdata)"
|
||||
value = azurerm_storage_account.app_data.name
|
||||
}
|
||||
|
||||
output "storage_account_id" {
|
||||
description = "Application data storage account ID"
|
||||
value = azurerm_storage_account.app_data.id
|
||||
}
|
||||
|
||||
output "terraform_state_storage_account_name" {
|
||||
description = "Terraform state storage account name (azwesadevstate)"
|
||||
value = var.create_terraform_state_storage ? azurerm_storage_account.terraform_state[0].name : null
|
||||
}
|
||||
|
||||
output "terraform_state_resource_group_name" {
|
||||
description = "Terraform state resource group name (az-we-rg-dev-state)"
|
||||
value = var.create_terraform_state_rg ? azurerm_resource_group.terraform_state[0].name : null
|
||||
}
|
||||
|
||||
output "terraform_state_storage_container_name" {
|
||||
description = "Terraform state storage container name (if created)"
|
||||
value = var.create_terraform_state_storage ? azurerm_storage_container.terraform_state[0].name : null
|
||||
}
|
||||
|
||||
# Naming convention outputs for reference
|
||||
output "naming_convention" {
|
||||
description = "Naming convention pattern used"
|
||||
value = {
|
||||
pattern = "{provider}-{region}-{resource}-{env}-{purpose}"
|
||||
provider = local.provider
|
||||
region_abbrev = local.region_short
|
||||
env_abbrev = local.env_short
|
||||
examples = {
|
||||
resource_group = local.rg_name
|
||||
storage_account = local.sa_data_name
|
||||
key_vault = local.kv_name
|
||||
aks_cluster = local.aks_name
|
||||
container_registry = local.acr_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
infra/terraform/resource-groups.tf
Normal file
24
infra/terraform/resource-groups.tf
Normal file
@@ -0,0 +1,24 @@
|
||||
# Resource Groups for The Order
|
||||
# Creates resource groups for each environment
|
||||
# Naming: az-we-rg-dev-main (provider-region-resource-env-purpose)
|
||||
|
||||
resource "azurerm_resource_group" "main" {
|
||||
name = local.rg_name
|
||||
location = var.azure_region
|
||||
|
||||
tags = merge(local.common_tags, {
|
||||
Purpose = "Main"
|
||||
})
|
||||
}
|
||||
|
||||
# Resource group for Terraform state (if using remote backend)
|
||||
resource "azurerm_resource_group" "terraform_state" {
|
||||
count = var.create_terraform_state_rg ? 1 : 0
|
||||
name = local.rg_state_name
|
||||
location = var.azure_region
|
||||
|
||||
tags = merge(local.common_tags, {
|
||||
Purpose = "TerraformState"
|
||||
})
|
||||
}
|
||||
|
||||
60
infra/terraform/storage.tf
Normal file
60
infra/terraform/storage.tf
Normal file
@@ -0,0 +1,60 @@
|
||||
# Azure Storage Account for Terraform State Backend
|
||||
# This should be created first, then uncomment the backend block in versions.tf
|
||||
# Naming: azwesadevstate (provider+region+sa+env+purpose, alphanumeric only, max 24 chars)
|
||||
|
||||
resource "azurerm_storage_account" "terraform_state" {
|
||||
count = var.create_terraform_state_storage ? 1 : 0
|
||||
name = local.sa_state_name
|
||||
resource_group_name = azurerm_resource_group.terraform_state[0].name
|
||||
location = var.azure_region
|
||||
account_tier = "Standard"
|
||||
account_replication_type = "LRS"
|
||||
min_tls_version = "TLS1_2"
|
||||
|
||||
# Enable blob versioning and soft delete for state protection
|
||||
blob_properties {
|
||||
versioning_enabled = true
|
||||
delete_retention_policy {
|
||||
days = 30
|
||||
}
|
||||
}
|
||||
|
||||
tags = merge(local.common_tags, {
|
||||
Purpose = "TerraformState"
|
||||
})
|
||||
}
|
||||
|
||||
resource "azurerm_storage_container" "terraform_state" {
|
||||
count = var.create_terraform_state_storage ? 1 : 0
|
||||
name = "terraform-state"
|
||||
storage_account_name = azurerm_storage_account.terraform_state[0].name
|
||||
container_access_type = "private"
|
||||
}
|
||||
|
||||
# Storage Account for application data (object storage)
|
||||
# Naming: azwesadevdata (provider+region+sa+env+purpose, alphanumeric only, max 24 chars)
|
||||
resource "azurerm_storage_account" "app_data" {
|
||||
name = local.sa_data_name
|
||||
resource_group_name = azurerm_resource_group.main.name
|
||||
location = var.azure_region
|
||||
account_tier = "Standard"
|
||||
account_replication_type = var.environment == "prod" ? "GRS" : "LRS"
|
||||
min_tls_version = "TLS1_2"
|
||||
allow_blob_public_access = false
|
||||
|
||||
# Enable blob versioning for data protection
|
||||
blob_properties {
|
||||
versioning_enabled = true
|
||||
delete_retention_policy {
|
||||
days = var.environment == "prod" ? 90 : 30
|
||||
}
|
||||
container_delete_retention_policy {
|
||||
days = var.environment == "prod" ? 90 : 30
|
||||
}
|
||||
}
|
||||
|
||||
tags = merge(local.common_tags, {
|
||||
Purpose = "ApplicationData"
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,10 +9,23 @@ variable "environment" {
|
||||
}
|
||||
}
|
||||
|
||||
variable "aws_region" {
|
||||
description = "AWS region"
|
||||
variable "azure_region" {
|
||||
description = "Azure region (default: westeurope, no US regions allowed)"
|
||||
type = string
|
||||
default = "us-east-1"
|
||||
default = "westeurope"
|
||||
|
||||
validation {
|
||||
condition = !can(regex("^us", var.azure_region))
|
||||
error_message = "US Commercial and Government regions are not allowed. Use European or other non-US regions."
|
||||
}
|
||||
|
||||
validation {
|
||||
condition = contains([
|
||||
"westeurope", "northeurope", "uksouth", "switzerlandnorth",
|
||||
"norwayeast", "francecentral", "germanywestcentral"
|
||||
], var.azure_region)
|
||||
error_message = "Region must be one of the supported non-US regions. See naming convention documentation."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_name" {
|
||||
@@ -39,3 +52,15 @@ variable "enable_logging" {
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "create_terraform_state_rg" {
|
||||
description = "Create resource group for Terraform state storage"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "create_terraform_state_storage" {
|
||||
description = "Create storage account for Terraform state backend"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
|
||||
22
infra/terraform/versions.tf
Normal file
22
infra/terraform/versions.tf
Normal file
@@ -0,0 +1,22 @@
|
||||
# Terraform and Provider Version Constraints
|
||||
# Azure provider configuration - No US Commercial or Government regions
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.5.0"
|
||||
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Configure backend for state management
|
||||
# Uncomment and configure after creating Azure Storage Account
|
||||
# backend "azurerm" {
|
||||
# resource_group_name = "az-we-rg-dev-state"
|
||||
# storage_account_name = "azwesadevstate"
|
||||
# container_name = "terraform-state"
|
||||
# key = "terraform.tfstate"
|
||||
# }
|
||||
}
|
||||
Reference in New Issue
Block a user