domingo, 21 de março de 2021

Jenkins - Pipeline para subir uma aplicação Java

Fala pessoal, beleza?

Espero que estejam todos bem!

Conforme meu post sobre Jenkins e pipeline para deploy de uma aplicação, vamos para segunda parte.

A primeira parte foi apenas para instalação e a segunda agora é para criação e uso de um pipeline.

Vamos definir pipeline como uma sequência de instruções que serão executadas até finalizar e prover uma entrega.

Nosso cenário será o seguinte:

  • Um servidor com o Jenkins instalado e configurado (feito no posto anterior)
  • Um servidor com linux instalado onde iremos subir um pacote de uma aplicação java que ao final do deploy nos dará uma ferramenta de monitoração
  • Chave SSH entre o servidor do Jenkins e o servidor onde a aplicação será instalada
  • Pipeline com as instruções para cada passo que iremos definir no processo de deploy (cópia de arquivos, descompactação, ajuste de parâmetros, criação de serviços, start

Uma observação importante: Eu não sou um expert e nem estou falando que este modelo de pipeline que estou propondo é o melhor e que não podemos fazer de outra forma. Essa foi uma forma que achei para ajudar em uma necessidade do meu dia-a-dia, OK? Cada um deve avaliar a melhor forma de usar a estrutura de funcionalidade e adaptar para o seu uso.

Agora vamos a criação do pipeline na console do Jenkins. 

Para isso clicar em New Job - Insira um nome - Clique em pipeline - OK


Agora irá abrir uma nova tela de configuração onde podemos colocar um comentário para documentarmos melhor o pipeline, algumas opções via checkbox para não termos deploys concorrentes, usar po Git, etc.

No nosso caso, não iremos marcar nenhuma opção. Vamos direto no campo pipeline e inserir a estrutura abaixo:

pipeline {
    agent none
    environment {
            IP = "xx.xx.xx.xx"
    }
    stages {
        stage ('Copia o pacote da aplicacao para o servidor') {
            agent any
           
            steps {
                sh '''#!/bin/bash
                scp /home/jenkins/repoapp/mon-java.tar.gz root@$IP:/opt
                '''
            }
        }
        stage ('SSH + desccompacta pacote do aplicacao') {
            agent any
            steps {
               sh '''#!/bin/bash
               ssh -o StrictHostKeyChecking=no root@$IP << EOF
               tar xzvf /opt/mon-java.tar.gz -C /opt
               exit
               EOF
               '''
            }
           
        }
        stage ('Adiciona usuario banco Postgres e muda permissao do data e tmp'){
            agent any
            steps {
                sh '''#!/bin/bash
                ssh -o StrictHostKeyChecking=no root@$IP << EOF
                useradd -m -d /opt/ManageEngine/OpManager/pgsql/ postgres
                chown -R postgres:postgres /opt/ManageEngine/OpManager/pgsql/tmp/
                chown -R postgres:postgres /opt/ManageEngine/OpManager/pgsql/data/
                exit
                EOF
                '''
            }
        }
        stage ('Cria o serviço e incia a aplicacao'){
            agent any
            steps {
                sh '''#!/bin/bash
                ssh -o StrictHostKeyChecking=no root@$IP << EOF
                cd /opt/ManageEngine/OpManager/bin/
                ./linkAsService.sh
                systemctl daemon-reload
                systemctl start OpManager.service
                exit 0
                EOF
                '''
            }
        }
        stage ('Alguns tunings na aplicacao'){
            agent any
            steps {
                sh '''#!/bin/bash
                ssh -o StrictHostKeyChecking=no root@$IP << EOF
                sed -i 's/wrapper.java.initmemory=512/wrapper.java.initmemory=600/g' /opt/ManageEngine/OpManager/conf/wrapper.conf
                sed -i 's/wrapper.java.maxmemory=1024/wrapper.java.maxmemory=1500/g' /opt/ManageEngine/OpManager/conf/wrapper.conf
                sed -i 's/24MB/1024MB/g' /opt/ManageEngine/OpManager/pgsql/data/postgres_ext.conf
                sleep 4m
                exit
                EOF
                '''
            }
        }
 }
}

Vejam que temos uma variável neste pipeline: IP = "xx.xx.xx.xx"
Trabalhar com variáveis torna o nosso pipeline mais preciso, pois em qualquer ponto necessário iremos declarar apenas a variável e seu conteúdo pode sofrer alterações que será replicado para todos. =)
Vale o mesmo conceito adotado em programação...

O IP da nossa máquina de aplicação neste exemplo é: 192.168.100.109, então devemos colocar este IP na variável.

Agora vamos no servidor do Jenkins, na shell do user Jenkins copiar nossa chave SSH para o servidor de aplicação:


Com isso, ao tentar acessar SSH o servidor destino através do shell do usuário Jenkins, não será solicitado senha (por que no meu exemplo foi configurado dessa forma). Se você colocar senha em sua chave, será necessário criar um mecanimos para essa senha seja digitada automaticamente no pipeline. 

** Importante **

A questão de ter que fazer o passo da chave SSH pode ser resolvido se no seu processo de deploy ou criação do ambiente (máquina virtual, instância, físico não importa) se você já adicionar a chave SSH do usuário Jenkins =)

Bem, agora na console do Jenkins vamos  clicar no pipeline que criamos e na opção Build Now, para o processo começar.

O legal é que para cada passo que criamos dentro do pipeline, ele irá gerar uma saída com a identificação, e caso necessário um log da execução.



Ao término, dando tudo certo, o pipeline ficar tudo "azul" indicando que todos os passos concluíram com sucesso.
Caso algum item apresente erro, teremos uma indicação na cor vermelha e com um breve log do possível erro para tratarmos.


Legal também é que temos o tempo que cada step demorou em sua execução completa.

Agora validando no servidor de aplicação, devemos ter nossa ferramenta de monitoração instalada, configurada com os tunings que fizemos, os serviços criados, etc. Sendo que no nosso caso basta apenas acessar a URL e autenticar para ver se ela encontra-se disponível para uso.





A ideia deste pipeline é para uma execução bem simples, mas que automatiza uma tarefa que poderia demorar fazendo tudo de forma manual, nos dando maior possibilidade de erros humanos, cada um fazendo um deploy de um jeito diferente, etc.

Lembre-se que existe uma infinidade de possibilidades de configuração e cenários para uso. Com issa ideia "base" espero que vocês possam adequar so seu modelo de uso e assim tornar tarefas corriqueiras automatizadas da melhor forma possível.

Por hoje é isso!
Abs e até a próxima.
:wq!

3 comentários:

  1. Grande Joao! Legal o artigo sobre o pipeline e que bom que voce nesta pegada! :)

    Abs

    ResponderExcluir
  2. Top o post Mestre. Essa ideia , acho que amadureceu na operação, quando pediam vários deploy nas Dockers numa sexta-feira kkkkkkkk . Parabéns Guerreiro

    ResponderExcluir
  3. Top o post Mestre. Essa ideia , acho que amadureceu na operação, quando pediam vários deploy nas Dockers numa sexta-feira kkkkkkkk . Parabéns Guerreiro

    ResponderExcluir