Guia Despliegues Tyson
La siguiente guia es exclusiva para el proyecto de Findep Transformación Digital.
Sumario
Requisitos de permisos para CI/CD
- Acceso a los siguientes Cluster de Kubernetes (En caso de no tenerlo, solicitarlo a Braulio):
- 1. GCR-TYSON-BETA-Findep Transformación Digital (Para CI)
- 2. GKE-TYSON-BETA-Findep Transformación Digital (Para CD)
- Acceso a los repositorios y a la administración de los mismos (En caso de no tenerlo, solicitarlo a Braulio):
- Dar permisos al team de arquitectura y Autonomation para el caso de instance (En caso de no tenerlo, solicitarlo a Braulio):
https://dev.azure.com/findepdev/Findep%20Transformaci%C3%B3n%20Digital/ settings/repositories
Configuración del proyecto:
Es importante tener ya configurado el proyecto con Java 17, el OpenApi en vez de Swagger 2.0 y las pruebas de Sonar con los cambios a Java 17
- En caso de que el servicio a migrar tenga base de datos, solicitar a infraestructura dupliquen el secret de base de datos
Rama de dev
- Estando en la rama de dev, vamos a traernos todos los cambios del repositorio con un git pull
git pull
- Vamos a crear la rama de tyson/dev con el siguiente comando:
git branch -m tyson/dev
- Ahora se va a cambiar el origen del repositorio, seguramente esta apuntando a google repos, hay que pasarlo a que apunte a azure repos:
git remote set-url origin https://findepdev@dev.azure.com/findepdev/Findep%20Transformaci%C3%B3n%20Digital/_git/{nombre de servicio}
- Vamos a respaldar el dockerfile y el makefile en otro archivo, porque el circuito lo reemplaza por otro
- Eliminamos el pipe del gitignore para que no se pierda en el push hacia la nueva rama
- Vamos a la clase de configuracion del servicio y eliminamos estas lineas
@PropertySource("classpath:git_dev.properties") @PropertySource("classpath:git_qa.properties")
- Reemplazar el build por este, o solamente poner las versiones correctas del maven-surefire-plugin y del org.jacoco
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <id>pre-integration-test</id> <goals> <goal>start</goal> </goals> </execution> <execution> <id>post-integration-test</id> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-maven-plugin</artifactId> <version>0.2</version> <executions> <execution> <phase>integration-test</phase> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.8</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> <execution> <id>post-unit-test</id> <phase>test</phase> <goals> <goal>report</goal> </goals> <configuration> <dataFile>target/jacoco.exec</dataFile> <outputDirectory>target/jacoco-ut</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
- Agregar esta linea en el properties del servicio:
server.servlet.context-path=/v1
- Ejecutar el siguiente script:
sh -c "$(curl -fsSL https://cli-service-stable-v1.tysonbeta.com/v1/)"
Se van a crear las carpetas .ci, pipe y se reemplazará el Dockerfile y el MakeFile.
- Restaurar el makefile (Sin eliminar el que nos arrojo el circuito)
- Desplegar a dev con el siguiente comando
make delete make submit
- Probar el actuator del servicio desplegado a dev
https://{nombre del servicio}-ko6eh66raa-uc.a.run.app/v1/actuator
- En caso de querer levantar sin sonar, comentar las siguientes lineas del dockerfile
- Para no ejecutar el sonar cambiar la linea 27 y acompletarle -Dmavem.test.skip y comentar las siguientes lineas:
27. RUN mvn -B clean package -Dmaven.test.skip Comentar las siguientes lineas #RUN if [ "$SONAR_ENABLED" = "true" ] ; \ # then mvn -X -B sonar:sonar \ # -Dsonar.host.url="${SONAR_URL}" \ # -Dsonar.login="${SONAR_TOKEN}" \ # -Dsonar.projectKey="${PROJECT_NAME}" ; \ # fi #RUN if [ "$SONAR_ENABLED" = "true" ] ; \ # then \ # bash -c `node -e "const {measures} = JSON.parse(process.argv[1]); const last = measures[0].history.sort(obj => -1*Date.parse(obj.date))[0]; Number(last.value) >= ${SONAR_MIN_COVERAGE} ? console.info('exit 1') : console.error('exit 0');" "$(curl -H "Authorization: Basic ${TOKEN_ENCODED}" "${SONAR_URL}/api/measures/search_history?component=${PROJECT_NAME}&metrics=coverage")"`; \ # fi
- Con el servicio funcionando en dev con el dockerfile de tyson vamos a comenzar el despliegue a UAT. Si el servicio falla por alguna razon, arreglarlo, si no, el error persistira en UAT. Tambien mandamos los cambios a la rama de tyson/dev.
git push origin tyson/dev
Rama de UAT
- Creamos la rama de tyson/uat
git branch -m tyson/uat
- Retornamos el makefile al que el circuito arrojo.
- Editar el archivo ./.ci/pipe/azure-pipelines_beta.yml
- Editar line 23 (GCRName) y colocar el nombre del kubernetes: GCR-TYSON-BETA-Findep Transformación Digital
- Para eliminar el JWT editar el archivo ./.ci/k8s/authPolicy.yaml y agregar las siguientes líneas:
- from: - source: namespaces: - "autonomation"
Instance en pipeline CI
- Editar el archivo ./ci/pipe/azure-pipelines_beta.yml:
- Agregar las 2 variables siguientes:
- Dbtype: 'postgres'
- DbInstance: 'findep-microservicios'
- Agregar las 2 variables siguientes:
- Agregar las siguientes lineas al job "PrepareK8S" en la seccion de bash:
echo "$(ClusterNamespace)" > $(Pipeline.Workspace)/variables/Namespace echo "$(Dbtype)" > $(Pipeline.Workspace)/variables/DBType echo "$(DbInstance)" > $(Pipeline.Workspace)/variables/DBInstance cp ./src/main/resources/schema.sql $(Pipeline.Workspace)/variables/
- Asegurar que existe el archivo "schema.sql" en la carpeta ./src/main/resources:
Configuracion de Secrets
- Editar este archivo .ci/pipe/azure-pipelines_beta.yaml y agregar la siguiente linea:
cp ./secret.json $(Pipeline.Workspace)/variables/
- Y asegurar que venga esta linea, en caso de que no, agregarla:
echo "$(ClusterNamespace)" > $(Pipeline.Workspace)/variables/Namespace
- Crear un archivo en la raiz del proyecto llamado secret.json con la siguiente estructura:
{ "nameSpace": "autonomation", "secretName": "secret-{nombre de servicio}-env", "secretParams": [ { "paramName": "project_timezone", "paramValue": "America/Mexico_City" }, ... ] }
- Replicar de la rama qa los secrets en el deploy y agregarlos al archivo actual del deployment
Creación de Pipeline CI
- Tener el repositorio con la rama de tyson/uat en el repositorio de Azure actualizado.
- Ir a la sección de "Pipelines" de Azure
- Dar click en New Pipeline
- Seleccionar la opcion de "Azure Repos Git"
- Buscar el repositorio y seleccionarlo
- Seleccionar la configuracion del pipeline en la opcion "Existing Azure Pipelines YAML file"
- Seleccionar la rama "tyson/uat" y el path del pipe es el siguiente: /.ci/pipe/azure-pipelines_beta.yml
- Antes de correr el pipeline, nos vamos a asegurar que el GCR sea el correcto y lo vamos a guardar para configurar los triggers y se haga automaticamente con cada commit que se haga a la rama de tyson/uat. Par eso seleccionamos la opcion de save y despues la de edit:
- Nos vamos a la seccion de Triggers y editamos el nombre del pipeline, por "[nombre de servicio] CI tyson uat"
- En la sección de "Get Sources" seleccionamos la rama de tyson/uat y damos click en la opción de save & queue para que el pipe se ejecute por primera vez. Con esto ya quedo configurado para que se ejecute automáticamente cada que haya un commit nuevo en la rama.
- Finalmente nos pedira autorizar la ejecucion del pipeline con el kubernetes dado (En caso de no ver el mensaje, refrescar la pagina).
Creación de Pipeline CD
* Para la creacion del pipeline de CD, nos vamos a ir a la sección de "Releases" y damos click en el botón de "New" y en "New release pipeline"
- Se crea un nuevo pipeline, y a cada elemento que agreguemos seleccionaremos la opcion de Empty Job
- Se selecciona en la parte de artifacts la opcion de add new artifact y buscamos el pipeline de CI de nuestro servicio:
- Determinamos el trigger de nuestro pipe para que se ejecute cada que se cree una nueva compilacion (Pipeline CI) de nuestro servicio:
- Cambiamos el nombre al stage que se crea por default y damos click en la opcion de 1 job, 0 tasks:
- El Agent job es el tipo de maquina que va a ejecutar esta tarea, en este caso el Agent Job se quedara tal cual está. Damos click en la opcion de + y buscamos la opcion de Deploy to Kubernetes''''
- Seleccionamos en la seccion de Kubernetes service connection el Kubernetes GKE-TYSON-BETA-Findep Transformación Digital
- Ponemos como namespace: autonomation
- En los 3 puntos de los Manifiestos, buscamos el archivo de deploy.yaml en la carpeta de k8s
- Regresamos al pipeline seleccionando la pestaña de pipeline que aparece en la parte superior y ahora vamos a crear el stage del delete
- Damos click a Add en la parte de Stages.
- Cambiamos el nombre del nuevo stage a Delete y vamos a configurarlo para que solo se pueda correr manual.
- Seleccionamos el icono del rayo y seleccionamos la opcion de Manual Only, para que no se ejecute como parte del pipeline automatico y solo se haga manual.
- Ahora entramos a la seccion de 1 job, 0 task, el agent job lo dejamos como esta y agregamos una tarea llamada Kubectl donde configuraremos el Kubernetes Service Connection, el namespace, el comando como delete, habilitamos la opcion de Use Configuration y buscamos el archivo deploy.yaml en la parte de File Path:
- Regresamos al pipeline y creamos el Stage de Report derivado del stage de Deploy, para que terminando el despliegue, se ejecute ese stage:
- Damos click en la seccion de 1 job, 0 task, y editamos el agent job. En Agent Pool seleccionamos Azure Pipelines y en Agent Specification seleccionamos ubuntu-22.04.
- Creamos una nueva tarea de tipo bash. Seleccionamos el type como Inline y pegamos el siguiente script.
ShortSHA=$(cat ./ShortSHA) echo "##vso[task.setvariable variable=ShortSHA]$ShortSHA" Project=$(cat ./Project) echo "##vso[task.setvariable variable=Project]$Project" Submitter=$(cat ./Submitter) echo "##vso[task.setvariable variable=Submitter]$Submitter" Stage=$(cat ./Stage) echo "##vso[task.setvariable variable=Stage]$Stage" echo "project: $Project; sha: $ShortSHA; email: $Submitter; stag: $Stage" curl https://storage.googleapis.com/tools-findep/findep-devops --output findep-devops chmod +x findep-devops ./findep-devops deploy record -s $Project -i $ShortSHA -u $Submitter -e tyson -E $Stage
- Finalmente le cambiamos el nombre al pipeline con la siguiente estructura "[nombre del servicio] CD tyson uat" y lo guardamos.
Creacion del Stage Instance
- Creamos un nuevo stage, y lo configuramos que se ejecute manualmente de la misma forma que el stage de Delete y lo renombramos a Instance DB
- Damos click a la seccion de 1 job, 0 task y editamos el agent pool por Azure Pipelines y el Agent Specificacion por ubuntu-22.04
- Creamos una tarea de tipo Bash, le decimos que el type es Inline y pegamos el siguiente script:
##=== APPLY SCHEMA ======## Namespace=$(cat ./Namespace) echo "##vso[task.setvariable variable=Namespace]$Namespace" Project=$(cat ./Project) echo "##vso[task.setvariable variable=Project]$Project" Stage=$(cat ./Stage) echo "##vso[task.setvariable variable=Stage]$Stage" DBType=$(cat ./DBType) echo "##vso[task.setvariable variable=DBType]$DBType" DBInstance=$(cat ./DBInstance) echo "##vso[task.setvariable variable=DBInstance]$DBInstance" ShortSHA=$(cat ./ShortSHA) echo "##vso[task.setvariable variable=ShortSHA]$ShortSHA" Submitter=$(cat ./Submitter) echo "##vso[task.setvariable variable=Submitter]$Submitter" echo "project: $Project; namespace: $Namespace; stage: $Stage, DBType: $DBType, DBInstance: $DBInstance, sha: $ShortSHA, submitter: $Submitter" curl https://storage.googleapis.com/tools-findep/findep-devops --output findep-devops chmod +x findep-devops ./findep-devops deploy database -f ./schema.sql -s $Project -n $Namespace -i $DBInstance -e $Stage -t $DBType -a $ShortSHA -u $Submitter
- Finalmente definimos en la sección de Advanced el Working Directory buscando la carpeta de variables:
Creación de Secrets
- Generamos 2 stages nuevos, uno para la creacion y una para el borrado del secret.
- El primer pipe en la seccion de tasks, el agent job lo configuramos como Azure Pipelines y el agent Specification como ubuntu-22.04:
- Se agrega un task del tipo Bash. Seleccionamos el type como inline y pegamos el siguiente script y ademas en la seccion de Advanced seleccionamos el working directory la carpeta de variables
##=== CREATE SECRET ======## Namespace=$(cat ./Namespace) echo "##vso[task.setvariable variable=Namespace]$Namespace" Stage=$(cat ./Stage) echo "##vso[task.setvariable variable=Stage]$Stage" ShortSHA=$(cat ./ShortSHA) echo "##vso[task.setvariable variable=ShortSHA]$ShortSHA" Submitter=$(cat ./Submitter) echo "##vso[task.setvariable variable=Submitter]$Submitter" Action=create echo "##vso[task.setvariable variable=Action]$Action" echo "project: $Project; namespace: $Namespace; stage: $Stage, sha: $ShortSHA, submitter: $Submitter, action: $Action" curl https://storage.googleapis.com/tools-findep/findep-devops --output findep-devops chmod +x findep-devops ./findep-devops deploy secrets -f ./secret.json -n $Namespace -e $Stage -t $Action -a $ShortSHA -u $Submitter
- Para el delete del secret se configura el agent job y el task del tipo bash de la misma forma, solo con el siguiente script:
IMPORTANTE: MODIFICAR LA LINEA:
Secretname=secret-prueba-cicd
PONIENDO EL NOMBRE DEL SECRET
##=== DELETE SECRET ======## Namespace=$(cat ./Namespace) echo "##vso[task.setvariable variable=Namespace]$Namespace" Stage=$(cat ./Stage) echo "##vso[task.setvariable variable=Stage]$Stage" ShortSHA=$(cat ./ShortSHA) echo "##vso[task.setvariable variable=ShortSHA]$ShortSHA" Submitter=$(cat ./Submitter) echo "##vso[task.setvariable variable=Submitter]$Submitter" Secretname=secret-prueba-cicd echo "##vso[task.setvariable variable=Secretname]$Secretname" Action=delete echo "##vso[task.setvariable variable=Action]$Action" echo "project: $Project; namespace: $Namespace; stage: $Stage, sha: $ShortSHA, submitter: $Submitter, action: $Action, secretname: $Secretname" curl https://storage.googleapis.com/tools-findep/findep-devops --output findep-devops chmod +x findep-devops ./findep-devops deploy secrets -k $Secretname -n $Namespace -e $Stage -t $Action -a $ShortSHA -u $Submitter
Probando el servicio en tyson
* Para asegurarnos de que el servicio este funcionando en tyson simplemente podriamos esperar a que el pipeline nos marque en verde el stage:
- Tambien podriamos entrar a los logs del servicio y ver que este todo bien en los pods
https://console.cloud.google.com/kubernetes/service/us-central1/tyson-beta/autonomation/{nombre del servicio}-v1-stable/overview?authuser=0&hl=es&project=findep-calidad-uat-mx&pageState=(%22savedViews%22:(%22i%22:%22f1aafe7c7e91487a96821c88e9601ac7%22,%22c%22:%5B%22gke%2Fus-central1%2Ftyson-beta%22,%22gke%2Fus-central1%2Ffintech-istio-devops%22,%22gke%2Fus-central1-b%2Fgalileo%22,%22gke%2Fus-central1%2Ftools-devops%22,%22gke%2Fus-central1-c%2Fus-central1-task-manager-ua-32c96eed-gke%22,%22gke%2Fus-central1%2Ffindep-dataproc-beta%22%5D,%22n%22:%5B%5D))
- Y podriamos mandar a llamar el actuator del servicio con la siguiente estructura de url:
https://{nombre del servicio}.tysonbeta.com/v1/actuator
- O el swagger con la siguiente estructura de url:
https://{nombre del servicio}.tysonbeta.com/v1/swagger-ui/index.html#/
Registro en el dashboard de liberación
- Accedemos a https://release-dashboard.stable.tysonprod.com/dashboard
- Ingresamos con Google.
- Si es la primera vez que queremos revisar un servicio le damos en Aplicaciones.
- Buscamos el servicio. Debería aparecer:
TYSON UAT, REGISTRAR EN TYSON PROD
- En caso de que aparezcan XXXX en lugar de TYSON corremos nuevamente el scrip en cualquier carpeta (simplemente para registrarlo):
sh -c "$(curl -fsSL https://cli-service-stable-v1.tysonbeta.com/v1/)"
- Le damos en REGISTRAR EN TYSON PROD y ya podemos correr el realese de producción.
Reporte
- Ingresamos a la consola de google en la malla de producción y buscamos nuestro servicio.
- Si todo está correcto copiamos el realese ID.
- En el dasboard a la izquierda damos clic en Buscar y llenamos los datos.
- Aparecerán los datos del reporte que debemos de llenar y enviar.
Fuentes
- Videos de Arquitectura
https://findep-documentation.tysonprod.com/documents/documentation
- Make Instance: