Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho)

Recentemente executei um projeto que me ajudou a revisitar conceitos importantes de CI/CD, containerização e infraestrutura como código.
Nesse post, vou compartilhar como foi a experiência, as tecnologias envolvidas, dificuldades encontradas e os apren…


This content originally appeared on DEV Community and was authored by Marcos Vilela

Recentemente executei um projeto que me ajudou a revisitar conceitos importantes de CI/CD, containerização e infraestrutura como código.
Nesse post, vou compartilhar como foi a experiência, as tecnologias envolvidas, dificuldades encontradas e os aprendizados que levei comigo. Esse post é muito mais sobre o que aprendi do que ferramentas para utilizar, exercitando então a capacidade de projetar, desenhar e integrar ferramentas e soluções modernas e entender como e quando o momento de utiliza-los.

O Projeto

A ideia era simples: criar uma API em Python com Flask que retorna frases motivacionais aleatórias, conteinerizá-la com Docker e configurá-la para ser implantada automaticamente usando GitHub Actions e Terraform em um provedor de nuvem.

O resultado final foi um pipeline que:

  1. Constrói a imagem Docker da aplicação.
  2. Faz o deploy automaticamente em um provedor de nuvem.
  3. Provisiona a infraestrutura via Terraform.

Tudo isso sendo disparado sempre que um commit é feito na branch main.

Tecnologias Utilizadas

  • Python + Flask – para criar a API.
  • Docker – para empacotar a aplicação e garantir portabilidade.
  • GitHub Actions – para criar o pipeline CI/CD.
  • Terraform – para gerenciar a infraestrutura como código.
  • Cloud – como provedor de hospedagem e deploy.

Estrutura Básica da API

O código da aplicação ficou simples, nesse exemplo abaixo suficiente para demonstrar a estrutura:

# app/advice.py
from flask import Flask, jsonify
import random

app = Flask(__name__)

frases = [
    "Acredite em você!",
    "Você é capaz de mais do que imagina.",
    "Persistência leva ao sucesso.",
    "Cada erro é uma oportunidade de aprendizado."
]

@app.route("/")
def home():
    return jsonify({"message": "Bem-vindo à API de Frases Motivacionais!"})

@app.route("/frase")
def frase():
    return jsonify({"frase": random.choice(frases)})

@app.errorhandler(404)
def not_found(error):
    return jsonify({"error": "Rota não encontrada"}), 404

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=80)

Dockerfile para Containerização

A imagem foi construída a partir de uma base Python e exposta na porta 80:

FROM python:3.10-slim

WORKDIR /app

COPY app/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app/ .

EXPOSE 80

CMD ["python", "advice.py"]

Para testar localmente:

docker build -t api-advice .
docker run -p 80:80 api-advice

Workflow do GitHub Actions

O workflow foi configurado para rodar na branch main e fluxos separados para executar build, teste e deploy:

name: CI Pipeline

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Build da imagem Docker
        run: docker build -t test-image:latest .

      - name: Rodar testes dentro do container
        run: |
          docker run --rm -d -p 80:80 --name test-container test-image:latest
          sleep 5
          curl -f http://localhost/ || exit 1
          curl -f http://localhost/frase || exit 1
          curl -s -o /dev/null -w "%{http_code}" http://localhost/inexistente | grep -q "404" && echo "404 OK" || exit 1
          docker stop test-container

      - name: Testes passaram ✅
        run: echo "Todos os testes passaram com sucesso!"

Action para infra

name: Provisionar Infraestrutura Render

on:
  push:
    branches: [infra]

jobs:
  terraform:
    runs-on: ubuntu-latest
    environment: render

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.12.2

      - name: Terraform Init
        working-directory: infra
        run: terraform init

      - name: Terraform Plan
        working-directory: infra
        env:
          TF_VAR_cloud_api_key: ${{ secrets.SECRET_API_KEY }}
          TF_VAR_cloud_owner_id: ${{ secrets.SECRET_OWNER_ID }}
        run: terraform plan -out=tfplan

      - name: Terraform Apply
        working-directory: infra
        env:
          TF_VAR_cloud_api_key: ${{ secrets.SECRET_API_KEY }}
          TF_VAR_cloud_owner_id: ${{ secrets.SECRET_OWNER_ID }}
        run: terraform apply -auto-approve

Código Terraform para o Cloud

No diretório infra/, configurei os recursos para o respectivo provedor:

terraform {
  required_providers {
    Cloud = {
      source  = "Seu-Provedor-Cloud-os/Cloud"
      version = "~> 0.2"
    }
  }
}

provider "Cloud" {
  api_key = var.Cloud_api_key
}

resource "Cloud_service" "api" {
  name    = "api-advice"
  type    = "web_service"
  plan    = "starter"
  env     = "docker"
  branch  = "main"
  repo    = "https://github.com/seu-usuario/seu-repo"
}

Principais Aprendizados

1. Containerização com Docker

Revisitei a criação de uma imagem Docker para uma aplicação Flask, expondo a porta 80 e configurando corretamente o CMD para inicializar o servidor.
Também testei chamadas à API com curl para validar o funcionamento dentro do container.

2. Automação com GitHub Actions

Configurei um workflow que:

  • Faz build da imagem Docker.
  • Publica a aplicação automaticamente em um provedor de nuvem.
  • Provisiona infraestrutura com Terraform.

3. Infraestrutura como Código com Terraform

Reforcei conceitos de organização de arquivos (main.tf, variables.tf, outputs.tf, terraform.tfvars) e boas práticas no uso de variáveis e outputs.

4. Estrutura de Projeto

Manter a separação entre código da aplicação e código de infraestrutura facilitou bastante a manutenção.

Dificuldades Encontradas

  • Revisão do Terraform: fazia algum tempo que não trabalhava com Terraform, então precisei revisar a documentação oficial para relembrar a sintaxe correta de módulos e garantir compatibilidade com as versões atuais.
  • Aprendendo sobre o provedor: como não conhecia o provedor definido para esse projeto, levei um tempo extra para entender como ele realiza implantações automáticas a partir de commits na branch main.

Ferramentas de Apoio

Durante o desenvolvimento, utilizei algumas ferramentas de IA que ajudaram a acelerar a curva de aprendizado:

  • ChatGPT (OpenAI): para esclarecer dúvidas e sugerir soluções.
  • GitHub Copilot: para agilizar a escrita de código e arquivos de configuração.
  • Claude Sonnet 3.7 (Anthropic): para revisar e sugerir melhorias na organização do projeto.

Conclusão

Esse projeto foi mais do que criar uma API simples — foi um exercício prático de integração entre desenvolvimento, automação e infraestrutura.
Revisitei conceitos importantes e aprendi novos fluxos de trabalho com ferramentas modernas como o Render.

Se você está começando com CI/CD, recomendo fortemente criar um projeto do zero, integrando Docker, Terraform e um pipeline de deploy automatizado.
A experiência prática é insubstituível.

Separação dos Pipelines

Foram criados dois workflows separados:

  • Pipeline CI (ci.yml): responsável por buildar a imagem Docker e rodar testes automatizados simples (incluindo verificação de rotas e status HTTP). O deploy no Render é acionado automaticamente via integração do próprio Render com o GitHub assim que há um push na branch main.
  • Pipeline de Infraestrutura (infra.yml): dedicado ao provisionamento da infraestrutura via Terraform, disparado por pushes na branch infra.

Essa separação garante maior organização, facilita troubleshooting e permite evoluir cada parte do processo de forma independente.

Observação: O pipeline de infraestrutura foi configurado para provisionar recursos em um provedor de cloud. No projeto original, foi utilizado o Render, mas o fluxo pode ser adaptado para outros provedores conforme necessidade.


This content originally appeared on DEV Community and was authored by Marcos Vilela


Print Share Comment Cite Upload Translate Updates
APA

Marcos Vilela | Sciencx (2025-09-02T19:20:32+00:00) Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho). Retrieved from https://www.scien.cx/2025/09/02/como-construi-um-pipeline-ci-cd-com-github-actions-docker-e-terraform-e-o-que-aprendi-no-caminho/

MLA
" » Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho)." Marcos Vilela | Sciencx - Tuesday September 2, 2025, https://www.scien.cx/2025/09/02/como-construi-um-pipeline-ci-cd-com-github-actions-docker-e-terraform-e-o-que-aprendi-no-caminho/
HARVARD
Marcos Vilela | Sciencx Tuesday September 2, 2025 » Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho)., viewed ,<https://www.scien.cx/2025/09/02/como-construi-um-pipeline-ci-cd-com-github-actions-docker-e-terraform-e-o-que-aprendi-no-caminho/>
VANCOUVER
Marcos Vilela | Sciencx - » Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho). [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/02/como-construi-um-pipeline-ci-cd-com-github-actions-docker-e-terraform-e-o-que-aprendi-no-caminho/
CHICAGO
" » Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho)." Marcos Vilela | Sciencx - Accessed . https://www.scien.cx/2025/09/02/como-construi-um-pipeline-ci-cd-com-github-actions-docker-e-terraform-e-o-que-aprendi-no-caminho/
IEEE
" » Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho)." Marcos Vilela | Sciencx [Online]. Available: https://www.scien.cx/2025/09/02/como-construi-um-pipeline-ci-cd-com-github-actions-docker-e-terraform-e-o-que-aprendi-no-caminho/. [Accessed: ]
rf:citation
» Como construí um pipeline CI/CD com GitHub Actions, Docker e Terraform (e o que aprendi no caminho) | Marcos Vilela | Sciencx | https://www.scien.cx/2025/09/02/como-construi-um-pipeline-ci-cd-com-github-actions-docker-e-terraform-e-o-que-aprendi-no-caminho/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.