O post descreve os passos para automatizar a gestão de certificados SSL da usando e AWS.
— esta é uma ferramenta que nos permitirá implementar esse recurso. Ela pode trabalhar com certificados SSL da Let’s Encrypt, armazená-los no Amazon Certificate Manager, usar a API Route53 para implementar o desafio DNS-01 e, por fim, enviar notificações para o SNS. No acme-dns-route53 também há funcionalidade embutida para uso dentro do AWS Lambda, e isso é exatamente o que precisamos.
Este artigo é dividido em 4 seções:
- criação do arquivo zip;
- criação da função IAM;
- criação da função lambda que dispara acme-dns-route53;
- criação de um timer CloudWatch que aciona a função 2 vezes ao dia;
Nota: antes de começar, é necessário instalar e
Criação do arquivo zip
acme-dns-route53 é escrito em GoLang e suporta a versão 1.9 ou superior.
Precisamos criar um arquivo zip com o binário acme-dns-route53 dentro. Para isso, é necessário instalar acme-dns-route53 do repositório GitHub usando o comando go install:
$ env GOOS=linux GOARCH=amd64 go install github.com/begmaroman/acme-dns-route53O binário será instalado na $GOPATH/bin diretório. Note que, ao instalar, especificamos duas variáveis de ambiente: GOOS=linux e GOARCH=amd64. Elas informam ao compilador Go que o binário deve ser criado para o sistema operacional Linux e arquitetura amd64 — é isso que será executado no AWS.
AWS pressupõe o deploy do nosso programa em um arquivo zip, então vamos criar um acme-dns-route53.zip arquivo que conterá o binário recém-instalado:
$ zip -j ~/acme-dns-route53.zip $GOPATH/bin/acme-dns-route53Nota: o binário deve estar na raiz do arquivo zip. Para isso, usamos -j a flag.
Agora nosso zip está pronto para o deploy, só falta criar uma função com as permissões necessárias.
Criação de função IAM
Precisamos configurar uma função IAM com as permissões necessárias para nossa lambda durante sua execução.
Vamos nomear esta política lambda-acme-dns-route53-executor e imediatamente atribuir a função básica AWSLambdaBasicExecutionRole. Isso permitirá que nossa lambda seja iniciada e consiga escrever logs no serviço AWS CloudWatch.
Para começar, criaremos um arquivo JSON descrevendo nossas permissões. Isso, em essência, permitirá que os serviços de lambda utilizem a função lambda-acme-dns-route53-executor:
$ touch ~/lambda-acme-dns-route53-executor-policy.jsonO conteúdo do nosso arquivo é o seguinte:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup"
],
"Resource": "arn:aws:logs:::*"
},
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogStream"
],
"Resource": "arn:aws:logs:::log-group:/aws/lambda/acme-dns-route53:*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"cloudwatch:PutMetricData",
"acm:ImportCertificate",
"acm:ListCertificates"
],
"Resource": "*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"sns:Publish",
"route53:GetChange",
"route53:ChangeResourceRecordSets",
"acm:ImportCertificate",
"acm:DescribeCertificate"
],
"Resource": [
"arn:aws:sns:${var.region}::",
"arn:aws:route53:::hostedzone/*",
"arn:aws:route53:::change/*",
"arn:aws:acm:::certificate/*"
]
}
]
}Agora vamos executar o comando aws iam create-role para criar a função:
$ aws iam create-role --role-name lambda-acme-dns-route53-executor
--assume-role-policy-document ~/lambda-acme-dns-route53-executor-policy.jsonNota: lembre-se do ARN da política (Amazon Resource Name) — precisaremos dele nas próximas etapas.
A função lambda-acme-dns-route53-executor foi criada, agora precisamos definir as permissões para ela. A maneira mais simples de fazer isso é usar o comando aws iam attach-role-policy, passando o ARN da política AWSLambdaBasicExecutionRole da seguinte forma:
$ aws iam attach-role-policy --role-name lambda-acme-dns-route53-executor
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRoleNota: a lista com as outras políticas pode ser encontrada .
Criando uma função Lambda que executa acme-dns-route53
Uhu! Agora podemos implantar nossa função na AWS usando o comando aws lambda create-function. A Lambda deve ser configurada usando as seguintes variáveis de ambiente:
AWS_LAMBDA— indica acme-dns-route53 que a execução ocorre dentro do AWS Lambda.DOMAINS— lista de domínios, separados por vírgulas.LETSENCRYPT_EMAIL— contém .NOTIFICATION_TOPIC— o nome do tópico de notificação SNS (opcional).STAGING— se definido como1usa o ambiente de staging.1024MB — limite de memória, pode ser alterado.900secs (15 min) — tempo limite.acme-dns-route53— o nome do nosso binário, que está no arquivo.fileb://~/acme-dns-route53.zip— caminho para o arquivo que criamos.
Agora vamos implantar:
$ aws lambda create-function
--function-name acme-dns-route53
--runtime go1.x
--role arn:aws:iam:::role/lambda-acme-dns-route53-executor
--environment Variables="{AWS_LAMBDA=1,DOMAINS="example1.com,example2.com",LETSENCRYPT_EMAIL=begmaroman@gmail.com,STAGING=0,NOTIFICATION_TOPIC=acme-dns-route53-obtained}"
--memory-size 1024
--timeout 900
--handler acme-dns-route53
--zip-file fileb://~/acme-dns-route53.zip
{
"FunctionName": "acme-dns-route53",
"LastModified": "2019-05-03T19:07:09.325+0000",
"RevisionId": "e3fadec9-2180-4bff-bb9a-999b1b71a558",
"MemorySize": 1024,
"Environment": {
"Variables": {
"DOMAINS": "example1.com,example2.com",
"STAGING": "1",
"LETSENCRYPT_EMAIL": "your@email.com",
"NOTIFICATION_TOPIC": "acme-dns-route53-obtained",
"AWS_LAMBDA": "1"
}
},
"Version": "$LATEST",
"Role": "arn:aws:iam:::role/lambda-acme-dns-route53-executor",
"Timeout": 900,
"Runtime": "go1.x",
"TracingConfig": {
"Mode": "PassThrough"
},
"CodeSha256": "+2KgE5mh5LGaOsni36pdmPP9O35wgZ6TbddspyaIXXw=",
"Description": "",
"CodeSize": 8456317,
"FunctionArn": "arn:aws:lambda:us-east-1::function:acme-dns-route53",
"Handler": "acme-dns-route53"
}Criando um timer do CloudWatch que aciona a função duas vezes ao dia
O último passo é configurar um cron que chama nossa função duas vezes ao dia:
- criar uma regra do CloudWatch com o valor
schedule_expression. - criar um alvo da regra (o que deve ser executado), especificando o ARN da função Lambda.
- dar permissão à regra para chamar a função Lambda.
Abaixo, anexei minha configuração Terraform, mas na verdade isso é feito de forma muito simples com o console da AWS ou AWS CLI.
# Cloudwatch event rule that runs acme-dns-route53 lambda every 12 hours
resource "aws_cloudwatch_event_rule" "acme_dns_route53_sheduler" {
name = "acme-dns-route53-issuer-scheduler"
schedule_expression = "cron(0 */12 * * ? *)"
}
# Specify the lambda function to run
resource "aws_cloudwatch_event_target" "acme_dns_route53_sheduler_target" {
rule = "${aws_cloudwatch_event_rule.acme_dns_route53_sheduler.name}"
arn = "${aws_lambda_function.acme_dns_route53.arn}"
}
# Give CloudWatch permission to invoke the function
resource "aws_lambda_permission" "permission" {
action = "lambda:InvokeFunction"
function_name = "${aws_lambda_function.acme_dns_route53.function_name}"
principal = "events.amazonaws.com"
source_arn = "${aws_cloudwatch_event_rule.acme_dns_route53_sheduler.arn}"
}Agora você também configurou a criação e atualização automática de certificados SSL.
Fonte: habr.com
