Is your feature request related to a problem?
When azd deploy runs a multi-service project, each service is built, pushed to ACR, and deployed sequentially. If the deployment fails partway through (e.g. service A deploys successfully but service B fails), the SERVICE_B_IMAGE_NAME env var points to the newly pushed image that was never verified in production.
On the next azd provision, Bicep picks up SERVICE_B_IMAGE_NAME and configures the infrastructure with an image that was never successfully deployed. This can cause the provisioned infrastructure to reference a broken or untested image.
There is currently no distinction between "the image azd most recently pushed" and "the image that was last confirmed working in a successful deploy." Projects that need this safety guarantee must build custom hook scripts to seed and track known-good image state, which is boilerplate that belongs in the CLI.
Describe the solution you'd like
After each service completes its deploy lifecycle successfully, azd should persist a LAST_SUCCESSFUL_{SERVICE}_IMAGE_NAME env var (or equivalent state). During provisioning, Bicep templates could reference this known-good image as a fallback, so that a failed deploy doesn't leave infrastructure pointing at an unverified image.
Concretely:
- After a service deploy succeeds, write
LAST_SUCCESSFUL_{SERVICE}_IMAGE_NAME = {image} to the azd environment.
- Expose this value alongside
SERVICE_{SERVICE}_IMAGE_NAME so Bicep can use a pattern like coalesce(candidateImage, lastSuccessfulImage).
- On first deploy (no prior state), seed from the live Azure resource if one exists (read the current container image from the running App Service / Container App).
Describe alternatives you considered
- Custom preprovision/postdeploy hooks that shell out to
az webapp config container show / az containerapp show to read live images and store them in azd env vars. This works but adds 100+ lines of cross-platform scripts (PowerShell + Bash) per project, queries Azure resources directly (fragile to naming conventions), and duplicates logic that azd already has internally.
- Always using
latest tag and relying on ACR immutability policies. This doesn't solve the "which image was last known-good" problem, just the tag collision problem.
- Manual rollback via
azd deploy --from-image. This requires operator intervention and doesn't prevent the next azd provision from picking up the bad image.
Additional context
azd already writes SERVICE_{SERVICE}_IMAGE_NAME in service_target_containerapp.go and service_target_appservice.go via SetServiceProperty. The proposed LAST_SUCCESSFUL_* tracking would follow the same pattern, gated on deploy success. This would complement the existing SERVICE_*_IMAGE_NAME rather than replacing it.
Is your feature request related to a problem?
When
azd deployruns a multi-service project, each service is built, pushed to ACR, and deployed sequentially. If the deployment fails partway through (e.g. service A deploys successfully but service B fails), theSERVICE_B_IMAGE_NAMEenv var points to the newly pushed image that was never verified in production.On the next
azd provision, Bicep picks upSERVICE_B_IMAGE_NAMEand configures the infrastructure with an image that was never successfully deployed. This can cause the provisioned infrastructure to reference a broken or untested image.There is currently no distinction between "the image azd most recently pushed" and "the image that was last confirmed working in a successful deploy." Projects that need this safety guarantee must build custom hook scripts to seed and track known-good image state, which is boilerplate that belongs in the CLI.
Describe the solution you'd like
After each service completes its deploy lifecycle successfully, azd should persist a
LAST_SUCCESSFUL_{SERVICE}_IMAGE_NAMEenv var (or equivalent state). During provisioning, Bicep templates could reference this known-good image as a fallback, so that a failed deploy doesn't leave infrastructure pointing at an unverified image.Concretely:
LAST_SUCCESSFUL_{SERVICE}_IMAGE_NAME = {image}to the azd environment.SERVICE_{SERVICE}_IMAGE_NAMEso Bicep can use a pattern likecoalesce(candidateImage, lastSuccessfulImage).Describe alternatives you considered
az webapp config container show/az containerapp showto read live images and store them in azd env vars. This works but adds 100+ lines of cross-platform scripts (PowerShell + Bash) per project, queries Azure resources directly (fragile to naming conventions), and duplicates logic that azd already has internally.latesttag and relying on ACR immutability policies. This doesn't solve the "which image was last known-good" problem, just the tag collision problem.azd deploy --from-image. This requires operator intervention and doesn't prevent the nextazd provisionfrom picking up the bad image.Additional context
azd already writes
SERVICE_{SERVICE}_IMAGE_NAMEinservice_target_containerapp.goandservice_target_appservice.goviaSetServiceProperty. The proposedLAST_SUCCESSFUL_*tracking would follow the same pattern, gated on deploy success. This would complement the existingSERVICE_*_IMAGE_NAMErather than replacing it.