Get verified SSL certificate via CloudFormation
Right now, it's hard to automcatically retrieve a verified SSL/TLS certificate from AWS Certificate Manager via CloudFormation, because you need to have at least a admin email address on one of your super domains. The solution provided here automates this process by managing the CloudFormation-unfriendly SES related stuff.
Overview of moving parts
- SES for Identity Management:
- A lambda function (calling
ses_domain_identity.py
) creates the subdomain (parameterdomain
) in an existing super-domain (parameter `hostedZoneName) - lambda function is returning the verification token for TXT record
- A lambda function (calling
- SNS Topic for receiving approval emails
- lambda function (
ses_wait_for_verification_and_create_rule_set
) is used to create a SES rule set to forward the certificate approval email to SNS - lambda function (
process_cert_manager_mail
) is triggered by SNS events and verifies the certification request by parsing the email to get the approval link and finally "clicking on it" via http post request
- lambda function (
Use the template as a nested stack
See AWS::CloudFormation::Stack documentation.
To retrieve a SSL certificate for subdomain.mydomain.com
you have to have a
Route53 Hosted Zone for a
super domain (e.g. mydomain.com
) which is needed to create DNS records for your domain.
Then you can use the following YAML snippet to retrieve the verified SSL certificate:
AWSTemplateFormatVersion: '2010-09-09'
Resources:
SSLCertificate:
Type: "AWS::CloudFormation::Stack"
Properties:
Parameters:
domain: subdomain.mydomain.com
hostedZoneName: mydomain.com. # your hosted domain
TemplateURL: "https://s3-eu-west-1.amazonaws.com/is24-infrastructure-public/cloudformation/verified-ssl-certificate/ssl-certificate.template.yaml"
Output parameters are:
Parameter Name | Description |
---|---|
Arn | ARN of the verified SSL certificate |
sslCertificateArn | ARN of the verified SSL certificate |
To reference the SSL certificate you can use the following snippet:
AWSTemplateFormatVersion: '2010-09-09'
Resources:
LoadBalancerListenerHttps:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref LoadBalancer
Port: 443
Protocol: HTTPS
DefaultActions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
Certificates:
- CertificateArn: !GetAtt SSLCertificate.Outputs.Arn
Deploying the certificate stack
Deploy the example stack like this
aws cloudformation create-stack \
--stack-name my-ssl-stack \
--template-body file://$(pwd)/ssl-certificate.template.yaml \
--parameters \
ParameterKey=domain,ParameterValue=my-domain.example.com \
ParameterKey=hostedZoneName,ParameterValue=example.com. \
--capabilities CAPABILITY_IAM
Changes to this repo are automatically deployed via teamcity after push.
Download URLs
We provide the templates ready for you:
Latest version:
- Template:
s3://is24-infrastructure-public/cloudformation/verified-ssl-certificate/ssl-certificate.template.yaml
- Lambda Code:
s3://is24-infrastructure-public/cloudformation/verified-ssl-certificate/labda_functions.zip
<commit-hash>
:
Specific version of commit - Template:
s3://is24-infrastructure-public/cloudformation/verified-ssl-certificate/<commit-hash>/ssl-certificate.template.yaml
- Lambda Code:
s3://is24-infrastructure-public/cloudformation/verified-ssl-certificate/<commit-hash>/labda_functions.zip
Development:
# buid an deploy code to your development bucket
./deploy.sh s3://my-dev-bucket/my-prefix
# deploy stack with development version
aws cloudformation create-stack \
--stack-name my-ssl-stack \
--template-body file://$(pwd)/ssl-certificate.template.yaml \
--parameters \
ParameterKey=domain,ParameterValue=my-domain.example.com \
ParameterKey=hostedZoneName,ParameterValue=example.com. \
ParameterKey=lambdaCodeS3Bucket,ParameterValue=my-dev-bucket \
ParameterKey=lambdaCodeS3Key,ParameterValue=my-prefix/lambda_functions.zip \
--capabilities CAPABILITY_IAM