kb.erickguedes.com
Terraform: Infraestrutura como Código

Terraform com Múltiplos Provedores

Aula 5 de 7

Múltiplos Provedores

Terraform gerencia não apenas AWS, mas Azure, GCP, Kubernetes, Cloudflare, Datadog, GitHub e centenas de outros provedores.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.0"
    }
    github = {
      source  = "integrations/github"
      version = "~> 6.0"
    }
  }
}

Múltiplas Contas/Regiões AWS

# Provider alias para múltiplas regiões
provider "aws" {
  region = "us-east-1"
  alias  = "virginia"
}

provider "aws" {
  region = "sa-east-1"
  alias  = "sao_paulo"
}

# Recurso na conta us-east-1
resource "aws_s3_bucket" "us" {
  provider = aws.virginia
  bucket   = "bucket-us"
}

# Recurso na conta sa-east-1
resource "aws_s3_bucket" "br" {
  provider = aws.sao_paulo
  bucket   = "bucket-br"
}

Assume Role (multi-conta)

provider "aws" {
  alias = "prod"

  assume_role {
    role_arn     = "arn:aws:iam::123456789012:role/TerraformRole"
    session_name = "TerraformSession"
    external_id  = "EXTERNAL_ID"
  }
}

provider "aws" {
  alias = "dev"

  assume_role {
    role_arn = "arn:aws:iam::234567890123:role/TerraformRole"
  }
}

Kubernetes + Helm

# Provedor Kubernetes (usa kubeconfig local)
provider "kubernetes" {
  config_path = "~/.kube/config"
}

# Provedor Helm
provider "helm" {
  kubernetes {
    config_path = "~/.kube/config"
  }
}

resource "kubernetes_namespace" "app" {
  metadata {
    name = "app-prod"
  }
}

resource "helm_release" "nginx" {
  name       = "nginx-ingress"
  repository = "https://kubernetes.github.io/ingress-nginx"
  chart      = "ingress-nginx"
  namespace  = kubernetes_namespace.app.metadata[0].name

  set {
    name  = "controller.replicaCount"
    value = 3
  }
}

GitHub + AWS

# Criar repositório + IAM Role para CI/CD
provider "github" {
  token = var.github_token  # ou GITHUB_TOKEN env var
  owner = "minha-org"
}

resource "github_repository" "app" {
  name        = "meu-app"
  description = "Aplicação principal"
  visibility  = "private"

  template {
    owner      = "minha-org"
    repository = "template-node"
  }
}

resource "aws_iam_openid_connect_provider" "github" {
  url = "https://token.actions.githubusercontent.com"
  client_id_list = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.github.certificates[0].sha1_fingerprint]
}

resource "aws_iam_role" "github_actions" {
  name = "github-actions-role"
  assume_role_policy = data.aws_iam_policy_document.github_actions_trust.json
}

data "aws_iam_policy_document" "github_actions_trust" {
  statement {
    effect = "Allow"
    principals {
      type        = "Federated"
      identifiers = [aws_iam_openid_connect_provider.github.arn]
    }
    condition {
      test     = "StringLike"
      variable = "token.actions.githubusercontent.com:sub"
      values   = ["repo:minha-org/${github_repository.app.name}:*"]
    }
  }
}

Cloudflare — DNS

provider "cloudflare" {
  api_token = var.cloudflare_api_token
}

variable "cloudflare_zone_id" {
  type = string
}

resource "cloudflare_record" "app" {
  zone_id = var.cloudflare_zone_id
  name    = "app"
  type    = "A"
  value   = aws_lb.app.dns_name
  proxied = true  # Cloudflare proxy (CDN + WAF)
}

# Terraform também gerencia Cloudflare Workers
resource "cloudflare_worker_script" "api" {
  name    = "api-worker"
  content = file("worker.js")
}

Multi-provider é onde Terraform brilha — uma única ferramenta para gerenciar cloud, k8s, DNS, CI/CD e monitoria. Use provider aliases para multi-região e assume_role para multi-conta.