Skip to content

Commit 02e0697

Browse files
Add bicep
1 parent bd50fa6 commit 02e0697

8 files changed

Lines changed: 223 additions & 17 deletions

File tree

ApiResources/TalentManagement-API

infra/main.bicep

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,12 @@ module identityApp 'modules/webApp.bicep' = {
7878
}
7979

8080
// ─── Angular Static Web App ───────────────────────────────────────────────────
81+
// Static Web Apps are not available in eastus — use eastus2
8182
module angularSwa 'modules/staticWebApp.bicep' = {
8283
name: 'angularSwa'
8384
params: {
8485
staticWebAppName: staticWebAppName
85-
location: location
86+
location: 'westus2'
8687
}
8788
}
8889

@@ -104,5 +105,3 @@ output apiAppUrl string = apiApp.outputs.url
104105
output identityAppUrl string = identityApp.outputs.url
105106
output angularAppUrl string = angularSwa.outputs.url
106107
output sqlServerFqdn string = sqlServer.outputs.sqlServerFqdn
107-
output apiDbConnectionString string = sqlServer.outputs.apiDbConnectionString
108-
output identityDbConnectionString string = sqlServer.outputs.identityDbConnectionString

infra/modules/appServicePlan.bicep

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
88
name: appServicePlanName
99
location: location
1010
sku: {
11-
name: 'B1'
12-
tier: 'Basic'
11+
name: 'F1'
12+
tier: 'Free'
1313
}
1414
properties: {
1515
reserved: false // Windows

infra/modules/sqlServer.bicep

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,5 @@ resource identityDatabase 'Microsoft.Sql/servers/databases@2023-05-01-preview' =
6969
}
7070

7171
output sqlServerFqdn string = sqlServer.properties.fullyQualifiedDomainName
72-
output apiDbConnectionString string = 'Server=tcp:${sqlServer.properties.fullyQualifiedDomainName},1433;Initial Catalog=${apiDbName};Persist Security Info=False;User ID=${sqlAdminLogin};Password=${sqlAdminPassword};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;'
73-
output identityDbConnectionString string = 'Server=tcp:${sqlServer.properties.fullyQualifiedDomainName},1433;Initial Catalog=${identityDbName};Persist Security Info=False;User ID=${sqlAdminLogin};Password=${sqlAdminPassword};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;'
72+
output apiDbName string = apiDbName
73+
output identityDbName string = identityDbName

infra/modules/webApp.bicep

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ param location string
77
@description('Resource ID of the App Service Plan')
88
param appServicePlanId string
99

10-
@description('Stack: dotnet, node, python, etc.')
11-
param linuxFxVersion string = ''
12-
1310
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
1411
name: webAppName
1512
location: location

infra/parameters/dev.bicepparam

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
// dev.bicepparam — parameter values for the dev environment
2-
// DO NOT add sqlAdminPassword here — pass it at deploy time from a GitHub Secret:
3-
// --parameters sqlAdminPassword=$SQL_ADMIN_PASSWORD
2+
// SQL password is read from the SQL_ADMIN_PASSWORD environment variable.
3+
// Set it before deploying: $env:SQL_ADMIN_PASSWORD = 'your-password'
44

55
using '../main.bicep'
66

77
// ─── Resource naming (Cloud Adoption Framework convention) ────────────────────
88
// Pattern: {type}-{workload}-{qualifier}-{env}
99

10-
param appServicePlanName = 'asp-talent-b1-dev'
10+
param appServicePlanName = 'asp-talent-f1-dev'
1111
param apiAppName = 'app-talent-api-dev'
1212
param identityAppName = 'app-talent-ids-dev'
1313
param staticWebAppName = 'swa-talent-ui-dev'
1414
param sqlServerName = 'sql-talent-dev'
1515
param apiDbName = 'sqldb-talent-api-dev'
1616
param identityDbName = 'sqldb-talent-ids-dev'
1717

18-
// ─── SQL admin login ──────────────────────────────────────────────────────────
19-
// Password is passed at deploy time — never stored here
20-
param sqlAdminLogin = 'sqladmin'
18+
// SQL admin credentials
19+
param sqlAdminLogin = 'sqladmin'
20+
param sqlAdminPassword = readEnvironmentVariable('SQL_ADMIN_PASSWORD')

infra/scripts/setup-azure.ps1

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# =============================================================================
2+
# setup-azure.ps1 - Deploy Azure infrastructure via Bicep
3+
# =============================================================================
4+
#
5+
# Provisions all Azure resources for the Talent Management full stack:
6+
# - App Service Plan (B1)
7+
# - Web App: Talent Management API (app-talent-api-dev)
8+
# - Web App: Duende IdentityServer (app-talent-ids-dev)
9+
# - Static Web App: Angular UI (swa-talent-ui-dev)
10+
# - Azure SQL Server (sql-talent-dev)
11+
# - SQL Database: API (sqldb-talent-api-dev)
12+
# - SQL Database: IdentityServer (sqldb-talent-ids-dev)
13+
#
14+
# Prerequisites:
15+
# az login
16+
# az account set --subscription "7d4355af-9f71-4123-8a18-aa68dc430bbf"
17+
# Resource group must exist (run setup-oidc.ps1 first)
18+
#
19+
# Usage (from repo root):
20+
# .\infra\scripts\setup-azure.ps1
21+
# =============================================================================
22+
23+
Set-StrictMode -Version Latest
24+
$ErrorActionPreference = "Stop"
25+
26+
# --- Configuration ------------------------------------------------------------
27+
$RESOURCE_GROUP = "rg-talent-dev"
28+
$RESOURCE_LOCATION = "westus3"
29+
$TEMPLATE_FILE = "infra/main.bicep"
30+
$PARAMETERS_FILE = "infra/parameters/dev.bicepparam"
31+
$SQL_ADMIN_PASSWORD = 'Tr@7vK#2mX$9pL4!'
32+
# ------------------------------------------------------------------------------
33+
34+
Write-Host ""
35+
Write-Host "========================================================"
36+
Write-Host " Azure Infrastructure Deployment"
37+
Write-Host " Resource Group: $RESOURCE_GROUP"
38+
Write-Host " Template: $TEMPLATE_FILE"
39+
Write-Host " Parameters: $PARAMETERS_FILE"
40+
Write-Host "========================================================"
41+
Write-Host ""
42+
43+
Write-Host ">>> Ensuring resource group exists in $RESOURCE_LOCATION..."
44+
45+
az group create `
46+
--name $RESOURCE_GROUP `
47+
--location $RESOURCE_LOCATION `
48+
--output none
49+
50+
Write-Host " Resource group ready: $RESOURCE_GROUP ($RESOURCE_LOCATION)"
51+
Write-Host ""
52+
Write-Host ">>> Deploying Bicep template..."
53+
54+
# Set env var so dev.bicepparam reads it via readEnvironmentVariable()
55+
$env:SQL_ADMIN_PASSWORD = $SQL_ADMIN_PASSWORD
56+
57+
$DEPLOYMENT = az deployment group create `
58+
--resource-group $RESOURCE_GROUP `
59+
--template-file $TEMPLATE_FILE `
60+
--parameters $PARAMETERS_FILE `
61+
--parameters "location=$RESOURCE_LOCATION" `
62+
--output json | ConvertFrom-Json
63+
64+
if (-not $DEPLOYMENT) {
65+
Write-Error "Deployment failed - no output returned from az CLI."
66+
exit 1
67+
}
68+
69+
Write-Host ""
70+
Write-Host "========================================================"
71+
Write-Host " Deployment Complete - Resource URLs"
72+
Write-Host "========================================================"
73+
Write-Host " API App: $($DEPLOYMENT.properties.outputs.apiAppUrl.value)"
74+
Write-Host " IdentityServer: $($DEPLOYMENT.properties.outputs.identityAppUrl.value)"
75+
Write-Host " Angular SWA: $($DEPLOYMENT.properties.outputs.angularAppUrl.value)"
76+
Write-Host " SQL FQDN: $($DEPLOYMENT.properties.outputs.sqlServerFqdn.value)"
77+
Write-Host "========================================================"

infra/scripts/setup-oidc.ps1

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# =============================================================================
2+
# setup-oidc.ps1 — One-time Azure OIDC setup for GitHub Actions (PowerShell)
3+
# =============================================================================
4+
#
5+
# Run this script ONCE per environment to wire up passwordless deployment.
6+
# It creates an App Registration, adds a Federated Identity Credential so
7+
# GitHub Actions can authenticate with Azure using short-lived OIDC tokens
8+
# (no stored passwords), and saves the three required values as GitHub secrets.
9+
#
10+
# Prerequisites:
11+
# az login (logged in to Azure CLI)
12+
# az account set --subscription "..." (correct subscription selected)
13+
# gh auth login (logged in to GitHub CLI)
14+
#
15+
# Usage:
16+
# .\infra\scripts\setup-oidc.ps1
17+
# =============================================================================
18+
19+
Set-StrictMode -Version Latest
20+
$ErrorActionPreference = "Stop"
21+
22+
# --- Configuration ------------------------------------------------------------
23+
# Edit these values before running.
24+
25+
$APP_NAME = "github-actions-talent-dev" # App Registration display name
26+
$RESOURCE_GROUP = "rg-talent-dev" # Resource group to manage
27+
$LOCATION = "eastus" # Azure region
28+
$GITHUB_ORG = "workcontrolgit" # GitHub organisation or username
29+
$GITHUB_REPO = "AngularNetTutorial" # GitHub repository name
30+
$BRANCH = "main" # Branch that triggers deployments
31+
$SQL_ADMIN_PASSWORD = 'Tr@7vK#2mX$9pL4!' # SQL admin password
32+
# ------------------------------------------------------------------------------
33+
34+
Write-Host ""
35+
Write-Host "========================================================"
36+
Write-Host " Azure OIDC Setup for GitHub Actions"
37+
Write-Host " App: $APP_NAME"
38+
Write-Host " Repo: $GITHUB_ORG/$GITHUB_REPO (branch: $BRANCH)"
39+
Write-Host " RG: $RESOURCE_GROUP ($LOCATION)"
40+
Write-Host "========================================================"
41+
Write-Host ""
42+
43+
# --- Step 1: Create App Registration ------------------------------------------
44+
Write-Host ">>> Step 1: Create App Registration"
45+
46+
$APP_ID = az ad app create `
47+
--display-name $APP_NAME `
48+
--query appId `
49+
--output tsv
50+
51+
Write-Host " Created App Registration: $APP_ID"
52+
53+
# --- Step 2: Create Service Principal -----------------------------------------
54+
Write-Host ">>> Step 2: Create Service Principal"
55+
56+
az ad sp create --id $APP_ID --output none
57+
58+
Write-Host " Service Principal created"
59+
60+
# --- Step 3: Add Federated Identity Credential --------------------------------
61+
Write-Host ">>> Step 3: Add Federated Identity Credential"
62+
63+
$TEMP_CRED_FILE = [System.IO.Path]::GetTempFileName() + ".json"
64+
@{
65+
name = "github-actions-branch-$BRANCH"
66+
issuer = "https://token.actions.githubusercontent.com"
67+
subject = "repo:${GITHUB_ORG}/${GITHUB_REPO}:ref:refs/heads/$BRANCH"
68+
audiences = @("api://AzureADTokenExchange")
69+
description = "GitHub Actions OIDC for $GITHUB_ORG/$GITHUB_REPO branch $BRANCH"
70+
} | ConvertTo-Json | Set-Content -Path $TEMP_CRED_FILE -Encoding UTF8
71+
72+
az ad app federated-credential create `
73+
--id $APP_ID `
74+
--parameters "@$TEMP_CRED_FILE" `
75+
--output none
76+
77+
Remove-Item $TEMP_CRED_FILE -Force
78+
79+
Write-Host " Federated credential added (branch: $BRANCH)"
80+
81+
# --- Step 4a: Create Resource Group -------------------------------------------
82+
Write-Host ">>> Step 4a: Create Resource Group (idempotent)"
83+
84+
az group create `
85+
--name $RESOURCE_GROUP `
86+
--location $LOCATION `
87+
--output none
88+
89+
Write-Host " Resource group ready: $RESOURCE_GROUP"
90+
91+
# --- Step 4b: Grant Contributor Role on Resource Group ------------------------
92+
Write-Host ">>> Step 4b: Grant Contributor role on $RESOURCE_GROUP"
93+
94+
$SUBSCRIPTION_ID = az account show --query id --output tsv
95+
$SCOPE = "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP"
96+
97+
az role assignment create `
98+
--assignee $APP_ID `
99+
--role "Contributor" `
100+
--scope $SCOPE `
101+
--output none
102+
103+
Write-Host " Contributor role granted on: $SCOPE"
104+
105+
# --- Step 5: Retrieve Tenant ID -----------------------------------------------
106+
$TENANT_ID = az account show --query tenantId --output tsv
107+
108+
# --- Step 6: Save Secrets to GitHub Repository --------------------------------
109+
Write-Host ">>> Step 6: Save secrets to GitHub repository"
110+
111+
gh secret set AZURE_CLIENT_ID --body $APP_ID --repo "${GITHUB_ORG}/${GITHUB_REPO}"
112+
gh secret set AZURE_TENANT_ID --body $TENANT_ID --repo "${GITHUB_ORG}/${GITHUB_REPO}"
113+
gh secret set AZURE_SUBSCRIPTION_ID --body $SUBSCRIPTION_ID --repo "${GITHUB_ORG}/${GITHUB_REPO}"
114+
gh secret set SQL_ADMIN_PASSWORD --body $SQL_ADMIN_PASSWORD --repo "${GITHUB_ORG}/${GITHUB_REPO}"
115+
116+
Write-Host " AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID, SQL_ADMIN_PASSWORD saved"
117+
118+
# --- Done ---------------------------------------------------------------------
119+
Write-Host ""
120+
Write-Host "========================================================"
121+
Write-Host " Summary"
122+
Write-Host "========================================================"
123+
Write-Host " AZURE_CLIENT_ID: $APP_ID"
124+
Write-Host " AZURE_TENANT_ID: $TENANT_ID"
125+
Write-Host " AZURE_SUBSCRIPTION_ID: $SUBSCRIPTION_ID"
126+
Write-Host " SQL_ADMIN_PASSWORD: (set)"
127+
Write-Host ""
128+
Write-Host " Verify all 4 secrets at:"
129+
Write-Host " https://github.com/${GITHUB_ORG}/${GITHUB_REPO}/settings/secrets/actions"
130+
Write-Host ""
131+
Write-Host " OIDC setup complete. GitHub Actions can now deploy to Azure"
132+
Write-Host " without any stored passwords or client secrets."
133+
Write-Host "========================================================"

0 commit comments

Comments
 (0)