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:
defiQUG
2025-11-12 08:22:51 -08:00
parent 9e46f3f316
commit 8649ad4124
136 changed files with 17251 additions and 147 deletions

130
infra/scripts/README.md Normal file
View 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.

View 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 ""

View 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
View 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
View 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

View 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/)

View 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!** 🚀

View 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
```

View File

@@ -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
View 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"
}
}

View File

@@ -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
}

View File

@@ -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
}
}
}

View 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"
})
}

View 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"
})
}

View File

@@ -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
}

View 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"
# }
}