DEV Community 👩‍💻👨‍💻

Cover image for [pt-BR] Consumindo conteúdo HTTP no Terraform
Plínio Balduino
Plínio Balduino

Posted on

[pt-BR] Consumindo conteúdo HTTP no Terraform

Parte de uma série de posts curtos com conhecimentos que podem ser úteis no dia a dia e quero compartilhar. Muitas vezes eles exigem um conhecimento prévio da ferramenta ou da linguagem.

Esses textos curtos são publicados sob a tag #quick.

Existem situações em que você precisa armazenar o conteúdo de um endpoint ou de um arquivo que está online, e esse conteúdo não será modificado dentro daquele contexto.

Por exemplo, trabalhei num projeto em que a geração de tokens JWT era feita pelo AWS Cognito. Para validar o token recebido pelo client e garantir que ele era legítimo, permitindo a liberação do acesso à API, é necessário verificar se o token foi gerado com a mesma chave do Cognito.

Para isso, todo User Pool do Cognito gera um documento público que pode ser consumido pelo seu código. Esse documento fica em https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json

Como o conteúdo desse documento nunca será alterado, é um desperdício fazer uma requisição HTTP para esse endereço toda vez que precisarmos validar um token. Como a validação precisa ser rápida e, no contexto de um recurso serverless, somos cobrados pelos tempo de uso, esse acesso extra causa um aumento desnecessário de custos.

Para resolver isso, a requisição HTTP é feita uma única vez, durante o build da aplicação, e esse valor é passado para o código como uma variável de ambiente.

Usando Terraform, bastou fazer assim:


# Aqui criamos o User Pool onde serão armazenadas 
# as credenciais dos usuários
resource "aws_cognito_user_pool" "exemplo" {
  name = "exemplo"

  # um monte de configurações
}

# Aqui armazenamos os dados da região AWS atual
data "aws_region" "current" {}

# E aqui fazemos a requisição HTTP, que terá os 
# parâmetros automaticamente atualizados se você
# mudar de região ou recriar seu User Pool
data "http" "cognito_jwks" {
  url = "https://cognito-idp.${data.aws_region.current.name}.amazonaws.com/${aws_cognito_user_pool.exemplo.id}/.well-known/jwks.json"

  request_headers = {
    Accept = "application/json"
  }
}

# Finalmente, exportamos o conteúdo da requisição 
# para que seja usada em outros módulos do seu projeto
output "cognito_jwks" {
  value = tostring(data.http.cognito_jwks.body)
}
Enter fullscreen mode Exit fullscreen mode

E, no módulo onde você definiu a Lambda, você faz assim:

# essa variável terá um valor atribuído
variable "cognito_jwks" {
  type = string
}

resource "aws_lambda_function" "exemplo" {
  environment {
    variables = {
      COGNITO_JWKS = var.cognito_jwks
    }
  }
Enter fullscreen mode Exit fullscreen mode

Isso funciona com qualquer outro recurso que você criar, não precisa ser necessariamente uma Lambda. COGNITO_JWKS contém um texto e você pode usá-lo da maneira que for melhor para o seu caso.

Ao gerar a Lambda, o conteúdo do arquivo estará disponível como uma variável de ambiente, podendo ser acessado no código com process.env.COGNITO_JWKS, caso você esteja usando JavaScript.

Variável de ambiente da AWS Lambda

Oldest comments (1)

Some comments have been hidden by the post's author - find out more

🌚 Life is too short to browse without dark mode