Provisionar SonarQube en Azure App Service (es-MX)
Artículo Original: https://blogs.msdn.microsoft.com/premier_developer/2018/12/23/sonarqube-hosted-on-azure-app-service/
Introducción
Esta publicación es proporcionada por el ingeniero de campo Premier, Nathan Vanderby, quien simplifica la configuración de un servidor SonarQube con un solo paso utilizando los servicios de aplicaciones de Azure.
SonarQube es una herramienta que centraliza el análisis de códigos estáticos y la cobertura de pruebas unitarias. Se puede utilizar en varios idiomas y para un solo proyecto hasta una escala empresarial.
https://msdnshared.blob.core.windows.net/media/2018/12/SQProject_thumb1.png
Hay varias guías sobre cómo configurar SonarQube alojado en Azure. Desde alojarlo en una máquina virtual (aquí y aquí) hasta una imagen de docker o un contenedor de Linux en un Servicio de aplicaciones de Azure. También hay instrucciones para utilizar IIS como proxy reverso para permitir el tráfico SSL para mayor seguridad.
Hay otro proyecto para tratar de simplificar la configuración de un servidor SonarQube al que se puede acceder públicamente. El proyecto es SonarQube-AzureAppService. Utiliza la extensión HttpPlatformHandler de IIS, que también se puede usar para alojar SonarQube directamente con IIS.
SonarQube-AzureAppService
URL del proyecto: https://github.com/vanderby/SonarQube-AzureAppService
Este proyecto simplifica la configuración de un servidor SonarQube en un solo paso. Simplemente haga clic en el enlace Implementar en Azure en la página de inicio del proyecto y siga el tutorial sencillo para desplegar y configurar los recursos. La hora de inicio inicial de SonarQube puede demorar hasta 10 minutos en recursos más lentos. ¡Eso es todo! Lea a continuación para obtener información más detallada sobre lo que está sucediendo detrás de escena.
Implementación de los recursos de Azure
El botón "Deploy To Azure" en el repositorio de GitHub usa el archivo de proyecto azuredeploy.json para implementar una plantilla ARM. La plantilla ARM define un plan de servicio de aplicación simple, aplicación web y el código del repositorio de GitHub. El código se inserta en la carpeta del repositorio en la aplicación web. Dentro del proyecto, un archivo .deployment define un script de implementación para ejecutar.
https://msdnshared.blob.core.windows.net/media/2018/12/DeployToAzure_thumb.png
En una nota al margen, en el momento de redactar este informe, el nivel mínimo del Plan de Servicio de Aplicaciones es Básico. Los niveles Libre y Compartido arrojan un error en el inicio relacionado con las restricciones de memoria de Java con la configuración predeterminada de SonarQube.
Script de implementación
El script de implementación es Deploy-SonarQuveAzureAppService.ps1. Esta secuencia de comandos copia la carpeta wwwroot desde el repositorio, que contiene los archivos web.config y HttpPlatformHandlerStartup.ps1, en la carpeta wwwroot de la aplicación web. Voy a caminar a través de estos archivos más tarde. También descarga y extrae los últimos binarios de SonarQube. He eliminado las líneas de registro y manejo de errores por brevedad en el bloque de código a continuación.
xcopy wwwroot ..\wwwroot /Y
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$global:progressPreference = 'SilentlyContinue'
$downloadSource = 'https://binaries.sonarsource.com/Distribution/sonarqube/'
$allDownloads = Invoke-WebRequest -Uri $downloadSource -UseBasicParsing
$zipFiles = $allDownloads[0].Links | Where-Object { $_.href.EndsWith('.zip') -and !($_.href.contains('alpha') -or $_.href.contains('RC')) }
$latestFile = $zipFiles[-1]
$downloadUri = $downloadSource + $latestFile.href
$outputFile = "..\wwwroot\$($latestFile.href)"
Invoke-WebRequest -Uri $downloadUri -OutFile $outputFile -UseBasicParsing
Expand-Archive -Path $outputFile -DestinationPath ..\wwwroot
Una vez que se haya completado la implementación, la carpeta wwwroot de su aplicación web debería tener una carpeta de sonarqube y solo unos pocos archivos. También puedes subir manualmente archivos binarios de sonarqube.
https://msdnshared.blob.core.windows.net/media/2018/12/AzureDeployFiles_thumb.png
Archivos de tiempo de ejecución
Este proyecto fue posible gracias a cómo un servicio de aplicaciones aloja aplicaciones Java. Lo hace utilizando la extensión HttpPlatformHandler. Esta extensión iniciará cualquier archivo ejecutable definido en web.config y reenviará todas las solicitudes que reciba al puerto definido por la variable de entorno HTTP_PLATFORM_PORT. HttpPlatformHandler establece esta variable de entorno aleatoriamente cuando invoca el ejecutable de inicio.
Web.Config
El archivo web.config que se muestra a continuación es muy simple. Agrega la extensión HttpPlatformHandler a los manejadores y luego define el comportamiento de HttpPlatformHandler. Se le dice al controlador que ejecute PowerShell y ejecute el script HttpPlatformHandlerStartup.ps1. Vamos a entrar en detalles de este script más tarde. También le dice al controlador que registre los mensajes de la salida estándar, no vuelva a intentar el inicio y espere 300 segundos antes de que se agote el tiempo de espera. Queremos un tiempo de espera de inicio largo, ya que SonarQube tarda un poco en comenzar. Especialmente la primera vez si usas una base de datos en memoria.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" requireAccess="Script" />
</handlers>
<httpPlatform stdoutLogEnabled="true" startupTimeLimit="300" startupRetryCount="0"
processPath="%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe"
arguments="%home%\site\wwwroot\HttpPlatformHandlerStartup.ps1">
</httpPlatform>
</system.webServer>
</configuration>
HttpPlatformHandlerStartup.ps1
Este script escribe el puerto HTTP_PLATFORM_PORT en el archivo sonar.properties, actualiza wrapper.conf con la ubicación java.exe y ejecuta StartSonar.bat. Lo más importante que sucede aquí es configurar HTTP_PLATFORM_PORT, ya que se aleatoriza cada vez que se inicia la aplicación. He eliminado las líneas de registro y manejo de errores por brevedad en el bloque de código a continuación.
$port = $env:HTTP_PLATFORM_PORT
$propFile = Get-ChildItem 'sonar.properties' -Recurse
$configContents = Get-Content -Path $propFile.FullName -Raw
$configContents -ireplace '#?sonar.web.port=.+', "sonar.web.port=$port" | Set-Content -Path $propFile.FullName
$wrapperConfig = Get-ChildItem 'wrapper.conf' -Recurse
$wrapperConfigContents = Get-Content -Path $wrapperConfig.FullName -Raw
$wrapperConfigContents -ireplace 'wrapper.java.command=java', 'wrapper.java.command=%JAVA_HOME%\bin\java' | Set-Content -Path $wrapperConfig.FullName
$startScript = Get-ChildItem 'StartSonar.bat' -Recurse
& $startScript[-1].FullName
En otra nota, la secuencia de comandos ejecuta el último archivo StartSonar.bat que encuentra para que ejecute la secuencia de comandos desde la carpeta x64 y no desde x86 si está presente.
Esperamos que esto sea útil si está considerando configurar un servidor SonarQube basado en la nube.