Deploy to a Linux Virtual Machine
Azure DevOps Services
Learn how to set up a continuous improvement/continuous development (CI/CD) pipeline for multi-virtual machine deployments. Use the instructions in this article for any app that publishes a web deployment package.
Note
If you want to deploy your application to a Linux virtual machine using the classic editor, see Deploy web apps to Linux virtual machines (VMs).
Get your sample code
If you already have an app in GitHub that you want to deploy, you can create a pipeline for that code.
If you are a new user, fork this repo in GitHub:
https://github.com/spring-projects/spring-petclinic
Note
Petclinic is a Spring Boot application built using Maven.
Prerequisites for the Linux VM
Use Ubuntu 16.04 for following the next section in this article, and more steps for Java or JavaScript.
- To deploy a Java Spring Boot and Spring Cloud based apps, create a Linux VM in Azure using this template, which provides a fully supported OpenJDK-based runtime.
- To deploy Java servlets on Tomcat server, create a Linux VM with Java 8 using this Azure template and configure Tomcat 9.x as a service.
- To deploy a Java EE-based Wildfly app, follow the blog post. To provision the VM, use an Azure template to create a Linux VM + Java + WebSphere 9.x or a Linux VM + Java + WebLogic 12.x or a Linux VM +Java + WildFly/JBoss 14.
Create an environment with virtual machines
You can add virtual machines as resources within environments and target for multi-VM deployments. The deployment history view provides traceability from the VM to the commit.
Sign into your Azure DevOps organization and navigate to your project.
Go to the Pipelines page and select Environments > Create Environment.
Specify a Name (required) for the environment and a Description.
Choose Virtual Machines as a Resource to be added to the environment, and then select Next.
Choose the Windows or Linux for the Operating System and copy the PowerShell registration script.
Run the PowerShell registration script on each of the target VMs registered with the environment.
Note
- The Personal Access Token (PAT) of the signed in user gets pre-inserted in the script and expires after three hours.
- If your VM already has any agent running on it, provide a unique name to register with the environment.
Once VM is registered, it will start appearing as an environment resource under Resources.
To add more VMs, copy the script again. Select Add resource and choose Virtual Machines. This script is the same for all the VMs you want to add to the same environment.
Each machine interacts with Azure Pipelines to coordinate deployment of your app.
You can add or remove tags for the VM. Select on the dots at the end of each VM resource in Resources.
Tags limit deployment to specific VMs when the environment's used in a deployment job. Each tag is limited to 256 characters. There's no limit to the number of tags you can create.

Define your CI build pipeline
You need a CI build pipeline that publishes your web app. You also need a deployment script that can be run locally on the Ubuntu server. Set up a CI build pipeline based on the runtime you want to use.
Sign in to your Azure DevOps organization and go to your project.
In your project, go to the Pipelines page, and then choose the action to create a new pipeline.
Select GitHub as the location of your source code.
You may be redirected to GitHub to sign in. If so, enter your GitHub credentials.
When the list of repositories appears, select the sample app repository that you want.
Azure Pipelines analyzes your repository and recommends a suitable pipeline template.
Select the starter template and copy this YAML snippet to build your Java project and run tests with Apache Maven:
- job: Build
displayName: Build Maven Project
steps:
- task: Maven@3
displayName: 'Maven Package'
inputs:
mavenPomFile: 'pom.xml'
- task: CopyFiles@2
displayName: 'Copy Files to artifact staging directory'
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)'
Contents: '**/target/*.?(war|jar)'
TargetFolder: $(Build.ArtifactStagingDirectory)
- upload: $(Build.ArtifactStagingDirectory)
artifact: drop
For more information, do the steps mentioned in Build your Java app with Maven for creating a build.
Define CD steps to deploy to the Linux VM
Edit your pipeline and include a deployment job by referencing the environment and the VM resources you created earlier:
jobs: - deployment: VMDeploy displayName: web environment: name: <environment name> resourceType: VirtualMachine tags: web1 strategy:Select specific sets of VMs from the environment to receive the deployment by specifying the tags that you've defined for each VM in the environment.
For more information, see the complete YAML schema for deployment job.
Specify either
runOnceorrollingas a deployment strategy.runOnceis the simplest deployment strategy. All the life-cycle hooks, namelypreDeploydeploy,routeTraffic, andpostRouteTraffic, get executed once. Then, eitheron:successoron:failuregets executed.See the following example of a YAML snippet for
runOnce:jobs: - deployment: VMDeploy displayName: web pool: vmImage: 'ubuntu-latest' environment: name: <environment name> resourceType: VirtualMachine strategy: runOnce: deploy: steps: - script: echo my first deploymentSee the following example of a YAML snippet for the rolling strategy. You can update up to five targets gets in each iteration.
maxParalleldetermines the number of targets that can be deployed to, in parallel. The selection accounts for absolute number or percentage of targets that must remain available at any time, excluding the targets being deployed to. It's also used to determine the success and failure conditions during deployment.jobs: - deployment: VMDeploy displayName: web environment: name: <environment name> resourceType: VirtualMachine strategy: rolling: maxParallel: 2 #for percentages, mention as x% preDeploy: steps: - download: current artifact: drop - script: echo initialize, cleanup, backup, install certs deploy: steps: - task: Bash@3 inputs: targetType: 'inline' script: | # Modify deployment script based on the app type echo "Starting deployment script run" sudo java -jar '$(Pipeline.Workspace)/drop/**/target/*.jar' routeTraffic: steps: - script: echo routing traffic postRouteTraffic: steps: - script: echo health check post-route traffic on: failure: steps: - script: echo Restore from backup! This is on failure success: steps: - script: echo Notify! This is on successWith each run of this job, deployment history gets recorded against the
<environment name>environment that you've created and registered the VMs.
Pipeline traceability views in environment
The Deployments view provides complete traceability of commits and work items, and a cross-pipeline deployment history per environment.


Next steps
Related articles
Maklum balas
Kirim dan lihat maklum balas untuk