Criação de uma esteira CI/CD para Python usando o Jenkins

Devido ao grande crescimento da utilização de Python, decidi criar um pipeline de entrega de código para esta linguagem, utilizando somente o Jenkins como orquestrador.

Repositório do GitHub deste projeto:

Objetivos:

  1. Integrar o pipeline com um SCM;
  2. Construir uma imagem Python usando Dockerfile;
  3. Realizar testes estáticos;
  4. Quebrar a entrega caso falhe nos testes (Quality Gate);
  5. Enviar a imagem para um repositório remoto;
  6. Ao final do build, executar um container com base na imagem criada.

O foco desta publicação, não é explicar o arquivo Jenkinsfile criado para a execução deste pipeline e sim testar itens listados acima. Posteriormente publicarei em um outro post com a descrição detalhada do pipeline.

Pós publicação:

Esse pipeline foi criado apenas para conhecimento, notem que não estou realizando testes integrados e também não verifico a integridade da imagem.

Topologia:

Configurações iniciais:

No servidor Jenkins:

Foi necessário a instalação do Docker e do Sonar-Scanner, os links para instalação estão logo abaixo:

Obs: importante verificar o caminho onde foi instalado o sonar-scanner.

No servidor SonarQube:

Sem muito o que configurar, no meu caso apenas tive que instalar o Docker e o Docker-Compose. Fica como referência este documento para instalação:

No servidor de Execução:

Como a aplicação é pequena, decidi utilizar o mesmo servidor do SonarQube para a execução, como já tinha o Docker instalado, não precisei de mais nenhuma configuração.

Parte prática:

Primeiramente vamos configurar o job no Jenkins. Como o pipeline inteiro foi escrito “as code”, temos apenas que informar ao Jenkins o repositório que vamos buscar as informações, as credenciais de acesso e o nome do arquivo (Jenkinsfile.groovy). Item 1 realizado!

Tela de configuração do Job no Jenkins.

Agora, basta configurar o webhook do SonarQube:

Tela de configuração de Webhook no SonarQube.

Observe que o endereço padrão é [Endereço do serviço do Jenkins]/sonarqube-webhook.

Também configurei o SonarQube para aceitar o mínimo de 40% de cobertura do código.

Tela de configuração do Quality Gate no SonarQube.

Agora sim vamos para a execução do pipeline! Rodei o build manualmente com a opção “Build Now” do Jenkins. É possível configurar um webhook do SCM para o Jenkins para cada push, mas não configurei porque minha instância está rodando em rede privada. O código atendeu os requisitos e passou por todas as etapas com sucesso! Item 2 realizado!

Tela do Jenkins (Blue Ocean) com o resumo do Pipeline.

Verificando o status do Quality Gate, percebemos que a resposta enviada pelo webhook do sonar foi: “Quality gate is ‘OK’”. Item 3 realizado!

Retorno do step Quality Gate.

No SonarQube, vemos toda a análise do código:

Tela de resumo do projeto no SonarQube.

A imagem foi publicada em meu repositório no DockerHub no step “Docker Push”. Item 5 realizado!

Imagem jenkins-python-full-pipeline tag 1 no Docker Hub.

Finalmente o Jenkins “entrou” via SSH (utilizando o plugin Publish Over SSH) no servidor de execução, fez um pull da imagem que acabamos de criar e rodou o contêiner. Item 6 realizado!

Conferindo no servidor de execução, temos tanto a imagem, quanto o contêiner:

Imagem criada no pipeline, no servidor de execução.
Contêiner executado durante o pipeline.

Bom, vamos testar se o Quality Gate realmente funciona, voltando na configuração do SonarQube, definimos um nível mínimo de cobertura de 70% e rodamos novamente o build.

Observe a resposta enviada pelo webhook do sonar foi: “Quality gate is ‘ERROR’”, o pipeline então foi quebrado e não foi feito o push da imagem para o Docker Hub e muito menos foi executado no servidor. Item 4 realizado!

Nos vemos até a próxima publicação!

Data scientist and devops enthusiast.

Data scientist and devops enthusiast.