#!/bin/bash # Azure Resources Setup Script for CMDB Insight # This script helps automate the creation of Azure resources # # Usage: # ./scripts/setup-azure-resources.sh # # Prerequisites: # - Azure CLI installed and logged in (az login) # - Appropriate permissions on Azure subscription # - Jira credentials ready (OAuth or PAT) set -e # Exit on error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Configuration - Customize these values RESOURCE_GROUP="rg-cmdb-insight-prod" LOCATION="westeurope" # ACR Configuration - Can be shared across multiple applications # Option 1: Use existing ACR (recommended if you have one) ACR_NAME="" # Leave empty to use existing, or set to create new ACR_RESOURCE_GROUP="" # Resource group where ACR exists (for existing) or will be created (for new) # Option 2: Create new ACR (only if ACR_NAME is set and doesn't exist) # ACR_NAME="yourcompanyacr" # Must be globally unique, lowercase, 5-50 chars # ACR_RESOURCE_GROUP="rg-shared-services" # Or use RESOURCE_GROUP DB_SERVER_NAME="cmdb-postgres-prod" # Must be globally unique DB_ADMIN_USER="cmdbadmin" DB_NAME="cmdb" KEY_VAULT_NAME="kv-cmdb-insight-prod" # Must be globally unique APP_INSIGHTS_NAME="appi-cmdb-insight-prod" # Must be globally unique APP_SERVICE_PLAN_NAME="plan-cmdb-insight-prod" BACKEND_APP_NAME="cmdb-backend-prod" # Must be globally unique FRONTEND_APP_NAME="cmdb-frontend-prod" # Must be globally unique # SKU Configuration ACR_SKU="Standard" # Options: Basic, Standard, Premium (Standard recommended for shared ACR) APP_SERVICE_SKU="B1" # Options: B1, B2, S1 POSTGRES_SKU="Standard_B1ms" # Options: Standard_B1ms, Standard_B2s echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}Azure Resources Setup for CMDB Insight${NC}" echo -e "${GREEN}========================================${NC}" echo "" # Check Azure CLI if ! command -v az &> /dev/null; then echo -e "${RED}Error: Azure CLI is not installed.${NC}" echo "Install it from: https://docs.microsoft.com/cli/azure/install-azure-cli" exit 1 fi # Check if logged in if ! az account show &> /dev/null; then echo -e "${YELLOW}Not logged in to Azure. Please run: az login${NC}" exit 1 fi # Show current subscription echo -e "${GREEN}Current Azure Subscription:${NC}" az account show --query "{Name:name, SubscriptionId:id}" -o table echo "" # Confirm before proceeding read -p "Do you want to proceed with creating resources? (yes/no): " confirm if [ "$confirm" != "yes" ]; then echo "Aborted." exit 0 fi echo "" echo -e "${GREEN}Step 1: Creating Resource Group...${NC}" az group create \ --name $RESOURCE_GROUP \ --location $LOCATION \ --output none echo -e "${GREEN}✓ Resource Group created${NC}" echo "" echo -e "${GREEN}Step 2: Setting up Azure Container Registry...${NC}" # Check if ACR_NAME is provided if [ -z "$ACR_NAME" ]; then echo -e "${YELLOW}⚠️ ACR_NAME not set. Please provide an existing ACR name or set ACR_NAME to create a new one.${NC}" read -p "Enter existing ACR name (or press Enter to skip): " EXISTING_ACR_NAME if [ -z "$EXISTING_ACR_NAME" ]; then echo -e "${YELLOW}Skipping ACR setup. You'll need to configure ACR manually.${NC}" ACR_NAME="" ACR_LOGIN_SERVER="" else ACR_NAME=$EXISTING_ACR_NAME if [ -z "$ACR_RESOURCE_GROUP" ]; then read -p "Enter ACR resource group: " ACR_RESOURCE_GROUP fi # Verify ACR exists if az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP &> /dev/null; then echo -e "${GREEN}✓ Using existing Container Registry: $ACR_NAME${NC}" ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query loginServer --output tsv) echo " ACR Login Server: $ACR_LOGIN_SERVER" else echo -e "${RED}Error: ACR '$ACR_NAME' not found in resource group '$ACR_RESOURCE_GROUP'${NC}" exit 1 fi fi else # Determine ACR resource group if [ -z "$ACR_RESOURCE_GROUP" ]; then ACR_RESOURCE_GROUP=$RESOURCE_GROUP fi # Check if ACR already exists if az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP &> /dev/null; then echo -e "${GREEN}✓ Using existing Container Registry: $ACR_NAME${NC}" ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query loginServer --output tsv) echo " ACR Login Server: $ACR_LOGIN_SERVER" else # Create resource group for ACR if it doesn't exist if ! az group show --name $ACR_RESOURCE_GROUP &> /dev/null; then echo "Creating resource group for ACR: $ACR_RESOURCE_GROUP" az group create --name $ACR_RESOURCE_GROUP --location $LOCATION --output none fi # Create new ACR echo "Creating new Container Registry: $ACR_NAME" az acr create \ --resource-group $ACR_RESOURCE_GROUP \ --name $ACR_NAME \ --sku $ACR_SKU \ --admin-enabled true \ --output none echo -e "${GREEN}✓ Container Registry created${NC}" ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query loginServer --output tsv) echo " ACR Login Server: $ACR_LOGIN_SERVER" echo -e "${YELLOW}💡 This ACR can be shared with other applications. Use repository names to separate apps.${NC}" fi fi echo "" echo -e "${GREEN}Step 3: Creating PostgreSQL Database...${NC}" echo -e "${YELLOW}Generating secure database password...${NC}" DB_ADMIN_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25) echo " Database Password: $DB_ADMIN_PASSWORD" echo " ${YELLOW}⚠️ Save this password securely!${NC}" az postgres flexible-server create \ --resource-group $RESOURCE_GROUP \ --name $DB_SERVER_NAME \ --location $LOCATION \ --admin-user $DB_ADMIN_USER \ --admin-password $DB_ADMIN_PASSWORD \ --sku-name $POSTGRES_SKU \ --tier Burstable \ --storage-size 32 \ --version 15 \ --public-access 0.0.0.0 \ --output none echo -e "${GREEN}✓ PostgreSQL Server created${NC}" az postgres flexible-server db create \ --resource-group $RESOURCE_GROUP \ --server-name $DB_SERVER_NAME \ --database-name $DB_NAME \ --output none echo -e "${GREEN}✓ Database created${NC}" DB_HOST="${DB_SERVER_NAME}.postgres.database.azure.com" DB_CONNECTION_STRING="postgresql://${DB_ADMIN_USER}:${DB_ADMIN_PASSWORD}@${DB_HOST}:5432/${DB_NAME}?sslmode=require" echo " Database Host: $DB_HOST" echo "" echo -e "${GREEN}Step 4: Creating Key Vault...${NC}" az keyvault create \ --name $KEY_VAULT_NAME \ --resource-group $RESOURCE_GROUP \ --location $LOCATION \ --sku standard \ --output none echo -e "${GREEN}✓ Key Vault created${NC}" # Add database password to Key Vault az keyvault secret set \ --vault-name $KEY_VAULT_NAME \ --name "DatabasePassword" \ --value "$DB_ADMIN_PASSWORD" \ --output none echo -e "${GREEN}✓ Database password stored in Key Vault${NC}" echo "" echo -e "${YELLOW}⚠️ You need to add the following secrets to Key Vault manually:${NC}" echo " - JiraPat (if using PAT authentication)" echo " - SessionSecret (generate with: openssl rand -hex 32)" echo " - JiraOAuthClientId (if using OAuth)" echo " - JiraOAuthClientSecret (if using OAuth)" echo "" echo "Commands to add secrets:" echo " az keyvault secret set --vault-name $KEY_VAULT_NAME --name SessionSecret --value \$(openssl rand -hex 32)" echo " az keyvault secret set --vault-name $KEY_VAULT_NAME --name JiraOAuthClientId --value " echo " az keyvault secret set --vault-name $KEY_VAULT_NAME --name JiraOAuthClientSecret --value " echo "" echo -e "${GREEN}Step 5: Creating Application Insights...${NC}" az monitor app-insights component create \ --app $APP_INSIGHTS_NAME \ --location $LOCATION \ --resource-group $RESOURCE_GROUP \ --application-type web \ --output none echo -e "${GREEN}✓ Application Insights created${NC}" INSTRUMENTATION_KEY=$(az monitor app-insights component show \ --app $APP_INSIGHTS_NAME \ --resource-group $RESOURCE_GROUP \ --query instrumentationKey --output tsv) echo " Instrumentation Key: $INSTRUMENTATION_KEY" echo "" echo -e "${GREEN}Step 6: Creating App Service Plan...${NC}" az appservice plan create \ --name $APP_SERVICE_PLAN_NAME \ --resource-group $RESOURCE_GROUP \ --sku $APP_SERVICE_SKU \ --is-linux \ --output none echo -e "${GREEN}✓ App Service Plan created${NC}" echo "" echo -e "${GREEN}Step 7: Creating Backend App Service...${NC}" az webapp create \ --name $BACKEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --plan $APP_SERVICE_PLAN_NAME \ --deployment-container-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/backend:latest" \ --output none echo -e "${GREEN}✓ Backend App Service created${NC}" # Enable Managed Identity az webapp identity assign \ --name $BACKEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --output none BACKEND_PRINCIPAL_ID=$(az webapp identity show \ --name $BACKEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --query principalId --output tsv) # Grant ACR access (if ACR was configured) if [ -n "$ACR_NAME" ] && [ -n "$ACR_RESOURCE_GROUP" ]; then ACR_ID=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query id --output tsv) az role assignment create \ --assignee $BACKEND_PRINCIPAL_ID \ --role AcrPull \ --scope $ACR_ID \ --output none echo -e "${GREEN}✓ ACR access granted to backend${NC}" else echo -e "${YELLOW}⚠️ ACR not configured. You'll need to grant ACR access manually.${NC}" fi # Configure container (if ACR was configured) if [ -n "$ACR_NAME" ]; then az webapp config container set \ --name $BACKEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --docker-custom-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/backend:latest" \ --docker-registry-server-url "https://${ACR_NAME}.azurecr.io" \ --output none else echo -e "${YELLOW}⚠️ ACR not configured. You'll need to configure container settings manually.${NC}" fi # Grant Key Vault access az keyvault set-policy \ --name $KEY_VAULT_NAME \ --object-id $BACKEND_PRINCIPAL_ID \ --secret-permissions get list \ --output none echo -e "${GREEN}✓ Key Vault access granted to backend${NC}" # Set environment variables (basic - you'll need to add Key Vault references manually) az webapp config appsettings set \ --name $BACKEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --settings \ NODE_ENV=production \ PORT=3001 \ DATABASE_TYPE=postgres \ DATABASE_URL="postgresql://${DB_ADMIN_USER}:${DB_ADMIN_PASSWORD}@${DB_HOST}:5432/${DB_NAME}?sslmode=require" \ JIRA_HOST=https://jira.zuyderland.nl \ JIRA_AUTH_METHOD=oauth \ FRONTEND_URL="https://${FRONTEND_APP_NAME}.azurewebsites.net" \ APPINSIGHTS_INSTRUMENTATIONKEY="${INSTRUMENTATION_KEY}" \ --output none # Enable HTTPS only az webapp update \ --name $BACKEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --https-only true \ --output none echo -e "${GREEN}✓ Backend configuration complete${NC}" echo "" echo -e "${GREEN}Step 8: Creating Frontend App Service...${NC}" az webapp create \ --name $FRONTEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --plan $APP_SERVICE_PLAN_NAME \ --deployment-container-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/frontend:latest" \ --output none echo -e "${GREEN}✓ Frontend App Service created${NC}" # Enable Managed Identity az webapp identity assign \ --name $FRONTEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --output none FRONTEND_PRINCIPAL_ID=$(az webapp identity show \ --name $FRONTEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --query principalId --output tsv) # Grant ACR access (if ACR was configured) if [ -n "$ACR_NAME" ] && [ -n "$ACR_RESOURCE_GROUP" ]; then ACR_ID=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query id --output tsv) az role assignment create \ --assignee $FRONTEND_PRINCIPAL_ID \ --role AcrPull \ --scope $ACR_ID \ --output none echo -e "${GREEN}✓ ACR access granted to frontend${NC}" fi # Configure container (if ACR was configured) if [ -n "$ACR_NAME" ]; then az webapp config container set \ --name $FRONTEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --docker-custom-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/frontend:latest" \ --docker-registry-server-url "https://${ACR_NAME}.azurecr.io" \ --output none fi # Set environment variables az webapp config appsettings set \ --name $FRONTEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --settings \ VITE_API_URL="https://${BACKEND_APP_NAME}.azurewebsites.net/api" \ --output none # Enable HTTPS only az webapp update \ --name $FRONTEND_APP_NAME \ --resource-group $RESOURCE_GROUP \ --https-only true \ --output none echo -e "${GREEN}✓ Frontend configuration complete${NC}" echo "" echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}Setup Complete!${NC}" echo -e "${GREEN}========================================${NC}" echo "" echo -e "${YELLOW}Next Steps:${NC}" echo "" echo "1. Add secrets to Key Vault:" echo " az keyvault secret set --vault-name $KEY_VAULT_NAME --name SessionSecret --value \$(openssl rand -hex 32)" echo " az keyvault secret set --vault-name $KEY_VAULT_NAME --name JiraOAuthClientId --value " echo " az keyvault secret set --vault-name $KEY_VAULT_NAME --name JiraOAuthClientSecret --value " echo "" echo "2. Update backend app settings to use Key Vault references:" echo " See AZURE-NEW-SUBSCRIPTION-SETUP.md for details" echo "" echo "3. Build and push Docker images:" if [ -n "$ACR_NAME" ]; then echo " export ACR_NAME=\"$ACR_NAME\"" echo " ./scripts/build-and-push-azure.sh" else echo " export ACR_NAME=\"\"" echo " ./scripts/build-and-push-azure.sh" fi echo "" echo "4. Restart apps to pull images:" echo " az webapp restart --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP" echo " az webapp restart --name $FRONTEND_APP_NAME --resource-group $RESOURCE_GROUP" echo "" echo -e "${GREEN}Resource Information:${NC}" echo " Resource Group: $RESOURCE_GROUP" if [ -n "$ACR_LOGIN_SERVER" ]; then echo " ACR: $ACR_LOGIN_SERVER" echo " Repository: cmdb-insight (backend, frontend)" else echo " ACR: Not configured (configure manually)" fi echo " Database: $DB_HOST" echo " Key Vault: $KEY_VAULT_NAME" echo " Frontend URL: https://${FRONTEND_APP_NAME}.azurewebsites.net" echo " Backend URL: https://${BACKEND_APP_NAME}.azurewebsites.net/api" echo "" echo -e "${YELLOW}⚠️ Important: Save the database password securely!${NC}" echo " Password: $DB_ADMIN_PASSWORD" echo ""