feat: Enhance deployment automation and Bicep CLI prerequisites#585
feat: Enhance deployment automation and Bicep CLI prerequisites#585Tejasri-Microsoft wants to merge 20 commits into
Conversation
chore: Dev to main merge
chore: Dev merge to main
Adds Bicep CLI (v0.33.0+) to the local deployment prerequisites so users provisioning this accelerator locally have the required Bicep version installed before running 'azd up' / 'az deployment'. Work item: AB#42634
docs: Add Bicep CLI (v0.33.0+) to local deployment prerequisites
feat: Remove legacy Python schema support and add JSON Schema uploads
Adds infra/scripts/configure_auth.{sh,ps1} invoked at the end of the
azd postprovision hook so 'azd up' produces a fully authenticated
deployment without the manual steps in docs/ConfigureAppAuthentication.md.
Idempotent (reuses app regs persisted in azd env by appId, reuses
existing container app secrets) and skippable via AZURE_SKIP_AUTH_SETUP.
Covers:
- Web + API app registrations with redirect URIs, exposed scopes,
Graph User.Read, ID/access token issuance
- Best-effort admin consent with clear manual-action message on failure
- Container App EasyAuth Microsoft provider on both apps
- API authConfig allowedApplications = Web client id
- Web container env vars APP_WEB_CLIENT_ID / APP_WEB_SCOPE / APP_API_SCOPE
- Final lockdown: Web -> RedirectToLoginPage, API -> Return401
…ze issuer Three fixes discovered during end-to-end azd up testing: 1. `az containerapp auth microsoft update` rejects `--issuer` and `--tenant-id` together; the issuer is derived from tenant-id. 2. `azd env get-value AZURE_TENANT_ID` prints its error message to stdout (not stderr), corrupting TENANT_ID when that key is absent. Read from `az account show` first instead. 3. `--allowed-token-audiences api://<clientId>` breaks EasyAuth login because the ID tokens it issues have `aud=<clientId>` (GUID), not the identifierUri. Drop the override and normalize `allowedAudiences` to just the clientId via an authConfig PUT (which also clears stale values left by prior runs and fixes `openIdIssuer` if it was previously corrupted). Verified: Web `/.auth/login/aad` -> 302 to login.microsoftonline.com with the correct client_id, redirect_uri, and scopes; API returns 401 to unauthenticated callers; allowedApplications on the API restricts callers to the Web clientId.
Default app registrations have requestedAccessTokenVersion=null, which means Entra issues v1 access tokens with aud='api://<clientId>'. EasyAuth was configured with allowedAudiences=['<clientId>'] (bare GUID only), so every Web->API call failed audience validation and returned 401. Include both forms so the script works regardless of the app reg's accessTokenAcceptedVersion setting.
- DeploymentGuide.md §5.2 rewritten: describes the automatic flow, permission requirements, admin-consent failure handling, and the AZURE_SKIP_AUTH_SETUP escape hatch. - ConfigureAppAuthentication.md gets a banner making clear the manual steps are now a fallback (for tenants that block programmatic app registration or admin consent).
- Add bundle_info.json manifests for claim_date_of_loss and claim_hail - Add Step 4 to post_deployment.ps1 and post_deployment.sh - Creates claim batch with schemaset ID - Uploads files with mapped schema IDs - Submits batch for workflow processing - Update DeploymentGuide.md with new step and sample output - Update AVMPostDeploymentGuide.md with manual sample processing instructions - Normalize output prefixes: ASCII dashes for ps1, emojis for sh
configure_auth.sh / configure_auth.ps1:
- Set globalValidation (requireAuthentication, unauthenticatedClientAction,
redirectToProvider) directly in the authConfig PUT — the CLI flags were not
reliably populating redirectToProvider, leaving the Web app responding 401
to browser users instead of redirecting to AAD.
- Explicitly POST oauth2PermissionGrants to grant the API user_impersonation
scope to the Web service principal. 'az ad app permission admin-consent'
silently consents Microsoft Graph only and skips custom-API delegated
scopes, which made MSAL acquireTokenSilent fail and rendered a blank SPA
after successful login.
- Override APP_WEB_AUTHORITY env var on the Web container app so MSAL.js
uses a properly-formed authority URL.
- Restart Web + API container revisions after secrets/env updates so the
new values take effect without a manual restart.
infra/main.bicep:
- Drop redundant slash in APP_WEB_AUTHORITY composition; loginEndpoint
already has a trailing slash, so '${loginEndpoint}/${tenantId}' produced
a double-slash URL that broke MSAL.
infra/scripts/post_deployment.sh:
- Fix bash array iteration in Step 4b schema-id lookup. The previous
'for RID in $REGISTERED_IDS' de-references the array as a scalar (only
the first element), causing only one file per sample bundle to upload.
Switched to indexed iteration with ${!REGISTERED_IDS[@]} and a name
lookup against REGISTERED_NAMES[$i].
…-solution-accelerator into us-42666-pr565-followup
There was a problem hiding this comment.
Pull request overview
This PR refactors the solution’s deployment workflow to remove automatic post-provision actions and instead provide explicit, script-driven post-deployment steps (schema registration, sample data upload, and Entra ID auth setup), along with updated documentation and new helper/testing scripts.
Changes:
- Removed
azdpostprovision hooks so post-deployment actions are run manually via scripts. - Split/organized post-deployment into discrete scripts (schema registration, sample data upload, auth setup) and added preflight testing for auth setup.
- Updated docs and fixed an
APP_WEB_AUTHORITYconcatenation issue in the Bicep template.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ContentProcessorAPI/samples/claim_hail/bundle_info.json | Adds bundle manifest mapping sample files to schema classes. |
| src/ContentProcessorAPI/samples/claim_date_of_loss/bundle_info.json | Adds bundle manifest mapping sample files to schema classes. |
| README.md | Documents Bicep CLI prerequisite and new manual post-deployment requirement. |
| infra/scripts/upload_sample_data.sh | Adds POSIX wrapper to run post-deployment in sample-data mode. |
| infra/scripts/upload_sample_data.ps1 | Adds PowerShell wrapper to run post-deployment in sample-data mode. |
| infra/scripts/test_configure_auth_preflight.sh | Adds bash-based mocked tests for configure_auth.sh --preflight-only. |
| infra/scripts/test_configure_auth_preflight.ps1 | Adds PowerShell-based mocked tests for configure_auth.ps1 --preflight-only. |
| infra/scripts/setup_auth.sh | Adds POSIX wrapper to run auth configuration script. |
| infra/scripts/setup_auth.ps1 | Adds PowerShell wrapper to run auth configuration script. |
| infra/scripts/run_post_deployment.sh | Adds orchestrator script to run schema registration, sample upload, and auth setup with skip flags. |
| infra/scripts/run_post_deployment.ps1 | Adds orchestrator script to run schema registration, sample upload, and auth setup with skip flags. |
| infra/scripts/register_schemas.sh | Adds POSIX wrapper to run post-deployment in schema-only mode. |
| infra/scripts/register_schemas.ps1 | Adds PowerShell wrapper to run post-deployment in schema-only mode. |
| infra/scripts/post_deployment.sh | Adds POST_DEPLOYMENT_MODE behavior and logic to resolve/upload sample bundles. |
| infra/scripts/post_deployment.ps1 | Adds POST_DEPLOYMENT_MODE behavior and logic to resolve/upload sample bundles. |
| infra/scripts/configure_auth.sh | Adds idempotent Entra app registration + EasyAuth automation with preflight checks. |
| infra/scripts/configure_auth.ps1 | Adds idempotent Entra app registration + EasyAuth automation with preflight checks. |
| infra/main.bicep | Fixes APP_WEB_AUTHORITY value concatenation. |
| docs/DeploymentGuide.md | Updates guide to reflect manual post-deployment scripts and Bicep prerequisite. |
| docs/CustomizeSchemaData.md | Updates links and notes related to schema registration workflow. |
| docs/ConfigureAppAuthentication.md | Adds “recommended script-first” guidance for auth setup. |
| docs/AVMPostDeploymentGuide.md | Updates AVM post-deployment guidance to include sample processing and manual steps. |
| azure.yaml | Removes automatic postprovision hook. |
| azure_custom.yaml | Removes automatic postprovision hook. |
Comments suppressed due to low confidence (5)
infra/scripts/run_post_deployment.sh:120
- This
sed -iusage will fail on macOS (BSD sed requires-i ''). Because this script targets macOS/Linux, consider using an OS-conditional in-place edit or a portable line-ending normalization method.
if [[ ! -f "$STEP2_SCRIPT" ]]; then
echo " ❌ Script not found: $STEP2_SCRIPT" >&2
exit 1
fi
sed -i 's/\r$//' "$STEP2_SCRIPT"
chmod +x "$STEP2_SCRIPT"
infra/scripts/run_post_deployment.sh:167
- This
sed -iusage will fail on macOS (BSD sed requires-i ''). Because this script targets macOS/Linux, consider using an OS-conditional in-place edit or a portable line-ending normalization method.
if [[ ! -f "$STEP3_SCRIPT" ]]; then
echo " ❌ Script not found: $STEP3_SCRIPT" >&2
exit 1
fi
sed -i 's/\r$//' "$STEP3_SCRIPT"
chmod +x "$STEP3_SCRIPT"
docs/DeploymentGuide.md:351
- The macOS/Linux instructions use
sed -iwithout a backup suffix, which will fail on macOS (BSD sed). Please adjust the docs to a portable command (e.g.,sed -i ''on macOS) or provide an OS-conditional snippet.
**macOS/Linux:**
```bash
sed -i 's/\r$//' ./infra/scripts/upload_sample_data.sh
bash ./infra/scripts/upload_sample_data.sh
docs/DeploymentGuide.md:369
- The macOS/Linux instructions use
sed -iwithout a backup suffix, which will fail on macOS (BSD sed). Please adjust the docs to a portable command (e.g.,sed -i ''on macOS) or provide an OS-conditional snippet.
```bash
sed -i 's/\r$//' ./infra/scripts/setup_auth.sh
bash ./infra/scripts/setup_auth.sh
**infra/scripts/configure_auth.sh:369**
* `/proc/sys/kernel/random/uuid` is Linux-specific and will fail on macOS. Since this script is intended for macOS/Linux, use a portable UUID source (e.g., `uuidgen`, or `python -c 'import uuid; print(uuid.uuid4())'`).
WEB_SCOPE_ID="$(az ad app show --id "$WEB_CLIENT_ID"
--query "api.oauth2PermissionScopes[?value=='user_impersonation'].id | [0]" -o tsv)"
[[ -z "$WEB_SCOPE_ID" || "$WEB_SCOPE_ID" == "null" ]] && WEB_SCOPE_ID="$(cat /proc/sys/kernel/random/uuid)"
</details>
---
💡 <a href="/microsoft/content-processing-solution-accelerator/new/dev?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 24 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (1)
infra/scripts/test_configure_auth_preflight.ps1:159
- Hard-coding
pwshhere makes the test runner fail on systems that only have Windows PowerShell (powershell) available (despite#Requires -Version 5.1). Consider invoking& $Subjectdirectly (current host), or selectingpwshvspowershellbased on availability.
$origPath = $env:PATH
$env:PATH = "$TempDir;$env:PATH"
$env:AZ_MOCK_SCENARIO = $AzScenario
$env:AZD_MOCK_SCENARIO = $AzdScenario
$env:AZURE_SKIP_AUTH_SETUP = ""
$rawOutput = pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass `
-File $Subject "--preflight-only" 2>&1
$exitCode = $LASTEXITCODE
| exit 1 | ||
| fi | ||
|
|
||
| sed -i 's/\r$//' "$STEP1_SCRIPT" |
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| sed -i 's/\r$//' "$SCRIPT_DIR/post_deployment.sh" |
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| sed -i 's/\r$//' "$SCRIPT_DIR/post_deployment.sh" |
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| sed -i 's/\r$//' "$SCRIPT_DIR/configure_auth.sh" |
| if [[ -z "$roles" ]]; then | ||
| _check WARN "Entra directory roles resolvable" \ | ||
| "Could not enumerate roles. The script will continue; exact permission errors will surface at runtime." | ||
| elif ! echo "$roles" | grep -Eiq 'Global Administrator|Application Administrator|Cloud Application Administrator'; then | ||
| _check FAIL "App-registration permission (Application Administrator or higher)" \ | ||
| "Assign 'Application Administrator' (or higher) in Entra ID, then re-run.\n Portal: https://entra.microsoft.com → Roles and administrators" | ||
| fatal=true | ||
| else | ||
| _check PASS "App-registration permission (Application Administrator or higher)" | ||
|
|
||
| if ! echo "$roles" | grep -Eiq 'Global Administrator|Cloud Application Administrator'; then | ||
| CONSENT_PRECHECK_OK=false | ||
| _check WARN "Admin-consent permission (Cloud Application Administrator or higher)" \ | ||
| "Admin consent step will be attempted but may fail. A tenant admin can grant consent at:\n https://login.microsoftonline.com/${TENANT_ID}/adminconsent?client_id=<web-client-id>" | ||
| else |
| @@ -0,0 +1,256 @@ | |||
| #Requires -Version 5.1 | |||
| if [ "$(uname)" = "Darwin" ]; then | ||
| sed -i '' 's/\r$//' ./infra/scripts/register_schemas.sh | ||
| else | ||
| sed -i 's/\r$//' ./infra/scripts/register_schemas.sh | ||
| fi |
This pull request refactors the deployment and post-deployment workflow for the Content Processing Solution Accelerator, making post-deployment steps more modular, manual, and idempotent. It removes automatic post-provision hooks from the deployment YAMLs, updates documentation to reflect the new manual script-based approach, and improves the clarity and flexibility of post-deployment scripts. The changes aim to give users more control, clearer guidance, and easier troubleshooting for schema registration, sample data upload, and authentication setup.
Deployment and Post-Deployment Workflow Refactor:
azure.yamlandazure_custom.yaml, so schema registration, sample data upload, and authentication setup are now performed via explicit manual scripts after deployment. [1] [2]infra/scripts/post_deployment.ps1to support a newPOST_DEPLOYMENT_MODEenvironment variable, allowing users to run schema registration and sample data upload independently or together. Improved output formatting and added logic to resolve existing schemas and schema sets when running in sample-data mode. [1] [2] [3] [4] [5]Documentation Updates:
README.md,DeploymentGuide.md,AVMPostDeploymentGuide.md,CustomizeSchemaData.md,ConfigureAppAuthentication.md) to instruct users to run manual scripts for schema registration, sample data upload, and authentication. Clarified that these steps are now manual and idempotent, and provided detailed instructions for both Windows and macOS/Linux. [1] [2] [3] [4] [5] [6] [7]Infrastructure and Requirements:
Minor Fixes:
infra/main.bicepfile for theAPP_WEB_AUTHORITYenvironment variable to correct the URL concatenation.Most important changes:
1. Deployment workflow and script improvements
azure.yamlandazure_custom.yaml; all post-deployment steps are now manual and script-driven. [1] [2]infra/scripts/post_deployment.ps1to support modular execution (schema registration and sample data upload separately), improved output, and idempotency. [1] [2] [3] [4] [5]2. Documentation and guidance updates
3. Infrastructure requirements
4. Minor bug fix
APP_WEB_AUTHORITYvalue ininfra/main.bicepto correctly concatenate the login endpoint and tenant ID.## PurposeDoes this introduce a breaking change?
Golden Path Validation
Deployment Validation
What to Check
Verify that the following are valid
Other Information