No mundo acelerado do desenvolvimento de software, entregar aplicações de alta qualidade de forma rápida e confiável é crucial. É aqui que CI/CD (Integração Contínua e Entrega/Implantação Contínua) entra em cena.
CI/CD é um conjunto de práticas e ferramentas projetadas para automatizar e simplificar o processo de integração de alterações de código, testá-las e implantá-las em produção. Ao adotar CI/CD, sua equipe pode reduzir erros manuais, acelerar 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 sobre como configurar um pipeline básico de CI/CD usando Bitbucket, um servidor Linux e Python com Flask. Especificamente, vamos criar um processo automatizado que puxa as últimas alterações de um repositório Bitbucket para o seu servidor Linux sempre que houver um push ou merge em um branch específico.
Esse processo será alimentado por webhooks do Bitbucket e um servidor Python simples baseado em Flask que escuta eventos de webhook recebidos e aciona a implantação.
É importante notar que CI/CD é um campo vasto e complexo, e este tutorial foi projetado para fornecer uma compreensão fundamental, em vez de ser um guia exaustivo.
Vamos cobrir o básico de como configurar um pipeline de CI/CD usando ferramentas que são acessíveis para iniciantes. Apenas tenha em mente que sistemas de CI/CD do mundo real muitas vezes envolvem ferramentas e configurações mais avançadas, como containerização, orquestração e ambientes de teste em múltiplas etapas.
Até o final deste tutorial, você terá um exemplo funcional de como automatizar implantações usando Bitbucket, Linux e Python, que você pode aprimorar à medida que se sentir mais confortável com os conceitos de CI/CD.
Sumário:
Por que CI/CD é Importante?
CI/CD tornou-se um pilar do desenvolvimento de software moderno por várias razões. Em primeiro lugar, acelera o processo de desenvolvimento. Ao automatizar tarefas repetitivas como testes e implantações, os desenvolvedores podem se concentrar mais em escrever código e menos em processos manuais. Isso leva a 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 diferencial.
Outro benefício importante 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 poderiam interromper a aplicação ou exigir correções caras mais tarde. Pipelines de implantação automatizados 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. Em 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 precocemente, 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.
Por fim, o 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 itere em seus produtos de forma mais eficaz.
O que Vamos Cobrir Neste Tutorial
No tutorial de hoje, vamos percorrer o 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ê vai 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 alterações do repositório e as implanta no servidor.
-
Como testar e solucionar problemas no seu processo de implantaçã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 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 ocorrer em seu repositório, como um push para um branch ou uma mesclagem de pull request.
No nosso caso, o webhook notificará nosso servidor Python baseado em Flask (executando no seu servidor Linux) sempre que houver um push ou mesclagem em um branch específico. Essa notificação acionará um script no servidor para puxar as últimas alterações do repositório e implantá-las automaticamente. Essencialmente, o webhook atua como a ponte entre o Bitbucket e seu servidor, permitindo a automação perfeita do processo de implantaçã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 recomendável usar HTTPS para garantir a comunicação entre o Bitbucket e seu servidor.) -
No campo Triggers, escolha os eventos que deseja monitorar. Para este exemplo, selecionaremos Push (e opcionalmente, Pull Request Merged se você quiser implantar após as mesclagens, também).
-
Salve o webhook com um nome autoexplicativo para que seja fácil de identificar depois.
Uma vez que o webhook esteja configurado, o Bitbucket enviará uma solicitação POST para a URL especificada toda vez 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
Etapa 2: Configure o Listener Flask em 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.
Instale o Flask:
Para criar a aplicação Flask, primeiro instale o Flask executando:
pip install flask
Crie a Aplicação Flask:
Crie um novo script Python (por exemplo, app_repo_pull.py
) em seu servidor e adicione o código a seguir:
from flask import Flask
import subprocess
app = Flask(__name__)
@app.route('/pull-repo', methods=['POST'])
def pull_repo():
try:
# Obter as últimas alterações do repositório remoto
subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"], check=True)
# Resetar forçadamente o 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 obtém 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 forçado, fazendo com que o repositório local corresponda ao branch remototest
. Substituatest
pelo nome do seu branch.
Certifique-se de substituir /caminho/para/seu/repositório
pelo caminho real do seu repositório Git local.
Passo 3: Expor o App Flask (Opcional)
Se você quiser que o app 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:
Primeiro, instale o NGINX se você ainda não o tiver, executando este comando:
sudo apt-get install nginx
Em seguida, você precisará configurar o NGINX para encaminhar solicitações para o seu app 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 basta recarregar o NGINX para aplicar as mudanças:
sudo systemctl reload nginx
Passo 4: Testar a Configuração
Agora que tudo está configurado, prossiga e inicie o app 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 para o ramo
test
em seu repositório Bitbucket. Essa ação irá acionar o webhook.
-
Acionamento do webhook: O webhook enviará uma solicitação POST para seu servidor. O aplicativo Flask receberá essa solicitação, realizará um pull forçado do ramo
test
e atualizará o repositório local. -
Verificar o pull: Verifique a saída de log do seu aplicativo Flask ou inspecione o repositório local para verificar se 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 contra acesso não autorizado, violações de dados e ataques. Aqui estão as principais áreas 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 de servidor seguro:
-
Software minimal: Instale apenas 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 esteja atualizado com os últimos patches de segurança.
-
Configuração do firewall: Utilize 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 (Uncomplicated Firewall) no Ubuntu pode ser assim:
# 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
# Ativar 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.
-
Quaisquer portas ou serviços desnecessários devem ser bloqueados por padrão para limitar a exposição a ataques.
Regras Adicionais de 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 da faixa de IP do Bitbucket.
-
Negar todo o outro tráfego de entrada: Para qualquer serviço que não precise ser exposto à Internet (por exemplo, portas de banco de dados), certifique-se de que essas portas estejam bloqueadas.
2. Adicionar Autenticação ao App Flask
Uma vez que seu aplicativo Flask estará acessível publicamente via URL do webhook, você deve considerar adicionar autenticação para garantir que apenas usuários autorizados (como os servidores do Bitbucket) possam acionar o pull.
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 a verificação do 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 será 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 possam interceptar ou modificar os dados.
Por que HTTPS?
-
Criptografia de dados: HTTPS criptografa a comunicação, garantindo que dados sensíveis como seu token de autenticação não sejam expostos a ataques man-in-the-middle.
-
Confiança e integridade: HTTPS ajuda a garantir que os dados recebidos pelo seu servidor não tenham sido alterados.
Usando 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 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 está funcionando.
4. Registro e Monitoramento
Implemente registro e monitoramento para o seu aplicativo Flask para rastrear qualquer tentativa não autorizada, erros ou atividades incomuns:
-
Registrar solicitações: Registre todas as solicitações recebidas, incluindo o endereço IP, cabeçalhos da solicitação e status da resposta, para que você possa monitorar qualquer atividade suspeita.
-
Usar ferramentas de monitoramento: Configure ferramentas como Prometheus, Grafana, ou New Relic para monitorar o desempenho do servidor e a saúde do aplicativo.
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 conceitos básicos de Integração Contínua (CI) e 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 o 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 automaticamente o processo de implantação.
-
Criando um Listener de Webhook baseado em Flask: Mostramos como configurar um aplicativo Flask em seu servidor Linux para escutar as solicitações de webhook recebidas do Bitbucket. Esse aplicativo Flask recebe as notificações e executa os comandos Git necessários para puxar e implantar as últimas alterações.
-
Automatizando o Processo de Implantação: Usando Python e Flask, automatizamos o processo de puxar alterações do repositório 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 de forma segura.
-
Considerações de Segurança: Abordamos etapas críticas de segurança para proteger seu processo de implantação:
-
Regras de 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 proteger 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 ou erro incomum.
-
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
-
Estrategias 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 enquanto expande suas habilidades nessa área. Feliz 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/