Context: in order to achieve a complete “infrastructure as code”, I want to codify the process of requesting an SSL certificate using certbot , verifying the domain using DNS TXT records, uploading the certificate to Amazon Certificate Manager (ACM), and finally attaching the ACM ARN certificate to my distribution Cloudfront All of this must be done through a serverless infrastructure.
I saw 2 possible options to make this work.
Option 1: using asynchronous javascript file variables
those. in serverless.yml I would define entries like:
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}}
If resources will use these variables as follows:
- Type: TXT Name: _acme-challenge.www.${{self:custom.domains.${{self:provider.stage}}, ''}} TTL: '86400' ResourceRecords: - ${{self:custom.ssl.${{self:provider.stage}}.dnsTxtWww}}
Where scripts/request-cert.js would look like this:
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' }) }
The problem is that it seems impossible to send parameters to request-cert.js or for this script to know the parameters of the serverless or options plugin (since this is not a plugin, but a simple script without context). This means that the script cannot know about the scene and domain, etc., for which the deployment is intended, and therefore, the required variables are missing for the certificate request.
So option 1 seems to be out of the question.
Option 2: create a plugin
Of course, I can create a plugin that will have all the necessary variables, because it can access serverless and options objects. Now the problem is that I will need to access the output plan inside serverless.yml , and so far I have not seen how this can be done. That is, I would like to be able to do something like this:
custom: domains: prod: tommedema.tk ssl: prod: dnsTxtRoot: ${{myPlugin:cert.dnsTxtRoot}} dnsTxtWww: ${{myPlugin:cert.dnsTxtWww}} certArn: ${{myPlugin:cert.certArn}}
But this is not possible. Is it correct?
If this is also not possible, how can I achieve my goal to programmatically (i.e. following the infrastructure as code principles) deploy my services using special SSL certificates without any manual steps? I.e.
- certificate request from certbot
- receive DNS txt records for confirmation from certbot
- attach DNS txt entries to route sets53.
- deployment of DNS records and certificate verification
- upload certificate from certbot and upload it to ACM
- get ARN certificate from ACM
- link to the ARN certificate from inside the cloud distribution inside the cloud information template
- relocate with attached ARN certificate