After Lab 3.6 — Recap
After Lab 3.6 — Recap
You verified that the pipeline builds once, publishes an artifact, and deploys the exact same artifact to dev, test, and production environments without rebuilding.
What You Should Understand
Build-Once-Promote-Many in Action
Guarantee: Production runs the exact code that passed tests and security scans in the Build stage. No rebuilds, no time drift, no dependency changes between environments.
Artifact Metadata Enables Traceability
When investigating a production issue:
# In deployment logs
cat BUILD_COMMIT # Shows: abc123def456789
cat BUILD_VERSION # Shows: 456
cat BUILD_NUMBER # Shows: 1.2.3-20260531.1You can now answer:
- Which commit is deployed? →
abc123 - Which build created it? → Build #456
- Which tests passed? → Check build #456 test results in Azure DevOps
- Which security scans cleared it? → Check build #456 artifact
security-reports/
No guesswork — full audit trail from code to production.
Reflection Questions
What happens if you rebuild the application for each environment instead of promoting an artifact?
Risks:
Time drift: Dev deployed Monday, prod deployed Friday — npm pulled different dependency versions (potential new vulnerabilities introduced)
Untested code in production: The artifact deployed to prod was never tested in dev or test — it's a fresh build with potentially different behavior
No traceability: Cannot prove production runs the same code that passed security scans
Real-world incident: A team rebuilt for prod on Friday. Between Tuesday (when dev was built) and Friday, a critical CVE was published. Friday's build pulled the vulnerable version, bypassing all prior security scans. Production breach.
How do you handle environment-specific configuration if the artifact is immutable?
Externalize configuration via:
- Environment variables (injected at deployment)
appSettings: |
-NODE_ENV production
-DATABASE_URL $(PROD_DATABASE_URL)
-FRONTEND_ORIGIN https://app.example.com- Azure App Configuration (runtime lookup)
import { AppConfigurationClient } from "@azure/app-configuration";
const config = await client.getConfigurationSetting({ key: "DatabaseUrl" });- Key Vault references (secure secrets)
appSettings: |
-DATABASE_PASSWORD @Microsoft.KeyVault(SecretUri=https://vault.vault.azure.net/secrets/db-password)Artifact contains code, not configuration. Configuration is injected per environment.
Should you use the same pipeline for hotfixes and regular releases?
Yes, but with branching strategy:
Regular release: Feature branch → main → pipeline (build → dev → test → prod)
Hotfix: Hotfix branch → main → pipeline (build → dev → test → prod)
Critical principle: Never skip stages. Even hotfixes must:
- Build artifact
- Run tests and security scans
- Deploy to dev
- Validate in test (maybe expedited approval)
- Deploy to prod
Never manually patch production — always flow through the pipeline.
Common Issues
| Issue | Symptom | Cause | Fix |
|---|---|---|---|
| Artifact metadata shows wrong commit SHA | BUILD_COMMIT doesn't match git log | Pipeline ran on detached HEAD or cached source | Ensure pipeline checks out with fetchDepth: 1 and uses $(Build.SourceVersion) variable |
| Deployment stage rebuilds instead of downloading | npm run build in DeployDev stage | Deployment stage missing DownloadPipelineArtifact task | Remove build tasks from deployment stages, only download artifact |
| Artifact not found in Test stage | Artifact 'backend-app' not found | Build stage failed or artifact name mismatch | Verify Build stage succeeded, check artifactName: matches between publish and download |
| Environment-specific config hardcoded in artifact | Prod uses dev database URL | Config in source code, not externalized | Move to environment variables or Key Vault, inject at deployment time |
| Cannot trace deployed artifact to source commit | No metadata files in artifact | echo BUILD_COMMIT step missing or ran after artifact publish | Ensure metadata creation runs before PublishPipelineArtifact task |
Bridge to Day 3 Wrap-Up
You now have a complete DevSecOps pipeline: quality gates, security scans, artifact promotion, and traceability. Time to reflect on what you've learned and prepare for Day 4.