Série API em Flask - Parte 16 - CI e CD com Jenkins, Python, Flask e Fabric
Nesse artigo vamos finalizar o processo de desenvolvimento de software colocando o Flask Api Users no Jenkins, executando os testes e fazendo deploy na digital ocean.
Para entendimento, segue os capítulos que serão abordados.
Capítulo 1: Introdução, configuração e Hello World
Capítulo 2: Organizando as dependências e requerimentos
Capítulo 3: Configurando o pytest e nosso primeiro teste
Capítulo 4: Configurando o Makefile
Capítulo 5: Adicionando o MongoDB
Capítulo 6: Criando e testando o modelo de usuários
Capítulo 7: Criando usuários
Capítulo 8: Listando usuários
Capítulo 9: Buscando usuários
Capítulo 10: Editando um usuário
Capítulo 11: Deletando um usuário
Capítulo 12: Autênticação por JWT
Capítulo 13: Criando um container Docker
Capítulo 14: Deploy Flask na Digital Ocean
Capítulo 15: Automatizando o processo de deploy com Fabric
Capítulo 16: CI e CD com Jenkins, Python, Flask e Fabric Estamos aqui
Capítulo 17: Utilizando o RabbitMQ com Flask e Sendgrid para enviar e-mails de boas vindas e ativar a conta do usuário
O repositório com todo o código fonte esta aqui. Os capítulos estão em branches
.
Configurações do servidor
Instalar os pacotes no sistema operacional.
root@ip-172-31-7-143:~# apt update && apt upgrade && apt install build-essential make python3-venv python3-dev git zsh openjdk-8-jdk
Editar o arquivo vim /etc/environment
JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin"
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$JAVA_HOME"
Instalando o Jenkins
Para instalar o Jenkins, eu segui este tutorial oficial.
root@ip-172-31-7-143:~# wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
Edite o arquivo vim /etc/apt/sources.list
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu bionic partner
# deb-src http://archive.canonical.com/ubuntu bionic partner
deb https://pkg.jenkins.io/debian binary/
Em seguida atualize o repositório apt
e instale o jenkins
:
root@ip-172-31-7-143:~# apt update && apt install jenkins
E iniciar o serviço:
root@ip-172-31-7-143:~# service jenkins start
Configurando o usuário Jenkins
Entre com o usuário jenkins
, su - jenkins
, e configurar o gitconfig
.
[user]
name = Jenkins Build
email = jenkins@teste.com.br
Depois gere as chaves ssh-rsa
:
root@ip-172-31-7-143:~# ssh-keygen -t rsa -C "jenkins@teste.com.br"
Passos importantes
Copie a chave
.ssh/id_rsa.pub
e cole nogithub
Copie a chave
.ssh/id_rsa.pub
e cole o seu conteúdo em.ssh/authorized_keys
do servidor(es) de deploy
Configurações no Jenkins
Colocar o shell para /bin/bash
em Configure System
Colocar o projeto como Project Matrix Based em Configure Global Security
Colocar a chave privada em uma credential em Credentials
no sidebar esquerdo.
Jenkinsfile
O Jenkinsfile é o script para executar todo o pipeline do projeto. Caso queria visualiza-lo no repositório acesse aqui:
pipeline {
environment {
MONGODB_URI_TEST = credentials('API_USERS_MONGO_DB_TEST')
FLASK_ENV = 'testing'
FLASK_APP = 'application.py'
DEBUG = true
HOSTS = credentials('API_USERS_DEPLOY_HOSTS')
}
options
{
skipDefaultCheckout(true)
buildDiscarder(logRotator(numToKeepStr: '3', daysToKeepStr: '7'))
timestamps()
}
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage ("Install Dependencies") {
steps {
sh """
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r ${env.WORKSPACE}/requirements/test.txt
"""
}
}
stage('Run Tests') {
steps {
sh """
source .venv/bin/activate
echo "Running the unit test..."
make clean
make coverage
"""
}
}
stage('Generate Release and deploy') {
steps {
script {
def version = readFile encoding: 'utf-8', file: '__version__.py'
def message = "Latest ${version}. New version:"
def releaseInput = input(
id: 'userInput',
message: "${message}",
parameters: [
[
$class: 'TextParameterDefinition',
defaultValue: 'uat',
description: 'Release candidate',
name: 'rc'
]
]
)
sh """
make release v=${releaseInput}
source .venv/bin/activate
fab -H ${env.HOSTS} deploy --tag ${releaseInput}
"""
}
}
}
}
post {
always {
sh """
rm -rf .venv
"""
}
success {
echo "Success"
echo "TODO: Send to slack webhook"
}
failure {
echo "TODO: Send e-mail, when failed"
}
}
}
Considerações finais.
O Jenkins é uma poderosa ferramenta para fazer CI e CD de seus produtos de software e feita pela comunidade como open source. Existem outras ferramentas como o circleci, travis, semaphore, gitlab-ci, pipeline do bitbucket. Porém existem alguns limites (por usuário, projeto) para uso dessa ferramentas, caso queira usar todas as funcionalidades é necessário pagar.
Com o Jenkins instalado em um servidor você tem acesso ilimitado a todos os recursos. Em contrapartida é necessário realizar toda a configuração desde infraestrutura do servidor até configurações do software, sendo então, um ponto negativo. Continuando neste tópico, os recursos aqui apresentados são bem básicos, logo, existem recursos avançados como:
clusters de build com
masters
eslaves
Builds disparados atrabeś de gatilhos do Github (webhooks)
Gerar artefatos, .zip, binários, .egg, .whl, .jar, etc…, do software.
Integrar com ferramentas como SonarQube
Criar imagens
docker
e fazer deploy em umECS
Enfim, as possibilidades são enormes e para isso necessita de estudo para aplicar esses recursos a necessidade de cada projeto de software.
Agradeço a todos e fiquem a vontade para mandar dúvidas, sugestões e criticas.
Valeu. Abraços a todos.