No mundo acelerado do desenvolvimento de software, entregar aplicativos de alta qualidade de forma rápida e confiável é crucial. É aí que entra o CI/CD (Integração Contínua e Entrega/Implantação Contínua).
O CI/CD é um conjunto de práticas e ferramentas projetadas para automatizar e otimizar o processo de integração de mudanças de código, testá-las e implantá-las em produção. Ao adotar o CI/CD, sua equipe pode reduzir erros manuais, acelerar os ciclos de lançamento e garantir que seu código esteja sempre em um estado implantável.
Neste tutorial, vamos focar em uma abordagem amigável para iniciantes para configurar um pipeline básico de CI/CD usando o Bitbucket, um servidor Linux e Python com Flask. Especificamente, vamos criar um processo automatizado que puxa as últimas mudanças de um repositório do Bitbucket para o seu servidor Linux sempre que houver um push ou merge para um branch específico.
Esse processo será alimentado por webhooks do Bitbucket e por um servidor Python simples baseado em Flask que escuta eventos de webhook recebidos e aciona a implantação.
É importante observar que o CI/CD é um campo vasto e complexo, e este tutorial é projetado para fornecer uma compreensão fundamental ao invés de ser um guia exaustivo.
Vamos abordar o básico de configurar um pipeline de CI/CD usando ferramentas acessíveis para iniciantes. Apenas tenha em mente que sistemas de CI/CD do mundo real frequentemente envolvem ferramentas e configurações mais avançadas, como containerização, orquestração e ambientes de teste de vários estágios.
Até o final deste tutorial, você terá um exemplo prático de como automatizar implantações usando Bitbucket, Linux e Python, que você pode expandir à medida que se sentir mais confortável com os conceitos de CI/CD.
Sumário:
Por que o CI/CD é importante?
O CI/CD tornou-se um pilar do desenvolvimento de software moderno por várias razões. Em primeiro lugar, acelera o processo de desenvolvimento. Automatizando tarefas repetitivas como testes e implantação, os desenvolvedores podem focar mais na escrita de código e menos em processos manuais. Isso resulta em uma entrega mais rápida de novos recursos e correções de bugs, o que é especialmente importante em mercados competitivos onde a velocidade pode ser um diferenciador.
Outro benefício-chave do CI/CD é a redução de erros e a melhoria da confiabilidade. Testes automatizados garantem que cada alteração de código seja rigorosamente verificada quanto a problemas antes de ser integrada ao código principal. Isso minimiza o risco de introduzir bugs que possam prejudicar a aplicação ou exigir correções custosas posteriormente. Os pipelines de implantação automatizada também reduzem a probabilidade de erro humano durante o processo de lançamento, garantindo que as implantações sejam consistentes e previsíveis.
CI/CD também promove uma melhor colaboração entre os membros da equipe. Nos fluxos de trabalho de desenvolvimento tradicionais, integrar alterações de código de vários desenvolvedores pode ser um processo demorado e propenso a erros. Com CI/CD, o código é integrado e testado com frequência, muitas vezes várias vezes ao dia. Isso significa que conflitos são detectados e resolvidos rapidamente, e a base de código permanece em um estado estável. Como resultado, as equipes podem trabalhar de forma mais eficiente e com maior confiança, mesmo quando vários colaboradores estão trabalhando em diferentes partes do projeto simultaneamente.
Finalmente, CI/CD apoia a melhoria contínua e a inovação. Ao automatizar o processo de implantação, as equipes podem liberar atualizações para a produção com mais frequência e com menos risco. Isso permite que elas obtenham feedback dos usuários mais rapidamente e iterem em seus produtos de forma mais eficaz.
O que Vamos Cobrir Neste Tutorial
Neste tutorial, vamos passar pelo processo de configuração de um pipeline CI/CD simples que automatiza a implantação de alterações de código de um repositório Bitbucket para um servidor Linux. Aqui está o que você aprenderá:
-
Como configurar um repositório Bitbucket para enviar notificações de webhook sempre que houver um push ou merge para um branch específico.
-
Como configurar um servidor Python baseado em Flask no seu servidor Linux para escutar eventos de webhook recebidos.
-
Como escrever um script que puxa as últimas mudanças do repositório e as implementa no servidor.
-
Como testar e solucionar problemas no seu processo de implementação automatizada.
Até o final deste tutorial, você terá um exemplo funcional de um pipeline básico de CI/CD que você pode personalizar e expandir conforme necessário. Vamos começar!
Passo 1: Configurar um Webhook no Bitbucket
Antes de começar com a configuração, vamos explicar brevemente o que é um webhook e como ele se encaixa em nosso processo de CI/CD.
Um webhook é um mecanismo que permite que um sistema notifique outro sistema sobre um evento em tempo real. No contexto do Bitbucket, um webhook pode ser configurado para enviar uma solicitação HTTP (geralmente uma solicitação POST com dados de carga) para uma URL especificada sempre que um evento específico ocorre no seu repositório, como um push para um branch ou a mesclagem de uma solicitação pull.
No nosso caso, o webhook notificará nosso servidor Python baseado em Flask (executando no seu servidor Linux) sempre que houver um push ou merge em um branch específico. Essa notificação acionará um script no servidor para puxar as últimas mudanças do repositório e implementá-las automaticamente. Essencialmente, o webhook age como a ponte entre o Bitbucket e seu servidor, possibilitando a automação perfeita do processo de implementação.
Agora que você entende o papel de um webhook, vamos configurar um no Bitbucket:
-
Faça login no Bitbucket e navegue até o seu repositório.
-
No painel lateral esquerdo, clique em Configurações.
-
Na seção Fluxo de Trabalho, encontre e clique em Webhooks.
-
Clique no botão Adicionar webhook.
-
Insira um nome para o seu webhook (por exemplo, “Pull Automático”).
-
No campo URL, forneça a URL do seu servidor onde o webhook enviará a solicitação. Se você estiver executando um aplicativo Flask localmente, isso seria algo como
http://seu-ip-do-servidor/pull-repo
. (Para ambientes de produção, é altamente recomendado usar HTTPS para proteger a comunicação entre o Bitbucket e seu servidor.) -
Na seção Triggers, escolha os eventos aos quais deseja ouvir. Para este exemplo, selecionaremos Push (e opcionalmente, Pull Request Merged se desejar fazer o deploy após merges também).
-
Salve o webhook com um nome autoexplicativo para que seja fácil identificá-lo posteriormente.
Assim que o webhook estiver configurado, o Bitbucket enviará uma solicitação POST para o URL especificado sempre que o evento selecionado ocorrer. Nos próximos passos, configuraremos um servidor Flask para lidar com essas solicitações recebidas e acionar o processo de implantação.
Aqui está o que você deve ver ao configurar o webhook do Bitbucket
Passo 2: Configure o Ouvinte Flask no seu Servidor Linux
No próximo passo, você configurará um servidor web simples em sua máquina Linux que ficará ouvindo o webhook do Bitbucket. Quando receber a notificação, ele executará um git pull
ou um pull forçado (em caso de alterações locais) para atualizar o repositório.
Instalar o Flask:
Para criar a aplicação Flask, primeiro instale o Flask executando:
pip install flask
Criar o Aplicativo Flask:
Crie um novo script em Python (por exemplo, app_repo_pull.py
) em seu servidor e adicione o seguinte código:
from flask import Flask
import subprocess
app = Flask(__name__)
@app.route('/pull-repo', methods=['POST'])
def pull_repo():
try:
# Buscar as últimas alterações do repositório remoto
subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"], check=True)
# Reset forçado do branch local para corresponder ao branch remoto 'test'
subprocess.run(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"], check=True) # Substitua 'test' pelo nome do seu branch
return "Force pull successful", 200
except subprocess.CalledProcessError:
return "Failed to force pull the repository", 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Aqui está o que este código faz:
-
subprocess.run
(["git", "-C", "/caminho/para/seu/repositório", "fetch"])
: Este comando busca as últimas alterações do repositório remoto sem afetar o diretório de trabalho local. -
subprocess.run
(["git", "-C", "/caminho/para/seu/repositório", "reset", "--hard", "origin/test"])
: Este comando realiza um reset rígido, forçando o repositório local a corresponder ao ramo remototest
. Substituatest
pelo nome do seu ramo.
Certifique-se de substituir /caminho/para/seu/repositório
pelo caminho real do seu repositório Git local.
Passo 3: Expor o Aplicativo Flask (Opcional)
Se deseja que o aplicativo Flask seja acessível de fora do seu servidor, você precisa expô-lo publicamente. Para isso, você pode configurar um proxy reverso com o NGINX. Veja como fazer isso:
Primeiramente, instale o NGINX se ainda não o tiver feito, executando o seguinte comando:
sudo apt-get install nginx
Em seguida, será necessário configurar o NGINX para encaminhar solicitações para o seu aplicativo Flask. Abra o arquivo de configuração do NGINX:
sudo nano /etc/nginx/sites-available/default
Modifique a configuração para incluir este bloco:
server {
listen 80;
server_name your-server-ip;
location /pull-repo {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Agora, apenas recarregue o NGINX para aplicar as alterações:
sudo systemctl reload nginx
Passo 4: Testar a Configuração
Agora que tudo está configurado, vá em frente e inicie o aplicativo Flask executando este script Python:
python3 app_repo_pull.py
Agora para testar se tudo está funcionando:
- Faça um commit: Faça um commit e envie para o ramo
test
no seu repositório do Bitbucket. Essa ação irá acionar o webhook.
-
Acionamento do webhook: O webhook enviará uma solicitação POST para o seu servidor. O aplicativo Flask receberá essa solicitação, realizará uma atualização forçada a partir do ramo
test
e atualizará o repositório local. -
Verifique a atualização: Verifique a saída de log do seu aplicativo Flask ou inspecione o repositório local para confirmar que as alterações foram puxadas e aplicadas com sucesso.
Passo 5: Considerações de Segurança
Ao expor um aplicativo Flask à internet, garantir a segurança do seu servidor e aplicativo é crucial para protegê-lo de acesso não autorizado, violações de dados e ataques. Aqui estão as áreas-chave para se concentrar:
1. Utilize um Servidor Seguro com Regras de Firewall Adequadas
Um servidor seguro é aquele configurado para minimizar a exposição a ameaças externas. Isso envolve o uso de regras de firewall, minimização de serviços desnecessários e garantia de que apenas as portas necessárias estejam abertas para comunicação.
Exemplo de configuração segura do servidor:
-
Software mínimo: Apenas instale o software que você precisa (por exemplo, Python, Flask, NGINX) e remova serviços desnecessários.
-
Atualizações do sistema operacional: Certifique-se de que o sistema operacional do seu servidor está atualizado com os últimos patches de segurança.
-
Configuração do firewall: Use um firewall para controlar o tráfego de entrada e saída e limitar o acesso ao seu servidor.
Por exemplo, uma configuração básica do UFW (Firewall Descomplicado) no Ubuntu pode se parecer com isso:
# Permitir SSH (porta 22) para acesso remoto
sudo ufw allow ssh
# Permitir HTTP (porta 80) e HTTPS (porta 443) para tráfego web
sudo ufw allow http
sudo ufw allow https
# Habilitar o firewall
sudo ufw enable
# Verificar o status do firewall
sudo ufw status
Neste caso:
-
O firewall permite conexões SSH de entrada na porta 22, HTTP na porta 80 e HTTPS na porta 443.
-
Todos os portos ou serviços desnecessários devem ser bloqueados por padrão para limitar a exposição a ataques.
Regras adicionais do firewall:
-
Limitar o acesso ao endpoint do webhook: Idealmente, permita apenas o tráfego para o endpoint do webhook a partir dos endereços IP do Bitbucket para evitar acesso externo. Você pode configurar isso em seu firewall ou usando seu servidor web (por exemplo, NGINX) aceitando apenas solicitações do intervalo de IP do Bitbucket.
-
Negar todo o outro tráfego de entrada: Para qualquer serviço que não precisa ser exposto à internet (por exemplo, portos de banco de dados), certifique-se de que esses portos estejam bloqueados.
2. Adicionar Autenticação ao Aplicativo Flask
Como seu aplicativo Flask será acessível publicamente por meio da URL do webhook, você deve considerar adicionar autenticação para garantir que apenas usuários autorizados (como os servidores do Bitbucket) possam acionar a solicitação.
Exemplo de Autenticação Básica:
Você pode usar uma autenticação simples baseada em token para proteger seu endpoint de webhook. Aqui está um exemplo de como modificar seu aplicativo Flask para exigir um token de autenticação:
from flask import Flask, request, abort
import subprocess
app = Flask(__name__)
# Defina um token secreto para verificação de webhook
SECRET_TOKEN = 'your-secret-token'
@app.route('/pull-repo', methods=['POST'])
def pull_repo():
# Verifique se a solicitação contém o token correto
token = request.headers.get('X-Hub-Signature')
if token != SECRET_TOKEN:
abort(403) # Proibido se o token estiver incorreto
try:
subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"], check=True)
subprocess.run(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"], check=True)
return "Force pull successful", 200
except subprocess.CalledProcessError:
return "Failed to force pull the repository", 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Como funciona:
-
O
X-Hub-Signature
é um cabeçalho personalizado que você adiciona à solicitação ao configurar o webhook no Bitbucket. -
Apenas solicitações com o token correto serão permitidas para acionar a extração. Se o token estiver ausente ou incorreto, a solicitação é rejeitada com uma resposta
403 Proibido
.
Você também pode usar formas mais complexas de autenticação, como OAuth ou HMAC (Código de Autenticação de Mensagem Baseado em Hash), mas essa abordagem simples de token funciona para muitos casos.
3. Use HTTPS para Comunicação Segura
É crucial criptografar os dados transmitidos entre seu aplicativo Flask e o webhook do Bitbucket, bem como quaisquer dados sensíveis (como tokens ou senhas) sendo transmitidos pela rede. Isso garante que os atacantes não consigam interceptar ou modificar os dados.
Por que HTTPS?
-
Encriptação de dados: O HTTPS criptografa a comunicação, garantindo que dados sensíveis, como seu token de autenticação, não sejam expostos a ataques de intermediários.
-
Confiança e integridade: O HTTPS ajuda a garantir que os dados recebidos pelo seu servidor não foram adulterados.
Usando o Let’s Encrypt para Proteger seu Aplicativo Flask com SSL:
- Instale o Certbot (a ferramenta para obter certificados Let’s Encrypt):
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx
Obtenha um certificado SSL gratuito para seu domínio:
sudo certbot --nginx -d your-domain.com
-
Este comando configurará automaticamente o Nginx para usar HTTPS com um certificado SSL gratuito do Let’s Encrypt.
-
Garanta que o HTTPS seja usado: Certifique-se de que seu aplicativo Flask ou a configuração do Nginx force todo o tráfego a usar HTTPS. Você pode fazer isso configurando uma regra de redirecionamento no Nginx:
server {
listen 80;
server_name your-domain.com;
# Redirecionar HTTP para HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Outra configuração do Nginx...
}
Renovação Automática: Os certificados Let’s Encrypt são válidos por 90 dias, então é importante configurar a renovação automática:
sudo certbot renew --dry-run
Este comando testa o processo de renovação para garantir que tudo esteja funcionando.
4. Logging e Monitoramento
Implemente logging e monitoramento para sua aplicação Flask para rastrear qualquer tentativa não autorizada, erros ou atividades incomuns:
-
Registrar requisições: Registre todas as requisições recebidas, incluindo o endereço IP, cabeçalhos da requisição e status da resposta, para que você possa monitorar qualquer atividade suspeita.
-
Utilizar ferramentas de monitoramento: Configure ferramentas como Prometheus, Grafana, ou New Relic para monitorar o desempenho do servidor e a saúde da aplicação.
Conclusão
Neste tutorial, exploramos como configurar um pipeline de CI/CD simples e amigável para iniciantes que automatiza implantações usando o Bitbucket, um servidor Linux e Python com Flask. Aqui está um resumo do que você aprendeu:
-
Fundamentos de CI/CD: Discutimos os princípios básicos da Integração Contínua (CI) e da Entrega/Implantação Contínua (CD), que são práticas essenciais para automatizar a integração, teste e implantação de código. Você aprendeu como CI/CD ajuda a acelerar o desenvolvimento, reduzir erros e melhorar a colaboração entre os desenvolvedores.
-
Configurando Webhooks do Bitbucket: Você aprendeu como configurar um webhook do Bitbucket para notificar seu servidor sempre que houver um push ou merge em um branch específico. Esse webhook serve como um gatilho para iniciar o processo de implantação automaticamente.
-
Criando um Ouvinte de Webhook Baseado em Flask: Mostramos como configurar um aplicativo Flask em seu servidor Linux para ouvir solicitações de webhook vindas do Bitbucket. Esse aplicativo Flask recebe as notificações e executa os comandos Git necessários para fazer pull e implantar as alterações mais recentes.
-
Automatizando o Processo de Implantação: Usando Python e Flask, automatizamos o processo de puxar alterações do repositório do Bitbucket e realizar um pull forçado para garantir que o código mais recente seja implantado. Você também aprendeu como configurar o servidor para expor o aplicativo Flask e aceitar solicitações com segurança.
-
Considerações de Segurança: Cobrimos etapas críticas de segurança para proteger seu processo de implantação:
-
Regras do Firewall: Discutimos a configuração de regras de firewall para limitar a exposição e garantir que apenas o tráfego autorizado (do Bitbucket) possa acessar seu servidor.
-
Autenticação: Adicionamos autenticação baseada em token para garantir que apenas solicitações autorizadas possam acionar implantações.
-
HTTPS: Explicamos como garantir a comunicação entre seu servidor e o Bitbucket usando certificados SSL do Let’s Encrypt.
-
Registro e Monitoramento: Por fim, recomendamos configurar registro e monitoramento para acompanhar qualquer atividade incomum ou erros.
-
Próximos Passos
Ao final deste tutorial, você agora tem um exemplo funcional de um pipeline de implantação automatizado. Embora esta seja uma implementação básica, ela serve como uma base sobre a qual você pode construir. À medida que você se sentir mais confortável com CI/CD, pode explorar tópicos avançados como:
-
Pipelines de implantação em múltiplas etapas
-
Integração com ferramentas de conteinerização como Docker
-
Estratégias de teste e implantação mais complexas
-
Uso de ferramentas de orquestração como Kubernetes para escalabilidade
As práticas de CI/CD estão em constante evolução e, ao dominar o básico, você se preparou para o sucesso à medida que expande suas habilidades nesta área. Boa automação e obrigado por ler!
Você pode fazer um fork do código a partir daqui.
Source:
https://www.freecodecamp.org/news/create-a-basic-cicd-pipeline-with-webhooks-on-linux/