Deploy your app to Linux virtual machines in Azure using Azure DevOps Services and Azure Pipelines
Applies to: ✔️ Linux VMs
Continuous integration (CI) and continuous deployment (CD) form a pipeline by which you can build, release, and deploy your code after every code commit. This document contains the steps associated with setting up a CI/CD pipeline for doing multi-machine deployments using Azure Pipelines.
Azure Pipelines provides a complete, fully featured set of CI/CD automation tools for deployments to Virtual machines, both on-prem or on any cloud.
In this tutorial, you will set up a YAML based CI/CD pipeline to deploy your app to an Azure Pipelines Environment with Linux Virtual machines as resources, each of which serve as web servers to run the app.
You learn how to:
- Get a sample app.
- Create a YAML based Azure Pipelines CI pipeline for building the sample app.
- Create an Azure Pipelines Environment for the Azure virtual machines
- Create an Azure Pipelines CD pipeline.
- Execute manual and CI-triggered deployments.
Before you begin
For more information, see Connect to Azure DevOps Services.
You need a Linux virtual machine for a deployment target. For more information, see Create and manage Linux VMs with the Azure CLI.
Open inbound port 80 for your virtual machine. For more information, see Create network security groups using the Azure portal.
Get your sample app code
If you already have an app in GitHub that you want to deploy, you can try creating a pipeline for that code.
However, if you are a new user, then you might get a better start by using our sample code. In that case, fork this repo in GitHub:
Prerequisites for the Linux VM
Sample apps mentioned above have been tested on Ubuntu 16.04, and we recommend you use the same version of Linux VM for this quickstart. Follow the additional steps described below based on the runtime stack used for the app.
- 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 app, 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 Azure Pipelines environment with Azure virtual machines
Virtual machines can be added as resources within environments and can be targeted for multi-machine deployments. Deployment history views within environment provide traceability from VM to the pipeline and then to the commit.
You can create an environment in the “Environments” hub within the “Pipelines” section.
Sign in to your Azure DevOps organization and navigate to your project.
In your project, navigate to the Pipelines page. Then choose 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 and click Next.
Choose Operating System (Windows/Linux), and copy PS registration script.
Now run the copied script from an administrator PowerShell command prompt on each of the target VMs to be registered with this Environment.
- Personal Access Token of the logged in user is pre-inserted in the script which expires on the same day making the copied script unusable thereon.
- If your VM already has any agent running on it, provide a unique name for “agent” to register with environment.
Once the VM is registered, it will start appearing as an environment resource under “resources” tab of the environment.
For adding more VMs, you can view and copy the script again by clicking on “Add resource” and choosing “Virtual Machines” as resource. This script would remain same for all the VMs to be added to this environment.
Each machine interacts with Azure Pipelines to coordinate deployment of your app.
You can add tags to the VM as part of the interactive PowerShell registration script (or) you can also add/remove the same from the resource view by clicking on the triple dots at the end of each VM resource in the resources view.
The tags you assign allow you to limit deployment to specific virtual machines 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 use.
Define your CI build pipeline
You'll need a continuous integration (CI) build pipeline that publishes your web application, as well as 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 might 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 the below YAML snippet that builds your Java project and runs tests with Apache Maven:
jobs: - 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.
Define CD steps to deploy to the Linux VM
Change the YAML file for the above pipeline to include a deployment job by referencing the environment and the VM resources which you have earlier using the YAML syntax below:
jobs: - deployment: VMDeploy displayName: web environment: name: <environment name> resourceType: VirtualMachine tags: web
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 deployment strategy.
runOnceis the simplest deployment strategy wherein all the life cycle hooks, namely
postRouteTraffic, are executed once. Then, either
Below is the example YAML snippet for
jobs: - deployment: VMDeploy displayName: web pool: vmImage: 'Ubuntu-latest' environment: name: <environment name> resourceType: VirtualMachine strategy: runOnce: deploy: steps: - script: echo my first deployment
Below is an example of the YAML snippet that you can use to define a rolling strategy for Virtual machines updates upto 5 targets 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: 5 #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.
Run your pipeline and get traceability views in environment
Deployments view of the environment provides complete traceability of commits and work items, and a cross-pipeline deployment history per environment/resource.