All blueprints

Production Blueprint · Real-world pipeline

From commit to production: .NET 8 + Angular 20 on Azure Windows VMs

A working dev-to-production setup, end to end: GitHub, Jenkins, SonarQube, Nexus and Jira on the delivery side, Ansible AWX deploying to IIS on Windows VMs across five environments.

GitHubJenkinsSonarQubeNexusJiraAnsible AWXAzure Windows VMIIS.NET 8Angular 20

The platform

Who talks to whom. Click any tool to open its guide.

Build once, deploy many

Only the dev job builds. Every higher environment deploys the exact package that dev already published to Nexus, after a Jira approval.

Dev

builds + deploys

Jira approval

SIT

deploys only

Jira approval

UAT

deploys only

Jira approval

Stage

deploys only

Jira approval

Prod

deploys only

The same Nexus package version travels through all five environments. Nothing is rebuilt, so what was tested is what ships.

Whether the jobs share one scalable template or each environment has its own branch and Jenkins job, the rule is the same: the dev job builds, and every higher job starts at deployment.

Inside the pipeline

Pick an environment to see which Jenkins stages actually run there, then a stage for the detail. Dev runs nine stages; every higher environment runs five.

Triggered by a commit to the dev branch. Builds, tests, scans, publishes to Nexus and deploys to dev.

Preload

Get the job ready before touching any code.

  • Load the environment parameters and credentials from Jenkins.
  • Confirm the .NET 8 SDK and the Node toolchain are available on the agent.
  • Start from a clean workspace.

What AWX does on the VM

The API and the UI each have their own deployment playbook, in the order they run. The same playbooks serve every environment; only the target VM and its variables change.

Backs up the running release first, and only stops the app pool once the new package is downloaded and extracted, so the API is down for the shortest possible window.

  1. Check connectivity

    Confirm AWX can reach the Windows VM over WinRM before anything is changed.

    Fails when
    The VM is stopped or deallocated, a network rule blocks WinRM, or the credentials are wrong or expired.
    Check first
    VM state in the Azure portal, then network security rules and the WinRM connection from AWX.
  2. Get root folder for backup

    Work out where backups live for this application and environment.

    Fails when
    The backup path variable is missing or wrong for this environment.
    Check first
    The environment's variables in the AWX inventory.
  3. Create backup folder if it does not exist

    Create the backup folder on first use.

    Fails when
    The deploy account can't create folders at the backup path.
    Check first
    The backup path and its permissions.
  4. Copy deployment folder to backup folder

    Save the currently deployed release aside before anything is replaced.

    Fails when
    The disk is full, or files in the deployment folder are locked.
    Check first
    Free disk space on the backup drive.
  5. Create deployment folder

    Create the deployment folder if it doesn't exist yet, so a brand-new VM works on its first deploy.

    Fails when
    The deploy account can't create folders at that path.
    Check first
    The folder path variable for this environment, and the deploy account's permissions.
  6. Create temp folder

    Create a temporary working folder for this release's download and extraction.

    Fails when
    The disk is full or the deploy account lacks permission.
    Check first
    Free disk space and folder permissions.
  7. Clean content from AWX folder

    Empty the AWX working folder so leftovers from an earlier run can't be mistaken for this release.

    Fails when
    Files from a previous run are locked or the account lacks permission to delete them.
    Check first
    What is still in the folder and which process holds it.
  8. Download from Nexus

    Fetch the exact package version being deployed from the Nexus repository.

    Fails when
    The version doesn't exist, Nexus is unreachable, or the download credentials lack permission.
    Check first
    Is that exact version listed in Nexus? Can the VM reach Nexus?
  9. Unzip

    Extract the downloaded package.

    Fails when
    The download was incomplete or corrupt, or the disk is full.
    Check first
    Does the downloaded archive open by hand? Free disk space.
  10. Stop app pool

    Stop the API's app pool so IIS releases every file in the deployment folder. From here until the pool restarts, the API is down.

    Fails when
    The pool hangs while stopping, or the worker process won't exit.
    Check first
    IIS Manager and the w3wp process for that pool.
  11. Clean content from deployment folder

    Remove the previous release's files so old and new files never mix.

    Fails when
    A file is still locked, or the deploy account lacks permission.
    Check first
    What holds the file, and the folder permissions.
  12. Copy to deployment folder

    Put the new release's files into the deployment folder.

    Fails when
    The disk is full or permissions are wrong. The pool is already stopped, so restore from the backup if it can't be fixed quickly.
    Check first
    Free disk space, permissions, and the backup made at the start of the run.
  13. Start app pool

    Start the app pool so IIS loads the new build.

    Fails when
    The pool won't come back up, often a runtime, module or configuration problem in the new build.
    Check first
    Event Viewer's Application log for ASP.NET Core Module and .NET runtime errors.
  14. Write success entry to application event log

    Record in the Windows Application log that the deployment finished, leaving an audit trail in Event Viewer.

    Fails when
    The event source isn't registered, or the account can't write to the log.
    Check first
    That the event source exists on the VM and the deploy account's rights.

Why each tool sits where it does

GitHub

Source of truth

Every change starts as a commit. A webhook on the dev branch is what starts the pipeline, so no one has to remember to run a build.

Read the guide →

Jenkins

Orchestrator

Runs the full build job in dev and the lighter promotion jobs elsewhere, and hands every deployment to AWX. It coordinates; it doesn't hold the server credentials.

Read the guide →

SonarQube

Quality gate

Turns 'is this code good enough?' into a pass/fail that stops the pipeline, instead of a review comment that gets ignored.

Read the guide →

Nexus

Artifact store

Holds every build as an immutable, versioned package. This is what makes 'build once, deploy many' possible.

Read the guide →

Jira

Approval gate

A recorded approval is what triggers promotion to the next environment, so every production change has an audit trail.

Ansible AWX

Deployment engine

Runs the API and UI playbooks against the servers with centrally managed credentials, role-based access and a job history. The same playbooks serve all five environments.

Read the guide →

Azure Windows VM

Runtime host

One VM per environment running Windows and IIS. AWX reaches it over WinRM.

Read the guide →

IIS

Web server

Hosts the .NET 8 API in its own app pool and serves the Angular 20 build as a site. Event Viewer and the IIS logs are where you look when something breaks.

Read the guide →

Where the pipeline itself can fail

The secret scan or quality gate fails

The build job stops before Nexus. Nothing was published and nothing was deployed. Remove the secret or fix the flagged issues, then push again.

The package can't be downloaded

The playbook fails at the download step, before the app pool is stopped or the deployment folder is touched. The running release is unharmed. Check the version in Nexus.

The API fails after the pool is stopped

This is the risky window: the API is down until the pool restarts. The backup taken at the start of the playbook is what you restore from, or you redeploy the previous Nexus version.

The interview talk track

"Walk me through how code gets from a commit to production." About two minutes, out loud.

Our code lives in GitHub. A merge to the dev branch fires a webhook and Jenkins runs the full build job: it preloads the environment, checks out the code, runs a secret scan, then builds and unit-tests the .NET 8 API or the Angular 20 UI and sends it through SonarQube. If the secret scan, a test or the quality gate fails, the pipeline stops there.

If it passes, Jenkins publishes one versioned package to Nexus and asks Ansible AWX to run the deployment playbook. For the API, that means checking connectivity, backing up the current release, downloading and unzipping the package, stopping the app pool, replacing the files, starting the pool again and writing a success entry to the Windows Application log. The UI playbook is the same idea without the app pool: download, unzip, clean, copy.

To move up we don't rebuild. Someone approves the promotion in Jira, which triggers the next environment's Jenkins job. It preloads, works out which application and which approved version it's deploying, runs the same playbook against that environment's VM, then runs the tests and the post tasks. The same package goes through SIT, UAT, Stage and Prod, so what we tested is what ships.

What I'd improve next

Knowing the gaps in a setup is what separates a senior answer from a description of the tools.

Automate the rollback

The API playbook already backs up the current release. A matching restore playbook (or 'run the job with the previous Nexus version') turns a manual scramble into one click.

A health check after the pool starts

The success entry in the event log proves the playbook finished, not that the API works. A call to a health endpoint proves the release is actually serving.

Give the UI playbook a backup step too

The API playbook saves the running release before replacing it; the UI playbook doesn't. The same three backup steps would make a bad UI release just as recoverable.

Prune old backups

Every deploy adds a copy of the previous release. Without a retention rule, backups quietly eat the disk until a deploy fails at the backup step.

Blue/green releases on IIS

Deploy to a second site or VM, verify it, then switch traffic, so the API is never down while the pool restarts.

Want to work through the tools behind this?

Create a free account to track the roadmap, practise the interview questions and read the tool guides.