Azure Deployment
This guide covers provisioning all Azure resources for NextGenPoll and wiring up CI/CD.
Azure Resources
| Resource | Name | SKU / Tier |
|---|---|---|
| Resource Group | rg-nextgenpoll | — |
| App Service Plan | asp-nextgenpoll | B3 Linux |
| App Service (backend) | nextgenpoll-api | Java 25 |
| App Service (frontend) | nextgenpoll-web | Node 24 LTS |
| PostgreSQL Flexible Server | nextgenpoll-db | Burstable B1ms |
| Azure AI Services | nextgenpoll-ai | S0 (westus2) |
| Communication Services | acs-nextgenpoll | — |
| Email Communication Service | acs-mail | — |
| Static Web App | nextgenpoll-docs | Free |
Option A — Bicep (recommended)
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>"
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
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: api → nextgenpoll-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:
- In the portal, search Static Web Apps → Create
- Select resource group
rg-nextgenpoll, name itnextgenpoll-docs, region East US 2, plan Free - Set Deployment source to GitHub, authorize, and select the repo/branch
- Leave build details blank —
docs-cd.ymlhandles the actual build and deploy - After creation, go to Custom domains → add
docs.nextgenpoll.com
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_PROFILEAZURE_FRONTEND_PUBLISH_PROFILE
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:
- Go to Actions → Backend CD → Run workflow.
- Go to Actions → Frontend CD → Run workflow.
- Go to Actions → Docs CD → Run workflow.
After a successful deploy, verify:
| URL | Expected |
|---|---|
| https://api.nextgenpoll.com/api/health | {"status":"UP","service":"nextgenpoll-api"} |
| https://nextgenpoll.com | Home page loads |
| https://docs.nextgenpoll.com | Documentation site loads |