Lucas Simon

Web Developer. lucassrod@gmail.com

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.

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

  1. Copie a chave .ssh/id_rsa.pub e cole no github

  2. 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

Configure shell

Colocar o projeto como Project Matrix Based em Configure Global Security

Configure Authorization

Colocar a chave privada em uma credential em Credentials no sidebar esquerdo.

Configure private key

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:

  1. clusters de build com masters e slaves

  2. Builds disparados atrabeś de gatilhos do Github (webhooks)

  3. Gerar artefatos, .zip, binários, .egg, .whl, .jar, etc…, do software.

  4. Integrar com ferramentas como SonarQube

  5. Criar imagens docker e fazer deploy em um ECS

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.