paint-brush
AWS LetsEncrypt Lambda ou por que escrevi um provedor TLS personalizado para AWS usando OpenTofu and Goby@kvendingoldo
441
441

AWS LetsEncrypt Lambda ou por que escrevi um provedor TLS personalizado para AWS usando OpenTofu and Go

Alexander Sharov15m2024/06/06
Read on Terminal Reader

O AWS LetsEncrypt Lambda é um aplicativo baseado em Go 1.22 que emite, renova e gerencia certificados AWS por meio do Let's Encrypt. Após a emissão do certificado, ele armazena certificados dentro do AWS Certificate Manager e do AWS Secret Manager. Lambda é totalmente personalizável e pode ser implantado na AWS via Terraform ou OpenTofu. Também pode ser executado localmente sem problemas.
featured image - AWS LetsEncrypt Lambda ou por que escrevi um provedor TLS personalizado para AWS usando OpenTofu and Go
Alexander Sharov HackerNoon profile picture
0-item
1-item

Hoje em dia, é um desafio imaginar sistemas que tenham endpoints de API públicos sem proteção de certificado TLS. Existem várias maneiras de emitir certificados:


  • Certificados curinga pagos que podem ser comprados de qualquer grande provedor de TLS
  • Certificados raiz pagos que assinam todos os certificados downstream emitidos por sistemas PKI corporativos
  • Certificados gratuitos emitidos por provedores de TLS como LetsEncrypt ou AWS Certificate Manager
  • Certificados autoassinados, emitidos por OpenSSL ou outra ferramenta


No contexto desta postagem, discutirei principalmente certificados gratuitos que podem ser usados dentro da AWS, mas não apenas pelos serviços da AWS. Claramente, usar qualquer coisa diferente do AWS Certificate Manager não faz sentido se você usa exclusivamente serviços gerenciados da AWS e não tem requisitos rígidos de segurança. O AWS Certificate Manager oferece um método muito conveniente e rápido de emissão de certificados por meio de desafios DNS ou HTTP; no entanto, você enfrentará limitações básicas da AWS se precisar usar esses certificados fora dos serviços da AWS (API Gateway, ALB, NLB, etc.), como uma instância EC2 executando Nginx que precisa de um arquivo de certificado físico. Além disso, mesmo que você solicite, o AWS Certificate Manager não exibe o conteúdo do certificado.


Neste ponto, é um bom momento para lembrá-lo do LetsEncrypt , uma ferramenta mais usada que o Certificate Manager – pelo menos porque não depende da nuvem. Infelizmente, não existem técnicas integradas de emissão de certificado LetsEncrypt disponíveis na AWS. É possível utilizar a ferramenta certbot para seus serviços EC2 ou ECS, mas nesse cenário, você precisará considerar como configurar o processo de renovação. Também não quero combinar estratégias diferentes, pois acho melhor ter um procedimento único para tudo, pois reduz toda a complexidade do sistema.


Levando isso em consideração, criei uma função Lambda que emite e renova automaticamente certificados LetsEncrypt sem exigir configurações complexas. O certificado pode ser utilizado em qualquer serviço AWS usando ARN juntamente com certificados AWS Certificate Manager após a emissão inicial do certificado. Além disso, você pode usar uma versão de certificado físico que é mantida no AWS Secrets Manager em qualquer local escolhido, seja uma instância EC2 executando Nginx ou outro local.

Como funciona o AWS LetsEncrypt Lambda

Neste artigo, presumirei que sua zona DNS é gerenciada pelo AWS Route53.

A função Lambda descrita neste artigo foi escrita em Go v1.22. Todos os recursos de resultado, como registros DNS, segredos ou certificados, são controlados pela função do Amazon IAM, que é criada por meio do código Terraform por padrão. A sequência de ações do Lambda é a seguinte:


  1. Obtenha um evento contendo uma lista de certificados. Normalmente, esse evento pode ser resultado de execução manual ou execução por cron feita por meio de aws_cloudwatch_event_target . Exemplo de evento:
 { "domainName": "hackernoon.referrs.me", "acmeUrl": "prod", "acmeEmail": "[email protected]", "reImportThreshold": 10, "issueType": "default", "storeCertInSecretsManager" : true }
  1. Verifique se o certificado existe no AWS Certificate Manager. Se sim, confirme a data de validade.
  2. Inicie o desafio LetsEncrypt DNS-01 se o número de dias até a data de expiração for menor que reImportThreshold . Esta etapa envolve o Lambda criando um registro TXT que corresponde ao nome de domínio à zona AWS Route53 e aguardando que seu certificado esteja pronto.
  3. O Lambda atualiza o certificado no AWS Certificate Manager quando estiver pronto.
  4. O Lambda armazenará arquivos de certificado dentro do AWS Secrets Manager se storeCertInSecretsManager for verdadeiro.


AWS LetsEncrypt Lambda, diagrama de sequência.

Detalhes de implementação do Lambda

O código

O Lambda está escrito em Go 1.22. Usar o mínimo de bibliotecas possível me ajudou a manter meu objetivo de manter o código seco. A lista completa de bibliotecas go necessárias:

URL

Descrição

github.com/aws/aws-lambda-go

Bibliotecas, exemplos e ferramentas para ajudar os desenvolvedores Go a desenvolver funções do AWS Lambda.

github.com/aws/aws-sdk-go-v2

AWS SDK para a linguagem de programação Go.

github.com/go-acme/lego

Cliente e biblioteca LetsEncrypt / ACME.

github.com/guregu/null

Tratamento razoável de valores anuláveis.

github.com/sirupsen/logrus

Registro estruturado e conectável para Go.


Imagem do Docker

Usei gcr.io/distroless/static:nonroot como uma imagem básica do docker. Para aplicativos Go que não requerem libc, esta imagem é perfeita. Não está completamente vazio como scratch e inclui o seguinte:


  • Certificados CA: não há necessidade de copiá-los de qualquer outro estágio.
  • /etc/passwd: contém usuários e grupos como não-root.
  • /tmp pasta.
  • tzdata: caso você queira definir um fuso horário diferente do UTC.


Processo de construção

Em grandes projetos de software, supervisionar o processo de construção pode se tornar uma tarefa trabalhosa e demorada. Makefiles podem ajudar a automatizar e agilizar esse processo, garantindo que seu projeto seja construído de forma eficiente e consistente. Por esse motivo, prefiro usar Makefile para todos os meus projetos Golang. O arquivo é simples:


 ##@ General help: ## Display this help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) fmt: ## Run go fmt against code. go fmt ./... vet: ## Run go vet against code. go vet ./... ##@ Build build: fmt vet ## Build service binary. go build -o bin/lambda main.go run: vet ## Run service from your laptop. go run ./main.go ##@ Test lint: ## Run Go linter golangci-lint run ./... test: ## Run Go tests go test ./...


Do lado do CICD, usei a configuração típica do aplicativo Go

  1. Ações do GitHub como integração contínua.

  2. ghcr.io como registro docker. Comparado ao DockerHub, este oferece dois recursos principais que o tornam minha preferência de uso:

    1. Os fluxos de trabalho de construção, teste e implantação podem ser automatizados mais facilmente diretamente do repositório GitHub, graças à integração suave do GHCR com GitHub Actions. Isso pode aumentar a produtividade e simplificar o processo de desenvolvimento.
    2. O GHCR aproveita o modelo de permissão do GitHub, permitindo que os usuários gerenciem o acesso às imagens de contêiner usando as mesmas equipes e permissões que usam para seus repositórios de código. Isso simplifica o gerenciamento de usuários e aumenta a segurança.
  3. kvendingoldo/semver-action : meu plugin GitHub Actions para versionamento automático. É uma ação do GitHub que gera tags compatíveis com SemVer para commits de repositório. A ação pode gerenciar versões, gerar lançamentos GitHub e controlar ramificações de lançamento dentro do repositório. Funciona maravilhosamente bem com single e monorepos.

  4. Geração automática de changelog. Eu gosto de changelogs! No contexto de outros projetos OpenSource que gerencio (por exemplo, https://github.com/tofuutils/tenv , https://github.com/tofuutils/tofuenv , etc.), minha equipe reconheceu a importância de informar os usuários sobre mudanças.

  5. golangci-lint . Da minha perspectiva, todo código deve ser revisado por um analisador de código estático. O SonarQube não pode ser configurado para todos os projetos, no entanto, o golangci, na minha opinião, é suficiente para projetos Go de pequeno a médio porte.

  6. códigospell.yml . Além da verificação do código, é uma boa ideia verificar a gramática, principalmente se você tiver uma grande quantidade de documentação.

Como implantar Lambda na AWS via Terraform/OpenTofu

O código discutido nesta página é o mesmo para Terraform e OpenTofu, mas a partir do Terraform v1.6, a Hashicorp modificou a licença do Terraform para Business Source License (BSL) v1.1. Terraform, mude para OpenTofu o mais rápido possível.

Se você precisar gerenciar várias versões do OpenTofu ou Terraform, use o dezv - Gerenciador de versões OpenTofu, Terraform, Terragrunt e Atmos, escrito em Go.

Mais exemplos do Terraform/OpenTofu podem ser encontrados na pasta de exemplos do repositório Git .

Para trabalhar com AWS LetsEncrypt Lambda via OpenTofu você precisa seguir as seguintes etapas:

  1. Adicione o módulo ao seu código OpenTofu/Terraform

     module "letsencrypt_lambda" { source = "[email protected]:kvendingoldo/aws-letsencrypt-lambda.git//files/terraform/module?ref=0.31.4" blank_name = "kvendingoldo-letsencrypt-lambda" tags = var.tags cron_schedule = var.letsencrypt_lambda_cron_schedule events = var.letsencrypt_lambda_events ecr_proxy_username = var.ecr_proxy_username ecr_proxy_access_token = var.ecr_proxy_access_token }
  2. Especifique variáveis

     variable "tags" { default = { hackernoon : "demo" } } variable "ecr_proxy_username" { default = "kvendingoldo" } variable "ecr_proxy_access_token" { default = "ghp_xxx" } variable "letsencrypt_lambda_cron_schedule" { default = "rate(168 hours)" } variable "letsencrypt_lambda_events" { default = [ { "acmRegion" : "us-east-1", "route53Region" : "us-east-1", "domainName" : "hackernoon.referrs.me", "acmeUrl" : "stage", "acmeEmail" : "[email protected]", "reImportThreshold" : 100, "issueType" : "default", "storeCertInSecretsManager" : false } ] }
  3. Preste atenção às variáveis ecr_proxy_username e ecr_proxy_access_token . Por padrão, o AWS Lambda não pode extrair imagens de fontes diferentes do AWS ECR. Felizmente, a equipe da AWS criou o cache ECR Proxy, que pode buscar imagens de registros disponíveis publicamente, como DockerHub ou GHCR, e armazená-las dentro do ECR. Apesar dessa possibilidade, a AWS não permite que imagens sejam extraídas sem token, mesmo de repositórios públicos abertos, portanto, você deve adquirir um token GitHub pessoal para obter acesso a imagens Docker pré-construídas. Alternativamente, você pode extrair meu repositório GitHub, construir a imagem localmente e depois carregá-la em seu repositório ECR pré-existente. Neste cenário, o exemplo pode ser modificado da seguinte forma:

     module "letsencrypt_lambda" { source = "../../" blank_name = "kvendingoldo-letsencrypt-lambda" tags = var.tags cron_schedule = var.letsencrypt_lambda_cron_schedule events = var.letsencrypt_lambda_events ecr_proxy_enabled = false ecr_image_uri = "<YOUR_ACCOUNT_ID>.dkr.ecr.us-east-2.amazonaws.com/aws_letsencrypt_lambda:<VERSION>" }


  4. Ao concluir a alteração do código, execute o seguinte comando para instalar o OpenTofu pelo OpenTofu version switcher tenv :

     $ tenv tofu install
  5. E por fim, execute os seguintes comandos para aplicar o código produzido:

     $ tofu init $ tofu plan $ tofu apply
  6. Aguarde até que o código seja implantado na AWS e os eventos sejam acionados. Após alguns minutos, você verá certificados prontos dentro do gerenciador de certificados. Exemplo:

    Uma lista de certificados emitidos com AWS LetsEncrypt Lambda dentro do AWS Certificate Manager.

  7. A partir de agora, a AWS pode usar o certificado emitido em qualquer serviço da ARN.

  8. Se você precisar usar o certificado fora dos serviços da AWS ou tiver acesso ao seu conteúdo, defina a opção de evento storeCertInSecretsManager como true . Nessa situação, quando o Lambda concluir a execução básica, o certificado será salvo no AWS Secrets Manager. Dá aos usuários mais flexibilidade: eles podem inspecionar o conteúdo do certificado, trabalhar com ele diretamente do EC2, etc. Para saber mais sobre o AWS Secrets Manager, leia o guia oficial.

    Exemplo de certificado emitido, armazenado dentro do AWS Secrets Manager.


Variáveis ambientais

Nome

Descrição

Valores possíveis

Valor padrão

Exemplo

Obrigatório

FORMATTER_TYPE

Tipo de formatador para logs

JSON | TEXTO

TEXTO

JSON

MODE

Modo de aplicação. Defina o modo cloud para execução da AWS e o modo local para testes locais.

nuvem | local

nuvem

nuvem

LOG_LEVEL

Nível de registro

pânico | fatal | erro | avisar | informações | depurar | rastreamento

avisar

avisar

AWS_REGION

Região padrão da AWS. Após a implantação na AWS, ele é configurado automaticamente.

<qualquer região válida da AWS>

-

nós-leste-1

DOMAIN_NAME

Nome de domínio para o qual o certificado está sendo emitido ou renovado

qualquer nome de domínio válido

-

meio-dia. refere.me

ACME_URL

A URL LetsEncrypt de produção será utilizada se estiver definida como prod ; caso contrário, o URL do estágio será usado.

produzir | estágio

cutucar

cutucar

ACME_EMAIL

Endereço de e-mail vinculado ao certificado LetsEncrypt

qualquer e-mail válido

[email protected]

[email protected]

REIMPORT_THRESHOLD

O certificado será renovado se seu tempo de vida (TTL) for igual REIMPORT_THRESHOLD .

qualquer int > 0

10

10

STORE_CERT_IN_SECRETSMANAGER

Se true , o Lambda manterá o certificado no Certificate Manager e no Secrets Manager.

“verdadeiro” | "falso"

"falso"

"falso"


Como verificar os logs do LetsEncrypt Lambda

No escopo do trabalho com aws-letsencrypt-lambda, ocasionalmente você pode querer revisar os logs. É muito fácil de realizar:

  1. Vá para AWS Cloudwatch, clique em “Grupos de log”
  2. Encontre o grupo de logs com o nome especificado no código OpenTofu. Por exemplo, no meu caso é /aws/lambda/kvendingoldo-letsencrypt-lambda
  3. Vá para o grupo, selecione o stream desejado na lista e revise os logs.


Como acionar o Lambda manualmente por meio da UI da AWS

  1. Vá para a função Lambda que foi criada via OpenTofu. Clique no botão “Testes”.

    AWS LetsEncrypt Lambda: interface de IU

  2. Preencha Test Event e clique em Test

     { "domainName": "<YOUR_VALID_DOMAIN>", "acmeUrl": <stage | prod>, "acmeEmail": "<ANY_VALID_EMAIL>", "reImportThreshold": 10, "issueType": "<default | force>", "storeCertInSecretsManager" : <true | false> }

    Exemplo 1:

     { "domainName": "hackernoon.referrs.me", "acmeUrl": "prod", "acmeEmail": "[email protected]", "reImportThreshold": 10, "issueType": "default" }


  3. Aguarde até que a execução seja concluída. Você pode ver o log de execução disponível no Cloudwatch. Normalmente, o problema inicial leva cerca de 5 minutos.

Como testar o Lambda localmente

  1. Clone o repositório https://github.com/kvendingoldo/aws-letsencrypt-lambda para o seu laptop

  2. Configure as credenciais do AWS Cli por meio do guia oficial .

  3. Examine a seção de variáveis de ambiente e defina o número mínimo de variáveis necessárias. Como LetsEncrypt limitará a quantidade de novas tentativas por hora para ACME_URL="prod" , aconselho usar ACME_URL="stage" para teste. Exemplo de variáveis de ambiente:

     export AWS_REGION="us-east-2" export MODE=local export DOMAIN_NAME="hackernoon.referrs.me" export ACME_URL="stage" export ACME_EMAIL="[email protected]" export REIMPORT_THRESHOLD=10 export ISSUE_TYPE="default" export STORE_CERT_IN_SECRETSMANAGER="true"
  4. Execute o lambda localmente por meio do seguinte comando:

     go run main.go
  5. Após a execução bem-sucedida do Lambda, o log a seguir aparecerá.

     INFO[0000] Starting lambda execution ... INFO[0000] Lambda will use STAGING ACME URL; If you need to use PROD URL specify it via 'ACME_URL' or pass in event body INFO[0000] Certificate found, arn is arn:aws:acm:us-east-2:004867756392:certificate/72f872fd-e577-43f4-ae38-6833962630af. Trying to renew ... INFO[0000] Checking certificate for domain 'hackernoon.referrs.me' with arn 'arn:aws:acm:us-east-2:004867756392:certificate/72f872fd-e577-43f4-ae38-6833962630af' INFO[0000] Certificate status is 'ISSUED' INFO[0000] Certificate in use by [] INFO[0000] Certificate valid until 2024-08-31 13:50:49 +0000 UTC (89 days left) INFO[0000] Try to get certificate for hackernoon.referrs.me domain 2024/06/02 17:56:23 [INFO] acme: Registering account for [email protected] 2024/06/02 17:56:24 [INFO] [hackernoon.referrs.me, www.hackernoon.referrs.me] acme: Obtaining bundled SAN certificate 2024/06/02 17:56:25 [INFO] [hackernoon.referrs.me] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/12603809394 2024/06/02 17:56:25 [INFO] [www.hackernoon.referrs.me] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/12603809404 2024/06/02 17:56:25 [INFO] [hackernoon.referrs.me] acme: Could not find solver for: tls-alpn-01 2024/06/02 17:56:25 [INFO] [hackernoon.referrs.me] acme: Could not find solver for: http-01 2024/06/02 17:56:25 [INFO] [hackernoon.referrs.me] acme: use dns-01 solver 2024/06/02 17:56:25 [INFO] [www.hackernoon.referrs.me] acme: Could not find solver for: tls-alpn-01 2024/06/02 17:56:25 [INFO] [www.hackernoon.referrs.me] acme: Could not find solver for: http-01 2024/06/02 17:56:25 [INFO] [www.hackernoon.referrs.me] acme: use dns-01 solver 2024/06/02 17:56:25 [INFO] [hackernoon.referrs.me] acme: Preparing to solve DNS-01 2024/06/02 17:56:26 [INFO] Wait for route53 [timeout: 5m0s, interval: 4s] 2024/06/02 17:57:00 [INFO] [www.hackernoon.referrs.me] acme: Preparing to solve DNS-01 2024/06/02 17:57:00 [INFO] Wait for route53 [timeout: 5m0s, interval: 4s] 2024/06/02 17:57:30 [INFO] [hackernoon.referrs.me] acme: Trying to solve DNS-01 2024/06/02 17:57:30 [INFO] [hackernoon.referrs.me] acme: Checking DNS record propagation. [nameservers=109.122.99.130:53,109.122.99.129:53] 2024/06/02 17:57:34 [INFO] Wait for propagation [timeout: 5m0s, interval: 4s] 2024/06/02 17:57:46 [INFO] [hackernoon.referrs.me] The server validated our request 2024/06/02 17:57:46 [INFO] [www.hackernoon.referrs.me] acme: Trying to solve DNS-01 2024/06/02 17:57:46 [INFO] [www.hackernoon.referrs.me] acme: Checking DNS record propagation. [nameservers=109.122.99.130:53,109.122.99.129:53] 2024/06/02 17:57:50 [INFO] Wait for propagation [timeout: 5m0s, interval: 4s] 2024/06/02 17:58:30 [INFO] [www.hackernoon.referrs.me] The server validated our request 2024/06/02 17:58:30 [INFO] [hackernoon.referrs.me] acme: Cleaning DNS-01 challenge 2024/06/02 17:58:30 [INFO] Wait for route53 [timeout: 5m0s, interval: 4s] 2024/06/02 17:59:09 [INFO] [www.hackernoon.referrs.me] acme: Cleaning DNS-01 challenge 2024/06/02 17:59:09 [INFO] Wait for route53 [timeout: 5m0s, interval: 4s] 2024/06/02 17:59:43 [INFO] [hackernoon.referrs.me, www.hackernoon.referrs.me] acme: Validations succeeded; requesting certificates 2024/06/02 17:59:43 [INFO] Wait for certificate [timeout: 30s, interval: 500ms] 2024/06/02 17:59:45 [INFO] [hackernoon.referrs.me] Server responded with a certificate. INFO[0203] Certificate has been successfully imported. Arn is arn:aws:acm:us-east-2:004867756392:certificate/72f872fd-e577-43f4-ae38-6833962630af INFO[0204] Secret updated successfully. SecretId: arn:aws:secretsmanager:us-east-2:004867756392:secret:hackernoon.referrs.me-NioT77 INFO[0204] Lambda has been completed
  6. É isso. A partir de agora, a AWS pode usar o certificado emitido em qualquer serviço da ARN ou em outros locais onde seja fisicamente necessário, obtendo-o no AWS Secrets Manager.


Experiência prática de uso ao longo de mais de 4 anos na AWS

Uso a função Lambda em produção há quase quatro anos. Ao longo dos anos, vários aspectos da implementação inicial mudaram:

  1. Anteriormente, a AWS proibia o uso de quaisquer registros não ECR como fontes Lambda. Isso não mudou, no entanto, a AWS adicionou proxy ECR para GitHub, DockerHub e alguns registros adicionais. Sem essa funcionalidade, tivemos que enviar manualmente as imagens Lambda para nosso ECR pessoal e substituir o URL da imagem no código Terraform. Agora o código OpenTofu faz isso automaticamente via ECR Proxy.

  2. No início, pensei em introduzir vários desafios, como http-01 ou tls-alpn-01 , mas ninguém me questionou sobre isso durante quatro anos. Ele ainda está presente nos problemas do GitHub e, se esse recurso for necessário, podemos trabalhar juntos para criá-lo.

  3. Eu não queria utilizar certificados LetsEncrypt em instâncias EC2 puras quando o projeto foi iniciado originalmente, mas hoje em dia é uma prática padrão. Como afirmei anteriormente, em certas situações, um certificado pode ser recuperado do AWS Secrets Managed usando o AWS cli.

  4. Escrevi muitos códigos Go novos ao longo dos anos, então posso dizer que o código Lambda original em meu repositório não é tão sofisticado quanto poderia ser. Há uma diferença significativa entre ele e meu projeto Go mais recente, tenv (gerenciador de versões OpenTofu, Terraform, Terragrunt e Atmos, escrito em Go), mas em qualquer caso, o código ainda é geralmente suportado, portanto, fazer modificações nele ganhou não seja muito problemático. Ocasionalmente, realizarei refatorações significativas para tornar o código mais elegante.

  5. O mesmo Lambda está sendo usado há anos em diversos projetos diferentes. Além disso, sou cofundador da plataforma DevOps cloudexpress.app , onde nossa equipe gerencia certificados TLS para todos os nossos clientes usando o AWS LetsEncrypt Lambda para simplificar os processos de automação.


Agora vamos falar sobre números. Durante um período de 4 anos , este projeto ajudou muitas pessoas e foi usado em vários projetos OpenSource e em mais de 30 projetos comerciais . O Lambda emite mais de 2.000 certificados e não quer parar por aí.

Conclusão

AWS LetsEncrypt Lambda é uma solução adequada para você, se

  • Você deve ter uma versão física do certificado e usá-lo em serviços nativos não AWS, como EC2 Nginx.
  • Você não deseja depender do AWS Certificate Manager para gerenciar o processo de emissão e renovação de certificados TLS (verificar logs, definir datas de renovação, etc.).
  • Você gostaria de receber notificações por e-mail do LetsEncrypt quando seu certificado expirar ou expirar em breve.
  • Você deseja personalizar a solução alterando o código Golang (por exemplo, alterando o desafio LetsEncrypt, armazenando o certificado no Hashicorp Vault, etc.).


Se você descobriu que pelo menos um desses pontos se aplica à sua situação, você pode usar o AWS Lambda. Além disso, se você deseja participar do desenvolvimento, estou sempre aberto a novos problemas e solicitações pull no GitHub. URL do projeto: https://github.com/kvendingoldo/aws-letsencrypt-lambda .