Pular para o conteúdo
Cursor AI

Do código ao cluster: IaC avançado com Terraform e GitOps

Admin4 min de leitura
Do código ao cluster: IaC avançado com Terraform e GitOps

Do código ao cluster: IaC avançado com Terraform e GitOps

“A maior vantagem da infraestrutura como código é a capacidade de tratar ambientes de produção como software: versionamento, revisão e automação.” – Adaptado de práticas modernas de DevOps.

Tecnologia e Inovação

Introdução

Nos últimos anos, a entrega de software evoluiu de um processo manual e propenso a erros para um fluxo totalmente automatizado, onde infraestrutura e aplicação são tratadas como um único artefato. Essa mudança é impulsionada por três pilares:

  • Infraestrutura como Código (IaC) – Definições declarativas que podem ser versionadas.
  • GitOps – O repositório Git passa a ser a fonte única de verdade para o estado do cluster.
  • CI/CD – Integração e entrega contínua garantem que mudanças sejam testadas e aplicadas rapidamente.
  • Neste artigo, vamos montar um cenário completo: provisionar recursos na nuvem com Terraform, criar um cluster Kubernetes, e usar GitHub Actions (ou outra ferramenta de CI) para aplicar mudanças via GitOps. Tudo isso sem mencionar ferramentas que já foram abordadas em outros posts.

    Objetivo: ao final, você será capaz de criar um pipeline que, ao receber um pull request, valida o código IaC, executa testes de segurança e, se aprovado, sincroniza o estado desejado com o cluster.


    1. Preparando o ambiente de IaC com Terraform

    1.1 Estrutura de diretórios

    infra/
    

    ├─ modules/ │ └─ k8s-cluster/ │ ├─ main.tf │ ├─ variables.tf │ └─ outputs.tf ├─ environments/ │ ├─ dev/ │ │ ├─ main.tf │ │ └─ terraform.tfvars │ └─ prod/ │ ├─ main.tf │ └─ terraform.tfvars └─ provider.tf

    • modules/ – código reutilizável (ex.: criação de VPC, sub‑redes, nós do cluster).
    • environments/ – configurações específicas de cada estágio (dev, prod).
    • provider.tf – definição do provedor de nuvem (ex.: AWS, Azure, GCP).

    1.2 Exemplo de módulo k8s-cluster

    # modules/k8s-cluster/main.tf
    

    resource "aws_eks_cluster" "this" { name = var.cluster_name role_arn = var.cluster_role_arn

    vpc_config { subnet_ids = var.subnet_ids }

    tags = { Environment = var.environment } }

    # modules/k8s-cluster/variables.tf
    

    variable "cluster_name" { type = string } variable "cluster_role_arn" { type = string } variable "subnet_ids" { type = list(string) } variable "environment" { type = string }

    # modules/k8s-cluster/outputs.tf
    

    output "cluster_endpoint" { value = aws_eks_cluster.this.endpoint } output "cluster_certificate_authority_data" { value = aws_eks_cluster.this.certificate_authority[0].data }

    1.3 Consumo do módulo em dev

    # environments/dev/main.tf
    

    module "k8s_cluster" { source = "../../modules/k8s-cluster" cluster_name = "myapp-dev" cluster_role_arn = aws_iam_role.eks_role.arn subnet_ids = data.aws_subnets.private.ids environment = "dev" }

    Dica: Use o comando terraform fmt para garantir formatação padrão e terraform validate para detectar erros antes de aplicar.


    2. GitOps: declarando o estado desejado no repositório

    2.1 Estrutura de diretórios para o cluster

    gitops/
    

    ├─ base/ │ ├─ namespace.yaml │ ├─ ingress-controller.yaml │ └─ storage-class.yaml └─ overlays/ ├─ dev/ │ ├─ kustomization.yaml │ └─ app-config.yaml └─ prod/ ├─ kustomization.yaml └─ app-config.yaml

    • base/ – recursos comuns a todos os ambientes.
    • overlays/ – variações específicas (ex.: réplicas, limites de recursos).

    2.2 Exemplo de kustomization.yaml para dev

    # gitops/overlays/dev/kustomization.yaml
    

    resources: - ../../base patchesStrategicMerge: - app-config.yaml commonLabels: env: dev

    2.3 Manifesto de aplicação (ex.: API em Node.js)

    # gitops/base/app-deployment.yaml
    

    apiVersion: apps/v1 kind: Deployment metadata: name: api-service labels: app: api spec: replicas: 2 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: api image: ghcr.io/empresa/api:{{IMAGE_TAG}} ports: - containerPort: 8080 env: - name: NODE_ENV value: production

    Observação: O placeholder {{IMAGE_TAG}} será substituído pelo pipeline de CI/CD com a tag da imagem recém‑construída.


    3. CI/CD – Automatizando build, teste e sincronização

    3.1 Workflow GitHub Actions (arquivo .github/workflows/ci-cd.yml)

    ```yaml name: CI/CD – IaC & GitOps

    on: push: branches: [ main ] pull_request: types: [ opened, synchronize, reopened ]

    jobs: lint-terraform: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: "1.6.0" - name: Terraform fmt run: terraform fmt -check -recursive - name: Terraform validate run: terraform validate

    test-k8s-manifests: runs-on: ubuntu-latest needs: lint-terraform steps: - uses: actions/checkout@v3 - name: Install kustomize run: | curl -sLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.0.0/kustomize_v5.0.0_linux_amd64.tar.gz tar -xzf kustomize_v5.0.0_linux_amd64.tar.gz kustomize sudo mv kustomize /usr/local/bin/ - name: Render manifests (dev) run: | kustomize build gitops/overlays/dev > rendered-dev.yaml - name: Validate YAML uses: actionshub/kubeval@v2 with: files: rendered-dev.yaml

    build-and-push-image: runs-on: ubuntu-latest needs: test-k8s-manifests steps: - uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Buildx uses: docker/setup-buildx-action@v2 - name: Login to GHCR uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build & push id: image uses: docker/build-push-action@v4 with: context: . push: true tags: ghcr.io/empresa/api:${{ github.sha }}

    sync-gitops: runs-on: ubuntu-latest needs: build-and-push-image if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v3 - name: Update image tag run: | sed -i "s/{{IMAGE_TAG}}/${{ github.sha }}/g" gitops/overlays/prod/app-deployment.yaml git config user.name "github-actions" git config user.email "actions@github.com" git add gitops/overlays/prod/app-deployment.yaml git commit -m "

    Artigos relacionados