Контекст: для достижения полной «инфраструктуры как кода» я хочу систематизировать процесс запроса SSL-сертификата с использованием certbot
, проверки домена с использованием записей DNS TXT
, загрузки сертификата в Amazon Certificate Manager (ACM) и, наконец, прикрепление сертификата ACM ARN к моему дистрибутиву Cloudfront. Все это должно быть сделано через бессерверную структуру.
Я видел 2 возможных варианта, чтобы сделать эту работу.
Вариант 1: использование асинхронных переменных файла JavaScript
т.е. в serverless.yml
я бы определил такие записи, как:
custom:
domains:
prod: tommedema.tk
ssl:
prod:
dnsTxtRoot: ${{file(scripts/request-cert.js):cert.dnsTxtRoot}}
dnsTxtWww: ${{file(scripts/request-cert.js):cert.dnsTxtWww}}
certArn: ${{file(scripts/request-cert.js):cert.certArn}}
Где ресурсы затем будут использовать эти переменные следующим образом:
- Type: TXT
Name: _acme-challenge.www.${{self:custom.domains.${{self:provider.stage}}, ''}}
TTL: '86400'
ResourceRecords:
- ${{self:custom.ssl.${{self:provider.stage}}.dnsTxtWww}}
Где scripts/request-cert.js
будет выглядеть так:
module.exports.cert = () => {
console.log('running async logic')
// TODO: run certbot, get DNS records, upload to ACM
return Promise.resolve({
dnsTxtRoot: '"LnaKMkgqlIkXXXXXXXX-7PkKvqb_wqwVnC4q0"',
dnsTxtWww: '"c43VS-XXXXXXXXXWVBRPCXXcA"',
certArn: 'arn:aws:acm:us-east-1:XXXX95:certificate/XXXXXX'
})
}
Проблема здесь в том, что невозможно отправить параметры в request-cert.js
или чтобы этот скрипт знал о параметрах плагина serverless
или options
(поскольку это не плагин, а простой скрипт без контекста). Это означает, что сценарий не может знать об этапе, домене и т. д., для которых предназначено развертывание, и поэтому в нем отсутствуют необходимые переменные для запроса сертификата.
Так что вариант 1 кажется невозможным.
Вариант 2: создайте подключаемый модуль
Конечно, я могу создать плагин, в котором будут все необходимые переменные, потому что он может получить доступ к объектам serverless
и options
. Теперь проблема в том, что мне нужно будет получить доступ к выводу плагина внутри serverless.yml
, и пока я не видел, как это можно сделать. т.е. Я хотел бы иметь возможность сделать что-то вроде этого:
custom:
domains:
prod: tommedema.tk
ssl:
prod:
dnsTxtRoot: ${{myPlugin:cert.dnsTxtRoot}}
dnsTxtWww: ${{myPlugin:cert.dnsTxtWww}}
certArn: ${{myPlugin:cert.certArn}}
Но это не кажется возможным. Это правильно?
Если это также невозможно, как я могу достичь своей цели, чтобы программно (т. е. следуя принципам инфраструктуры как кода) развернуть свои службы с помощью пользовательских сертификатов SSL без каких-либо ручных действий? т.е.
- запросить сертификат у certbot
- получать txt-записи DNS для проверки от certbot
- прикрепить записи DNS txt к наборам записей route53
- развернуть записи DNS и проверить сертификат
- скачайте сертификат с certbot и загрузите его в ACM
- получить сертификат ARN от ACM
- ссылка на сертификат ARN из дистрибутива cloudfront внутри шаблона cloudformation
- повторное развертывание с прикрепленным сертификатом ARN