Desde mi punto de vista Azure DevOps es quizas una de las mejores herramientas como orquestadora de Pipelines para DevOps, al menos con la que me siento más cómodo trabajando y para mi, la mas fácil. Si bien, hoy vamos a ver como trabajar con Jenkins para conseguir el mismo objetivo que ya vimos en el post anterior (con Azure DevOps) y para la aplicación MyBudget.
Configuración
Aunque podemos descargar e instalalar localmente Jenkins, vamos a optar por una instalación en Azure.
- Crear un nuevo recurso (Create a resource)
- Seleccionar Jenkins
- Pulsar el boton de crear y completar los pasos indicados hasta finalmente pulsar “OK”.
- Una vez creado el servidor Jenkins, tendremos acceso a la VM. Por defecto el protocolo de acceso es HTTP, por lo que no podremos acceder directamente a traves navegador a la url “xxx.cloudapp.azure.com“. Por tanto, tendremos que hacerlo via localhost mediante ssh de la forma: ssh -L 127.0.0.1:8080:localhost:8080 username@xxxwesteurope.cloudapp.azure.com, tal y como muestra la siguiente imagen:
- En estos momentos ya podremos acceder al portal de jenkins vía http://localhost:8080, si bien para poder compilar la aplicación MyBudget, necesitaremos instalar el SDK de NetCore para Linux (Ubuntu) utilizando para ello las siguentes instrucciones.
Para conocer la distribución de linux para la que actualizar el SDK, podemos ejecutar el comando “cat /proc/version” desde la consola Cloud Shell.
wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2
- Adicionalmente y para que Jenkins pueda acceder y desplegar en Azure App Service, necesitamos dos plugins que podemos instalar desde el menú: Manage Jenkin – Manage Plugins:
- Azure Credentials
- Azure App Service Plugin
Pipeline
Ahora que ya tenemos todo configurado, crearemos el Pipeline, cuyo objetivo es compilar y ejecutar los tests unitarios de forma automática (CI – Continuous Integration) tras cada push/merge en la rama “master”, para a continuación, disparar el proceso de CD (Continuous Deployment) para el despliegue a DEV de manera automática y a Producción, previa aprobación. Supondremos que nuestros dos Azure App Services (para DEV y PROD) han sido creados previamente.
En primer lugar creamos una nueva credencial para el acceso a Azure (gracias al plugin “Azure Credential”):
- Desde el terminal Cloud Shell de Azure, ejecutar las siguientes dos instrucciones:
- az account set –subscription “<AZURE SUBSCRIPTION NAME>”
- az ad sp create-for-rbac –name “MyBadget” –password <PASSWORD
- Con el resultado de dichos comandos completar la siguiente información para añadir así la nueva credencial de tipo “Microsoft Azure Service Principal“, donde:
- Client ID, se corresponde con el appId.
- Client Secret, con el password.
- Tenat ID, con el tenant y,
- Subscription ID, con la subscripción de Azure, que también podemos obtener con la instrucción “az account show“.
- Pulsar en “Verify Service Principal” para asegurar que la credencial es correcta.
- Pusar en “OK”.
Las dos intrucciones anteriores registran una nueva aplicación (“MyBadget”) en el Directorio Activo de Azure. Navegando a ella, podemos ver también los valores de los parámetros antes introducidos.
- Crear un nuevo Pipiline con el nombre “MyBudget-CI-CD”.
- Parametrizar el proyecto marcando el check “This project is parameterized” y crear los siguientes parámetros:
- GIT_Repo, con el valor por defecto: https://github.com/juanluelguerre/MyBudget.git
- RESORCE_GROUP, con el valor correspondiente al nombre del Resource Group de azure donde se encontraran los Azure App Services destino del despliegue: mybudget.
- APP_NAME_DEV con el valor “mybudgetdev” y, APP_NAME_PROD con el valor “mybudgetprod“. Donde ambos parámetros se corresponden con el nombre del Azure App Service y que a su vez forma parte de la url: https://<APP_NAME_DEV|APP_NAME_PROD>.azurewebsites.net.
- AZURE_CREDENTIAL_ID, del tipo “Microsoft Azure Service Principal” y requediro y selecciónar la credencial previamente creada: “Azure-Enterprise-MyBudget“.
- Marcar el check “Github hook trigger for GITScm polling”.
- Crear el script para la Pipeline (Declarativo).
pipeline { agent any stages { stage('Checkout git repo (DEV)') { steps { git branch: 'master', url: params.GIT_REPO } } stage('Build and Publish') { steps { sh(script: "dotnet publish MyBudget.sln -c Release", returnStdout: true) } } stage('Deploy to Azure (DEV)') { steps { azureWebAppPublish azureCredentialsId: params.AZURE_CREDENTIAL_ID, resourceGroup: params.RESOURCE_GROUP, appName: params.APP_NAME_DEV, sourceDirectory: "MyBudget/bin/Release/netcoreapp2.2/publish/" } } stage('Deploy to Azure (PROD)') { steps { input 'Do you approve deployment to PRO?' azureWebAppPublish azureCredentialsId: params.AZURE_CREDENTIAL_ID, resourceGroup: params.RESOURCE_GROUP, appName: params.APP_NAME_PROD, sourceDirectory: "MyBudget/bin/Release/netcoreapp2.2/publish/" } } } }
Aunque hemos optado para este post la opción “inline” para la creación de la Pipeline, la recomendación es usar un fichero “jenkinsfile” dado que el repositorio de código fuente jugará un papel importante en el mismo al igual que para el resto de código de nuestra aplicación.
Continuous Integration/Delivery
Para configurar la Integración continua (CI) en Jenkins, y así poder disparar el Pipeline automáticamente, es necesario incluir un Webhook en el repositorio de github, a traves de la opción: “Settings – Webhooks” y añadiendo el sufijo “/github-webhook” a la url de Jenkins:
Finalmente si hacemos un cambio en el código y un push a “master”, el Pipeline se activará debido al Webhook en Github y el proceso de CI/CD dará comienzo.
En el ejemplo, para el despliegue a “PROD” se ha incluido la aprobación, al igual que en el post anterior con Azure DevOps.
Happy DevOps
Juanlu
Nota: No olvidemos apagar la VM cuando no la usemos para ahorra créditos de Azure.
Referencias: