Pular para o conteúdo
Automação

Infraestrutura como Código: Do Docker ao Terraform em Pipelines CI/CD

Admin5 min de leitura
Infraestrutura como Código: Do Docker ao Terraform em Pipelines CI/CD

Infraestrutura como Código: Do Docker ao Terraform em Pipelines CI/CD

Tecnologia e Inovação

Introdução

A transformação digital das empresas depende cada vez mais da capacidade de entregar software rapidamente, com qualidade e segurança. Nesse cenário, a prática de Infraestrutura como Código (IaC) tornou‑se a espinha dorsal das organizações que buscam automação, reproducibilidade e governança.

Ao combinar Docker, Kubernetes, Terraform e GitHub Actions, é possível criar pipelines de CI/CD que:

Provisionam a infraestrutura de forma declarativa; Empacotam aplicações em containers consistentes; Orquestram serviços em clusters escaláveis; Entregam mudanças automaticamente em ambientes de teste e produção.

Este artigo apresenta, passo a passo, como montar essa cadeia completa, com exemplos reais de código, boas práticas e dicas de segurança. Ao final, você será capaz de reproduzir todo o fluxo em seu próprio projeto.


1. Containerização com Docker e Docker Compose

Por que Docker?

Isolamento: Cada serviço roda em seu próprio container, eliminando conflitos de dependência. Portabilidade: A mesma imagem funciona em laptops, servidores on‑premise ou nuvem. Velocidade: Builds incrementais reduzem o tempo de feedback nos testes.

Dockerfile básico

# Dockerfile

FROM python:3.11-slim

Variáveis de ambiente

ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1

Instala dependências do sistema

RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential gcc && \ rm -rf /var/lib/apt/lists/

Diretório de trabalho

WORKDIR /app

Copia requisitos e instala

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

Copia código da aplicação

COPY . .

Porta que a aplicação escuta

EXPOSE 8000

Comando padrão

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Dica: Use a flag --no-cache-dir para evitar camadas desnecessárias e reduzir o tamanho da imagem.

Docker Compose para ambiente de desenvolvimento

# docker-compose.yml

version: "3.9"

services: api: build: . ports: - "8000:8000" volumes: - .:/app environment: - ENV=development depends_on: - db

db: image: postgres:15-alpine environment: POSTGRES_USER: devuser POSTGRES_PASSWORD: devpass POSTGRES_DB: devdb volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432"

volumes: pgdata:

Com docker compose up --build, você tem a API FastAPI e o PostgreSQL rodando localmente, prontos para testes automatizados.


2. Orquestração com Kubernetes e Helm

Quando a aplicação precisa escalar ou ser executada em múltiplas zonas, o Kubernetes entra em cena. Ele gerencia containers em um cluster, provendo balanceamento, auto‑recuperação e atualizações sem downtime.

Manifesto de Deployment

# k8s/deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: api-deployment labels: app: api spec: replicas: 3 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: api image: ghcr.io/empresa/api:latest ports: - containerPort: 8000 env: - name: ENV value: "production" resources: limits: cpu: "500m" memory: "256Mi" requests: cpu: "250m" memory: "128Mi"

Service para exposição

# k8s/service.yaml

apiVersion: v1 kind: Service metadata: name: api-service spec: type: LoadBalancer selector: app: api ports: - protocol: TCP port: 80 targetPort: 8000

Helm Chart simplificado

Criar um Helm chart permite versionar a configuração do Kubernetes junto com o código da aplicação.

helm create api-chart

Estrutura resumida (api-chart/values.yaml):

replicaCount: 3

image: repository: ghcr.io/empresa/api pullPolicy: IfNotPresent tag: "latest"

service: type: LoadBalancer port: 80

resources: limits: cpu: 500m memory: 256Mi requests: cpu: 250m memory: 128Mi

Instalação:

helm upgrade --install api-release ./api-chart --namespace production

Prática recomendada: Mantenha o values.yaml fora do repositório (por exemplo, em um secret manager) e injete valores sensíveis via CI/CD.


3. Provisionamento Declarativo com Terraform

O Terraform permite descrever a infraestrutura (clusters, redes, bancos de dados) em arquivos .tf, garantindo que o estado seja versionado e auditável.

Provider e backend

# terraform/provider.tf

terraform { required_version = ">= 1.5.0" backend "s3" { bucket = "tf-state-empresa" key = "infra/prod/terraform.tfstate" region = "us-east-1" encrypt = true } }

provider "google" { project = var.project_id region = var.region }

Variáveis

# terraform/variables.tf

variable "project_id" { description = "ID do projeto GCP" type = string }

variable "region" { description = "Região onde os recursos serão criados" type = string default = "us-east1" }

Cluster GKE

# terraform/gke.tf

resource "google_container_cluster" "primary" { name = "prod-gke-cluster" location = var.region

initial_node_count = 3

node_config { machine_type = "e2-medium" oauth_scopes = [ "https://www.googleapis.com/auth/cloud-platform", ] labels = { environment = "production" } }

remove_default_node_pool = true

lifecycle { prevent_destroy = true } }

Saída de credenciais para o pipeline

# terraform/outputs.tf

output "kubeconfig" { description = "Kubeconfig para acesso ao cluster" value = google_container_cluster.primary.endpoint sensitive = true }

Fluxo típico:

terraform init

terraform plan -var="project_id=empresa-prod" -out=plan.out terraform apply "plan.out"

Os arquivos gerados (plan.out) podem ser consumidos por um job do GitHub Actions para atualizar o cluster automaticamente.


4. CI/CD Automatizado com GitHub Actions

O GitHub Actions oferece pipelines como código, permitindo que o fluxo de build, test e deploy seja armazenado no mesmo repositório da aplicação.

Workflow completo

```yaml

.github/workflows/ci-cd.yml

name: CI/CD Pipeline

on: push: branches: - main pull_request: branches: - main

env: REGISTRY: ghcr.io/empresa IMAGE_NAME: api TF_VERSION: 1.6.0

jobs: build-test: runs-on: ubuntu-latest steps: - name: Checkout código uses: actions/checkout@v4

- name: Configurar Python uses: actions/setup-python@v5 with: python-version: "3.11"

- name: Instalar dependências run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install pytest

- name: Executar testes unitários run: pytest -q

- name: Build da imagem Docker uses: docker/build-push-action@v5 with: context: . push: false tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

deploy: needs: build-test runs-on: ubuntu-latest environment: production permissions: contents: read id-token: write steps: - name: Checkout código uses: actions/checkout@v4

- name: Configurar Terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ env.TF_VERSION }}

- name: Autenticar no GCP uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_SA_KEY }}

- name: Inicializar Terraform run: terraform init -backend-config

Artigos relacionados