@Subhash Chand You do not need to create a new VM image every day we can suggest using the image as a stable base and deploy app changes via automation on top of the VMSS - https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-deploy-app
Do I need a new image per code change - Microsoft shows two main options for VMSS app deployment:
- custom image with app preinstalled, or
- base image + install or update scripts orextensions
Always Use VMSS with immutable base images: OS, security hardening, monitoring agents, Node.js runtimes and common tools.
- Deploy app versions through automated mechanisms - Create and deploy VM Application - https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=TAR%2Ccli1%2Ccli2%2Crest3%2Crest4
- Custom Script Extension to download and install/update the app.
- VM Applications to package the app, upload to Storage, and assign that VM Application version to the VMSS. Use VMSS upgrade policy to roll changes through instances, combined with health checks.
Immutable vs fully baked images - Both are valid and the choice is about cadence and complexity.
- Immutable base image (OS and runtime only)
- Image updated when OS,Node,runtime,baseline changes.
- App code delivered via scripts,extensions,VM Applications.
- This is best when you deploy code often and want fast iterations without image churn.
Fully baked image (OS and app)
- CI pipeline builds app, creates/validates an image (e.g., Packer), then VMSS upgrades to this image. Very fast scale-out, simple runtime, and easy rollback by switching to previous image version.
- This is best when you want strict immutability and can afford an image build pipeline per release.
- For your daily pushes, 12 apps, no containers scenario, base image + app deployment (extensions/VM Applications) is typically more practical
For deploying of frequent updates to multiple Node.js apps
Build Node.js projects in CI (npm install, npm run build, tests), then publish artifacts (zip/tar with compiled JS and minimal node_modules) to Storage or artifact reposiory.
For VMSS: Always use Custom Script Extension configuration (JSON) that pulls the right artifact version and swaps symlink or folder, then restarts services or define a VM Application version that contains payload + install/update scripts and assign it to the VMSS application Profile. - https://docs.azure.cn/en-us/virtual-machines/extensions/custom-script-linux
Then, reapply extension or update VM Application version when you deploy a new build. VMSS then updates instances according to the upgrade policy - https://docs.azure.cn/en-us/virtual-machine-scale-sets/tutorial-install-apps-cli
For handling different build requirements (12 projects) - Standardize runtimes on the base image and install all required Node.js versions and shared tools (pm2, systemd units, reverse proxy) in the image - https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/
Keep per-project logic in scripts:
- One bootstrap script that, for each project, downloads its artifact, applies config, and restarts that project’s service.
- Services defined per app (systemd units or pm2 processes) so you don’t restart everything for one change.
- Projects that only need “runtime execution” just get their pre-built artifact; projects that need a build step get it done in CI, not on the VM.