Deploy to a Linux Virtual Machine
If you want to deploy your application to a Linux virtual machine using the classic editor, see Deploy web apps to Linux VMs.
Azure Pipelines provides a complete, fully featured set of CI/CD automation tools for deployments to virtual machines.
You can use continuous integration (CI) and continuous deployment (CD) to build, release, and deploy your code. Learn how to set up a CI/CD pipeline for multi-machine deployments.
This article covers how to set up continuous deployment of your app to a web server running on Ubuntu. You can use these steps for any app that publishes a web deployment package.
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:
Prerequisites for the Linux VM
- For deploying 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.
- For deploying Java servlets on Tomcat server, create a Linux VM with Java 8 using this Azure template and configure Tomcat 9.x as a service.
- For deploying Java EE-based Wildfly app, follow the blog post here. 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
Virtual machines can be added as resources within environments and can be targeted for multi-VM deployments. The deployment history view provides traceability from the VM to the commit.
You can create an environment in Environments within Pipelines.
Sign into your Azure DevOps organization and navigate to your project.
Navigate to the Pipelines page. Select Environments and click Create Environment. Specify a Name (required) for the environment and a Description.
Choose Virtual Machines as a Resource to be added to the environment. Click Next.
Choose the Windows or Linux for the Operating System and copy PS registration script.
Run the copied script from an administrator PowerShell command prompt on each of the target VMs registered with this environment.
- The Personal Access Token (PAT) of the logged in user is 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 environment.
Once VM is registered, it will start appearing as an environment resource under Resources.
To add more VMs, copy the script again. Click 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. Click on the dots at the end of each VM resource in Resources. The tags you assign allow you to limit deployment to specific VMs when the environment is used in a deployment job. Tags are each limited to 256 characters, but there is no limit to the number of tags you can create.
Define your CI build pipeline
You'll need a continuous integration (CI) build pipeline that publishes your web application and 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 navigate to your project.
In your project, navigate to the Pipelines page. Then choose the action to create a new pipeline.
Walk through the steps of the wizard by first selecting 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 your desired sample app repository.
Azure Pipelines will analyze your repository and recommend a suitable pipeline template.
Select the starter template and copy this YAML snippet to build your Java project and runs 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 guidance, follow 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:
You can select specific sets of virtual machines from the environment to receive the deployment by specifying the tags that you have defined for each virtual machine in the environment. Here is the complete YAML schema for Deployment job.
You can specify either
rollingas a deployment strategy.
runOnceis the simplest deployment strategy. All the life-cycle hooks, namely
postRouteTraffic, are executed once. Then, either
Below is an example YAML snippet for
jobs: - deployment: VMDeploy displayName: web pool: vmImage: 'Ubuntu-16.04' environment: name: <environment name> resourceType: VirtualMachine strategy: runOnce: deploy: steps: - script: echo my first deployment
Below is an example YAML snippet for the rolling strategy. You can update up to 5 targets gets in each iteration.
maxParallelwill determine 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 that are being deployed to. It is 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 success
With each run of this job, deployment history is recorded against the
<environment name>environment that you have 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.
To learn what else you can do in YAML pipelines, see YAML schema reference.