Table of Contents
A computação sem servidor transformou a forma como as equipes constroem e implementam aplicativos, oferecendo escalabilidade, preços por uso e custos operacionais reduzidos. No entanto, executar aplicativos sem servidor na produção envolve muito mais do que escrever código de função. Você precisa fornecer e gerenciar dezenas de recursos em nuvem – gateways API, filas de espera, bases de dados, funções IAM, configurações de registro e componentes de rede – todos eles devem ser replicados de forma consistente em ambientes de desenvolvimento, estadia e produção. Click-ops manuais no console rapidamente se torna propensa a erros e inescaláveis. Ferramentas de infraestrutura como o Código (IaC) como ferramentas Terraform enfrentam esse desafio, permitindo que você defina cada peça de infraestrutura em arquivos de configuração controlados por versão e legíveis por humanos. Este artigo explora como usar Terraform para automatizar a implantação de infraestrutura para aplicações sem servidor, fornecendo exemplos concretos, melhores práticas e estratégias para gerenciar complexidades do mundo real.
O que é o Terraform?
Terraform é uma ferramenta de IAC de código aberto criada pela HashiCorp que permite que você provisione e gerencie infraestrutura em vários provedores de nuvem usando uma linguagem de configuração declarativa conhecida como HCL (HashiCorp Configuration Language). Em vez de escrever scripts imperativos que executam comandos passo a passo, você declara o estado desejado de sua infraestrutura – quais recursos você deseja, suas propriedades e como eles se relacionam uns com os outros – e Terraform determina as ações necessárias para alcançar esse estado.
No centro da Terraform está o plano de execução. Antes de fazer quaisquer alterações, a Terraform compara a sua configuração com o estado actual da infra- estrutura e produz um plano detalhado do que será criado, actualizado ou destruído. Este plano pode ser revisto (e, em gasodutos CI/CD, aprovado) antes de ser aplicado, dando- lhe uma linha de feedback segura que previne alterações não intencionais. A Terraform também rastreia os recursos num ficheiro de estado, que mapeia a configuração dos objectos de nuvem do mundo real. Este ficheiro de estado é essencial para a Terraform saber o que está a gerir e detectar a deriva.
A Terraform suporta centenas de provedores, incluindo todas as principais plataformas de nuvem (AWS, Azure, Google Cloud), bem como serviços SaaS como Cloudflare, Datadog e GitHub. Para aplicativos sem servidor em AWS, você normalmente usará o provedor AWS para definir funções Lambda, API Gateway REST APIs, tabelas DynamoDB, filas SQS, streams de usuários Kinesis, conjuntos Cognito e todas as políticas IAM que os unem.
Por que aplicativos sem servidor precisam de infraestrutura como código
As aplicações sem servidor consistem em muitos serviços pequenos e concebidos para fins que comunicam assíncronas ou síncronas. Uma arquitectura típica orientada para eventos pode incluir uma API Gateway que recebe solicitações HTTP, uma função Lambda para processá-las, uma tabela DynamoDB para armazenar resultados e uma fila SQS para fazer um buffer para uma segunda função Lambda. Criar estes recursos manualmente é tedioso e propensa a erros, especialmente à medida que a sua arquitectura cresce para incluir dezenas de funções e serviços auxiliares. Os desafios da gestão manual incluem:
- Inconsistência: Diferentes ambientes (dev, encenação, prod) inevitavelmente se separam quando criados manualmente.
- Sem histórico de versão: Quem mudou a capacidade de leitura do DynamoDB? Quando? Por quê? Sem código, você perde a auditabilidade.
- Pesadelo de recreação: Após um desastre, você precisaria reconfigurar tudo do zero, esperando que você se lembrasse de cada cenário.
- ]Desperdicio de tempo: Clicar no console para cada recurso consome horas que devem entrar na lógica da aplicação.
O IAC resolve esses problemas transformando infraestrutura em software. Cada alteração é uma solicitação de pull. Cada ambiente é uma implantação repetitiva. E toda a sua arquitetura pode ser demolida e reconstruída em minutos. Para aplicativos sem servidor, onde a proposta de valor é velocidade e agilidade, o IAC não é opcional – é a base de um fluxo de trabalho de produção confiável.
Principais benefícios de usar Terraform para servidor sem
Embora qualquer ferramenta IAC possa ser usada para gerenciar infraestrutura sem servidor, Terraform oferece vantagens distintas que se alinham bem com as necessidades de equipes sem servidor.
Automação de ciclo de vida completo
O Terraform lida não apenas com o provisionamento, mas também com a actualização e destruição dos recursos. Quando você precisa alterar o tamanho de memória de uma função Lambda ou o atributo TTL de uma tabela DynamoDB, você simplesmente atualiza a configuração e executa . Quando você terminar com um recurso, o mesmo código que o criou irá limpar. Isto é especialmente valioso em ambientes efêmeros, como implantações de antevisão para cada requisição de arranque, onde você pode rodar uma pilha completa sem servidor e depois destruí- la automaticamente.
Gestão da Dependência Declarativa
As arquitecturas sem servidor têm dependências complexas. Uma função Lambda depende de uma função IAM, que pode depender de uma política, que pode depender de uma tabela DynamoDB ARN. O Terraform constrói um gráfico de recursos a partir das suas declarações e determina automaticamente a ordem correta das operações. Cria recursos antes de serem referenciados e espera que as dependências se tornem disponíveis. Isto liberta- o de escrever programas propensas a erros que sequenciam comandos manualmente.
Consistência Multiambiental
Usando espaços de trabalho ou estruturas de diretórios Terraform, você pode reutilizar a mesma configuração em vários ambientes com diferentes valores variáveis. A configuração de uma função Lambda pode ser idêntica em dev, estadiamento e produção, exceto para variáveis específicas do ambiente, como nomes de tabelas, níveis de log ou configurações de VPC. Isso garante que a infraestrutura de produção é exatamente o que foi testado no estadiamento.
Controlo do Estado Granular
A gestão do estado é uma preocupação crítica. Terraform permite armazenar o estado remotamente em backends como S3 (com bloqueio DynamoDB), Terraform Cloud ou HashiCorp Consul. Estado remoto permite a colaboração da equipe: vários engenheiros podem aplicar com segurança mudanças na mesma infraestrutura sem conflito. Para equipes sem servidor que implementam continuamente, o gerenciamento robusto do estado é essencial.
Começando com Terraform para implantação sem servidor
Vamos passar por uma configuração completa de uma aplicação sem servidor usando Terraform no AWS. Nosso exemplo irá expor uma API REST simples via API Gateway que ativa uma função Lambda, que escreve dados para uma tabela DynamoDB. Nós também cobriremos as permissões IAM necessárias.
Pré-requisitos
- Terraform instalado (download)
- Conta AWS com credenciais configuradas (via variáveis de ambiente ou )
- Node.js instalado (para compilar o código Lambda)
Estrutura do Projeto
serverless-terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── lambda/
│ └── index.js
└── terraform.tfvars
1. Defina o fornecedor de terraforma
Em , configure o provedor AWS e especifique a região:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "serverless-app/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
}
}
provider "aws" {
region = var.aws_region
}
2. Criar papel IAM para Lambda
data "aws_iam_policy_document" "lambda_assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role" "lambda_exec" {
name = "serverless-lambda-role"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role.json
}
resource "aws_iam_policy" "lambda_dynamodb_policy" {
name = "lambda-dynamodb-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:UpdateItem"]
Effect = "Allow"
Resource = aws_dynamodb_table.items.arn
},
{
Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"]
Effect = "Allow"
Resource = "*"
}
]
})
}
resource "aws_iam_role_policy_attachment" "lambda_policy_attach" {
role = aws_iam_role.lambda_exec.name
policy_arn = aws_iam_policy.lambda_dynamodb_policy.arn
}
3. Implantar a tabela DynamoDB
resource "aws_dynamodb_table" "items" {
name = "items"
billing_mode = "PAY_PER_REQUEST"
hash_key = "id"
attribute {
name = "id"
type = "S"
}
tags = {
Environment = var.environment
}
}
4. Pacote e Implantar a função Lambda
Primeiro, crie uma função Lambda simples em :
exports.handler = async (event) => {
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const id = event.pathParameters.id;
const params = {
TableName: process.env.TABLE_NAME,
Item: { id, timestamp: Date.now(), data: event.body }
};
await dynamodb.put(params).promise();
return {
statusCode: 200,
body: JSON.stringify({ id })
};
};
Em seguida, na configuração do Terraform, consulte o código de função:
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "${path.module}/lambda"
output_path = "${path.module}/lambda_function_payload.zip"
}
resource "aws_lambda_function" "api_handler" {
filename = data.archive_file.lambda_zip.output_path
function_name = "serverless-api-handler"
role = aws_iam_role.lambda_exec.arn
handler = "index.handler"
runtime = "nodejs18.x"
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
environment {
variables = {
TABLE_NAME = aws_dynamodb_table.items.name
}
}
}
5. Expor o Lambda através do API Gateway
resource "aws_api_gateway_rest_api" "api" {
name = "serverless-api"
}
resource "aws_api_gateway_resource" "items" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_rest_api.api.root_resource_id
path_part = "items"
}
resource "aws_api_gateway_resource" "item" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_resource.items.id
path_part = "{id}"
}
resource "aws_api_gateway_method" "put_item" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.item.id
http_method = "PUT"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "lambda" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.item.id
http_method = aws_api_gateway_method.put_item.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.api_handler.invoke_arn
}
resource "aws_lambda_permission" "apigw" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.api_handler.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.api.execution_arn}/*/*"
}
resource "aws_api_gateway_deployment" "prod" {
depends_on = [aws_api_gateway_integration.lambda]
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = "prod"
}
6. Defina saídas
Em , expor o ponto final da API:
output "api_endpoint" {
value = "${aws_api_gateway_deployment.prod.invoke_url}/items/"
}
7. Aplicar
terraform init
terraform plan
terraform apply
Depois de aplicar, você pode emitir uma solicitação PUT para o endpoint com um corpo JSON. A função Lambda escreve os dados para DynamoDB. Para derrubar toda a pilha, execute .
Estruturando projetos Terraform para Servidores
As aplicações sem servidor do mundo real são demasiado grandes para um único ficheiro de configuração. A adopção de uma estrutura de projecto escalável é crítica. Aqui estão os padrões comuns:
Usar módulos para Encapsular Componentes Reutilizáveis
Os módulos Terraform permitem agrupar recursos em unidades lógicas. Para serverless, você pode criar módulos para:
- Um módulo de função Lambda base (com função IAM, permissões básicas do CloudWatch e configuração opcional do VPC)
- Um Gateway API + módulo de integração Lambda
- Um módulo de tabela DynamoDB com atributos padronizados e autoescalamento
- Um módulo de fila SQS com filas de letras mortas
Os módulos podem ser armazenados no seu próprio repositório Git ou publicados no Terraform Registry. Eles simplificam configurações específicas do ambiente: você instancia um módulo com variáveis diferentes por ambiente.
Ambientes separados com Directórios ou Espaços de Trabalho
Existem duas abordagens comuns para gerir ambientes:
- Directório por ambiente: Criar pastas como , , , cada uma com as suas próprias e possivelmente uma . Isto isola ficheiros de estado e evita alterações acidentais no ambiente transverso.
- Terraform Workspaces: Use o recurso de espaço de trabalho incorporado para criar instâncias nomeadas da mesma configuração. Os espaços de trabalho são mais leves, mas podem tornar-se confusos quando lidam com várias equipes.
Para a maioria das equipes sem servidor, a abordagem de diretório é mais clara porque torna os limites de ambiente explícitos na base de código.
Estado remoto com bloqueio
Nunca guarde o estado localmente para projetos de equipe. Use uma infraestrutura S3 com o bloqueio do DynamoDB. O balde S3 mantém o arquivo de estado, e o DynamoDB fornece bloqueios de consistência para que apenas um seja executado de uma vez. A configuração da infraestrutura de exemplo foi mostrada anteriormente. Certifique-se de que a tabela S3 bucket e DynamoDB são criados fora do Terraform (bootstrap-los com um script separado ou use o gerenciamento de estado incorporado do Terraform Cloud).
Gerenciar Segredos Seguramente
Aplicações sem servidor geralmente requerem segredos como senhas de banco de dados, chaves API ou tokens de assinatura JWT. Nunca codifice estes em configurações Terraform. Em vez disso, use:
- Gestor de Segredos AWS ou SSM Parâmetro Store, referenciado através de ou fontes de dados
- Fornecedor de cofres para obter segredos dinâmicos
- Arquivos variáveis criptografados específicos do ambiente (por exemplo, ]] com ferramentas como )
Melhores práticas para automatizar a infraestrutura com Terraform
Para maximizar a confiabilidade e a velocidade da equipe, siga essas práticas comprovadas:
Controle de Versão Tudo
Todas as configurações do Terraform, incluindo módulos, devem ser armazenadas no Git com mensagens de commit significativas. As versões de etiquetas e o uso de branches para alterações. Isto fornece uma trilha completa de auditoria de quem mudou o que e quando.
Executar sempre plano e revisão
No desenvolvimento local, sempre execute antes . Em CI/CD, requer uma etapa de aprovação manual para implantações de produção. Terraform Cloud e Atlantis são ferramentas populares que integram fluxos de trabalho de plano/aplicação em solicitações de pull.
Implementar o IC/CD para Infraestrutura
Tratar mudanças de infraestrutura como mudanças de código. Use um pipeline que executa e em requisições de pull, então executa e -- após a mesclagem - executa . Para serverless, você pode executar testes de integração após o aplicativo para verificar se os endpoints da API respondem corretamente.
Usar para detecção de deriva
Mesmo com o CI/CD, alguém pode modificar manualmente um recurso através do console. Agendar as operações regulares (por exemplo, noturnamente) para detectar deriva e alertar a equipe. Ferramentas como a detecção de deriva da Terraform Cloud podem automatizar isso.
Teste suas configurações de terraforma
O código de infraestrutura de teste unitário é possível com ferramentas como Terratest, uma biblioteca Go que gira recursos reais na nuvem, verifica seu comportamento e os derruba. Para serverless, você pode implantar pilhas em contas de teste isoladas, executar testes HTTP contra a API e validar conteúdo do DynamoDB. Enquanto escrever testes Terratest é um investimento, ele captura erros de configuração sutis precocemente.
Usar a Política como Código
Defina regras de conformidade em toda a organização usando o Sentinel HashiCorp (Cloud) ou Open Policy Agent. Por exemplo, exija que todas as funções Lambda tenham o rastreamento de raios X ativado, ou impeça as tabelas públicas do DynamoDB. Estas políticas são aplicadas no momento do plano, tornando a segurança e a governança de custos sistemáticas.
Desafios e soluções comuns
Bloqueamento e Conflitos de Ficheiros de Estado
Quando vários membros da equipe rodam simultaneamente, pode ocorrer corrupção de estado. Solução: sempre use uma infraestrutura que suporta o bloqueio (S3 + DynamoDB) e nunca execute diretamente de ramos paralelos. Use pipelines CI/CD para serializar se aplica.
Manuseando grandes números de funções Lambda
Gerenciar funções 50+ Lambda em uma única configuração torna-se descomplicado. Solução: use ou com um mapa de definições de funções. Melhor ainda, organize funções em configurações de Terraform separadas que compartilham fontes de dados de estado. Por exemplo, uma configuração central “core” exporta saídas (nomes de tabelas DynamoDB, URLs de fila SQS) que as configurações de funções a jusante importam via .
Dependência Ordenação em Arquiteturas Complexas
Embora Terraform lide com a maioria das dependências automaticamente, dependências circulares (por exemplo, dois serviços que se referem aos ARNs do outro) podem causar problemas. Solução: quebrar o ciclo introduzindo um terceiro recurso (como um tópico central SNS) ou usar blocos explícitos . Para serverless, um padrão comum é criar funções e políticas IAM separadamente de funções para evitar ciclos.
A implementar alterações de código Lambda
O Terraform é projetado para infraestrutura, não para implantação contínua de código de aplicação. A aplicação de novas versões da Lambda por meio da reaplicação do Terraform é lenta e não é ideal para iterações rápidas de código. Solução: separa a implantação da infraestrutura (criada uma vez por ambiente) da implantação do código. Use pipelines CI/CD que atualizem o código de função da Lambda através do AWS SDK ou ferramentas como o Serverless Framework, enquanto o Terraform gerencia os recursos circundantes. Alternativamente, use a fonte de dados com uma fonte consistente hash para que apenas as alterações no arquivo de código desencadeie uma nova implantação.
Conclusão
A implantação de infraestrutura automatizada com Terraform traz o mesmo rigor para a infraestrutura sem servidor que as equipes de software aplicam ao código de aplicação. Ao definir cada recurso em arquivos HCL controlados por versão, você ganha implementações repetitivas, gerenciamento de mudanças seguras e trilhas de auditoria completas. Um projeto Terraform bem estruturado com módulos, estado remoto e integração CI/CD permite que as equipes gerem centenas de funções Lambda, endpoints de API e armazenamento de dados sem perder tempo em provisionamento manual ou se preocupar com a deriva do ambiente.
À medida que as arquiteturas sem servidor continuam a crescer em complexidade, com fluxos de trabalho orientados por eventos, funções de passo e infraestrutura global espalhadas por várias regiões, a importância do IC robusto só aumenta.A partir dos padrões e exemplos deste artigo, você pode construir uma base que dimensione com sua aplicação e sua organização.O investimento inicial em automatizar sua infraestrutura sem servidor se paga muitas vezes em erros reduzidos, implementações mais rápidas e confiança maior de que seu ambiente de produção corresponde ao que você testou.