Tutorial: Automate infrastructure and deployment on Azure using Jenkins and Ansible
              WRITTEN BY
/en-us/opensource/blog/author/kylie-liang
Both Ansible and Jenkins are powerful open source automation tools. Using Ansible, you can provision virtual machines, containers, network and complete cloud infrastructures on Azure. In addition, Ansible allows you to automate the deployment and configuration of resources in your environment. Jenkins provides hundreds of plugins to support building, deploying and automating any project, including a plugin for Ansible.
With the power of Ansible and Jenkins, and their deep integration with Azure, you can have a seamless CI/CD experience on Azure. Below is an example for a web app scenario. Jenkins is used to build and deploy, and Ansible is called to handle provisioning.
In the following sections, we will walk though how to use Jenkins to call Ansible to provision a web app and then continuously build and deploy a Java Spring Boot application to Azure Web Apps.
Build your Jenkins and Ansible environment
Set up the Jenkins host
It is easy to create a Jenkins server on an Azure Linux virtual machine from a solution template. You can learn more about this template from install-jenkins-solution-template.
Install Ansible on the Jenkins host
When your Jenkins host is created, let us SSH to your Jenkins server and set up Ansible on it.
## Install pre-requisite packages
$ sudo apt-get update
$ sudo apt-get install -y libssl-dev libffi-dev python-dev python-pip
            $ sudo pip install ansible[azure]==2.7.0rc2
            or
## Install Azure preview modules
$ sudo ansible-galaxy install Azure.azure_preview_modules
            $ sudo pip install -r ~/.ansible/roles/Azure.azure_preview_modules/files/requirements-azure.txt
            Install Maven for a sample Java application
In this demo, we will directly use this Jenkins server to build our Java application. Here we also install Maven on it.
## Install maven
sudo apt-get install -y maven
            Install Jenkins plugin for Ansible
The following three plugins will be used for this web app scenario.
- azure-app-service: A Jenkins plugin to deploy a web app.
 - ansible: This plugin allows to execute Ansible tasks as a job build step.
 - envinject: This plugin makes it possible to have an isolated environment for your jobs.
 
Connect to your Jenkins server by following connect-to-jenkins. After you unblock Jenkins, suggest you choose “Install suggested plugins.” The Jenkins plugin for App Service will be installed here.
              
              Prepare Application, Ansible playbook, and Jenkinsfile
Spring Boot application for Azure Web Apps
Here we forked a Spring Boot project from https://github.com/spring-guides/gs-spring-boot to https://github.com/VSChina/gs-spring-boot for the following tutorial. On the branch named”war-based-deployment,” we updated the application.java and pom.xml to package this project as an executable war file, which can be directly deployed to Azure Web Apps with a Tomcat container by default.
Ansible playbook to provision Azure Web Apps
The below Ansible playbook creates a resource group and a web app on App Service Linux with Java 8 with Tomcat container runtime.
- name: Create Azure VM
hosts: localhost
connection: local
vars:
resource_group: "{{ lookup('env', 'RES_GROUP') }}"
webapp_name: "{{ lookup('env', 'WEB_APP_NAME') }}"
location: eastus
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create a linux web app with java framework
azure_rm_webapp:
resource_group: "{{ resource_group }}"
name: "{{ webapp_name }}"
plan:
resource_group: "{{ resource_group }}"
name: myappplan
is_linux: true
sku: S1
number_of_workers: 1
frameworks:
- name: "java"
version: "8"
settings:
java_container: tomcat
java_container_version: 8.5
            Jenkinsfile
Below Jenkinsfiledefines 4 tasks as followings.
- Check out source code
 - Build
 - Call Ansible to provision web app
 - Deploy application to created web app
 
node {
stage('Init') {
checkout scm
}
stage('Build') {
sh '''
cd complete
mvn clean package
mv target/*.war ROOT.war
'''
}
stage('Deploy') {
withCredentials([azureServicePrincipal(credentialsId: env.AZURE_CRED_ID,
subscriptionIdVariable: 'AZURE_SUBSCRIPTION_ID',
clientIdVariable: 'AZURE_CLIENT_ID',
clientSecretVariable: 'AZURE_SECRET',
tenantIdVariable: 'AZURE_TENANT')]) {
ansiblePlaybook installation: 'ansible',
playbook: 'complete/deploy/ansible/webapp.yml'
}
azureWebAppPublish azureCredentialsId: env.AZURE_CRED_ID,
resourceGroup: env.RES_GROUP,
appName: env.WEB_APP_NAME,
filePath: "ROOT.war"
}
}
            Define your Jenkins pipeline
Add Azure Service Principal in credentials
Authentication is required using Ansible modules to provision Azure resources. If you don’t have Service Principal, create an Azure service principal. Take note of the values for the subscription ID, Client ID, Secret, and Tenant ID.
On Jenkins dashboard, click Credentials on the left bar and then System item. Then you will see Global Credentials on the page. Select it and click Add Credentials. As for kind, select Microsoft Azure Service Principal here and fill in subscription ID, Client ID, Secret, and Tenant ID.
              
              Create a Jenkins job
Select New Item from the Jenkins console, then fill in your project and select Pipeline project, then select OK.
              AZURE_CRED_ID=azure-credentials-id
WEB_APP_NAME=web-app-name
RES_GROUP=web-app-resource-group
JENKINS_ADMIN=Jenkins-server-username
            
              
              Launch the Jenkins Job
Now it is time to click Build Now. After the deployment is complete, you can find your web app on the portal and you will see it at https://.azurewebsites.net.
              
              Conclusion
In this tutorial we demonstrated a simple flow that automates web app provisioning and application deployment to Azure Web Apps. If you want to try more with the combination of Jenkins and Ansible, check out Ansible on Azureand Jenkins on Azure.
Questions? Let us know in the comments.