Skip to main content

Azure Deployment

This guide covers provisioning all Azure resources for NextGenPoll and wiring up CI/CD.


Azure Resources

ResourceNameSKU / Tier
Resource Grouprg-nextgenpoll
App Service Planasp-nextgenpollB3 Linux
App Service (backend)nextgenpoll-apiJava 25
App Service (frontend)nextgenpoll-webNode 24 LTS
PostgreSQL Flexible Servernextgenpoll-dbBurstable B1ms
Azure AI Servicesnextgenpoll-aiS0 (westus2)
Communication Servicesacs-nextgenpoll
Email Communication Serviceacs-mail
Static Web Appnextgenpoll-docsFree

The repository includes a clean, parameterized Bicep template in infra/.

infra/
├── main.bicep ← clean infrastructure definition
├── main.bicepparam ← parameter values (safe to commit, no secrets)
└── main.exported.bicep ← raw portal export for reference

Step A1 — Create the resource group

az login
az group create \
--name rg-nextgenpoll \
--location "North Central US"

Step A2 — Deploy the template

az deployment group create \
--resource-group rg-nextgenpoll \
--template-file infra/main.bicep \
--parameters infra/main.bicepparam \
--parameters dbAdminPassword="<strong-password>"
Password requirements

The PostgreSQL admin password must be 8–128 characters and contain uppercase, lowercase, a digit, and a special character. Do not commit it to main.bicepparam.

The deployment takes ~5–10 minutes. When complete you'll see outputs:

backendAppUrl = https://nextgenpoll-api.azurewebsites.net
frontendAppUrl = https://nextgenpoll-web.azurewebsites.net
postgresHost = nextgenpoll-db.postgres.database.azure.com
aiEndpoint = https://nextgenpoll-ai.cognitiveservices.azure.com/

Step A3 — Skip to post-deploy steps

Bicep provisions all core infrastructure. Continue at Step 4 — Configure Custom Domains.


Option B — Azure CLI (manual step-by-step)

Step 1 — Create the resource group

az group create \
--name rg-nextgenpoll \
--location "North Central US"

Step 2 — App Service Plan

az appservice plan create \
--name asp-nextgenpoll \
--resource-group rg-nextgenpoll \
--sku B3 \
--is-linux

Step 3A — Backend App Service

az webapp create \
--name nextgenpoll-api \
--resource-group rg-nextgenpoll \
--plan asp-nextgenpoll \
--runtime "JAVA:25-java25"

az webapp config set \
--name nextgenpoll-api \
--resource-group rg-nextgenpoll \
--startup-file "java -jar /home/site/wwwroot/app.jar"

Set required application settings:

az webapp config appsettings set \
--name nextgenpoll-api \
--resource-group rg-nextgenpoll \
--settings \
SPRING_PROFILES_ACTIVE=prod \
SPRING_DATASOURCE_URL="jdbc:postgresql://<db-host>:5432/nextgenpoll?sslmode=require" \
SPRING_DATASOURCE_USERNAME="<db-username>" \
SPRING_DATASOURCE_PASSWORD="<db-password>" \
AZURE_TENANT_ID="<ciam-tenant-id>" \
AZURE_OPENAI_ENDPOINT="<openai-endpoint>" \
AZURE_OPENAI_API_KEY="<openai-key>" \
AZURE_COMMUNICATION_CONNECTION_STRING="<acs-connection-string>" \
ALLOWED_ORIGINS="https://nextgenpoll.com,https://www.nextgenpoll.com"

Step 3B — Frontend App Service

az webapp create \
--name nextgenpoll-web \
--resource-group rg-nextgenpoll \
--plan asp-nextgenpoll \
--runtime "NODE:24-lts"

az webapp config set \
--name nextgenpoll-web \
--resource-group rg-nextgenpoll \
--startup-file "node /home/site/wwwroot/server.js"

Step 3C — PostgreSQL Flexible Server

az postgres flexible-server create \
--name nextgenpoll-db \
--resource-group rg-nextgenpoll \
--location "North Central US" \
--admin-user db_admin \
--admin-password "<strong-password>" \
--sku-name Standard_B1ms \
--tier Burstable \
--version 17 \
--public-access 0.0.0.0

az postgres flexible-server db create \
--server-name nextgenpoll-db \
--resource-group rg-nextgenpoll \
--database-name nextgenpoll
Tighten firewall post-deploy

Replace 0.0.0.0 with App Service outbound IPs:

az webapp show --name nextgenpoll-api --resource-group rg-nextgenpoll \
--query outboundIpAddresses --output tsv

Step 4 — Configure Custom Domains

Backend API (api.nextgenpoll.com)

az webapp config hostname add \
--webapp-name nextgenpoll-api \
--resource-group rg-nextgenpoll \
--hostname api.nextgenpoll.com

Create a CNAME record: apinextgenpoll-api.azurewebsites.net

Frontend (nextgenpoll.com and www.nextgenpoll.com)

az webapp config hostname add \
--webapp-name nextgenpoll-web \
--resource-group rg-nextgenpoll \
--hostname nextgenpoll.com

az webapp config hostname add \
--webapp-name nextgenpoll-web \
--resource-group rg-nextgenpoll \
--hostname www.nextgenpoll.com

Docs (docs.nextgenpoll.com)

Create the Static Web App in the Azure Portal (not CLI) so you can link GitHub during creation — this automatically adds the AZURE_STATIC_WEB_APPS_API_TOKEN_* secret to your repo:

  1. In the portal, search Static Web AppsCreate
  2. Select resource group rg-nextgenpoll, name it nextgenpoll-docs, region East US 2, plan Free
  3. Set Deployment source to GitHub, authorize, and select the repo/branch
  4. Leave build details blank — docs-cd.yml handles the actual build and deploy
  5. After creation, go to Custom domains → add docs.nextgenpoll.com
Auto-generated workflow

The portal will add a workflow file like azure-static-web-apps-*.yml to your repo. Delete it — docs-cd.yml is already configured correctly.

git rm .github/workflows/azure-static-web-apps-*.yml

Create a CNAME record: docs → the SWA default hostname (shown in portal after provisioning).


Step 7 — Get Publish Profiles

Download the publish profiles and add them as GitHub secrets:

# Backend publish profile
az webapp deployment list-publishing-profiles \
--name nextgenpoll-api \
--resource-group rg-nextgenpoll \
--xml > backend-publish-profile.xml

# Frontend publish profile
az webapp deployment list-publishing-profiles \
--name nextgenpoll-web \
--resource-group rg-nextgenpoll \
--xml > frontend-publish-profile.xml

Add the contents of each XML file as:

  • AZURE_BACKEND_PUBLISH_PROFILE
  • AZURE_FRONTEND_PUBLISH_PROFILE
Security

Delete the local XML files after uploading to GitHub secrets. They contain deployment credentials.


Step 8 — Set Remaining GitHub Secrets

Set all remaining secrets listed in Environment Variables → GitHub Actions Secrets.


Step 9 — First Deploy

Trigger a manual deployment from GitHub Actions:

  1. Go to Actions → Backend CDRun workflow.
  2. Go to Actions → Frontend CDRun workflow.
  3. Go to Actions → Docs CDRun workflow.

After a successful deploy, verify:

URLExpected
https://api.nextgenpoll.com/api/health{"status":"UP","service":"nextgenpoll-api"}
https://nextgenpoll.comHome page loads
https://docs.nextgenpoll.comDocumentation site loads