Creating an SSL Certificate in AWS with CloudFormation
Creating and managing SSL certificates in AWS is crucial for securing API Gateway, ALB, or ELB-based applications. While manual certificate creation is an option, it lacks the scalability and integration benefits that AWS CloudFormation offers. This post will guide you through the process of automating SSL certificate creation and management in AWS using CloudFormation, ensuring a secure and efficient deployment. Learn how to leverage CloudFormation to not only create but also seamlessly reference SSL certificates in your AWS Stacks, enhancing your application’s security and your infrastructure’s manageability.
Wildcard or not?
When we talk about domains for certificates we view them as either a root or a wildcard:
- Root Domain Certificate: When a certificate is issued for the root domain, such as domain.com, it means that the certificate is explicitly valid for that domain only. It ensures secure connections to the website accessed directly via the root domain.
- Wildcard Domain Certificate: A certificate issued for a wildcard domain, denoted as *.domain.com, covers the root domain and all its subdomains at one level. This means it can secure connections not just to domain.com but also to any subdomain like www.domain.com, mail.domain.com, store.domain.com, etc. The asterisk (*) acts as a placeholder for any subdomain name.
Build it the Easy Way (for domains that will have a wildcard)
You can use a script I created to automate all of this for you. First we’ll download the script, next we’ll run it. The script asks all of the questions it needs to execute such as domain, AWS named profile, etc… it assumes you have the domain hosted at AWS as well.
1
2
3
4
# Obtain the script
wget -O create-certificate.sh "https://raw.githubusercontent.com/cbschuld/aws-cf-static-website-hosting-s3-cloudfront-route53/main/create-certificate-with-wildcard.sh"
# Run the script
/bin/bash create-certificate.sh
The Detailed Way
You can create them with CloudFormation using the following YAML file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
DomainName:
Description: "Domain for which you are requesting a cert"
Type: String
Default: example.com # Put your own domain name here
HostedZoneId:
Description: "hosted zone id in which CNAME record for the validation needs to be added"
Type: String
Default: XYZABCDERYH # Put the hosted zone id in which CNAME record for the validation needs to be added
Resources:
Certificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: !Ref DomainName
SubjectAlternativeNames:
- !Sub "*.${DomainName}"
DomainValidationOptions:
- DomainName: !Ref DomainName
HostedZoneId: !Ref HostedZoneId
ValidationMethod: DNS
Outputs:
CertificateArn:
Value: !Ref Certificate
Export:
Name: !Sub "${AWS::StackName}-CertificateArn"
You will need the HostedZoneId
which you can get from the command line or from the AWS UI/UX. This does require jq
and cut
which you may need to install.
1
2
3
4
5
6
7
8
REGION=us-east-1
PROFILE_NAME="PROFILE"
DOMAIN_NAME="DOMAIN"
STACK_NAME=$(echo "$DOMAIN_NAME" | sed 's/\./-/g')-certificate
HOSTED_ZONE=$(aws route53 list-hosted-zones-by-name --profile="$PROFILE_NAME" |
jq --arg name "$DOMAIN_NAME." -r '.HostedZones | .[] | select(.Name==$name) | .Id' |
cut -d'/' -f3)
echo $HOSTED_ZONE
You can upload this YAML file via CloudFront’s UI/UX or you can run it via command line:
1
2
3
4
5
6
7
8
wget -O certificate.yml https://raw.githubusercontent.com/cbschuld/aws-cf-static-website-hosting-s3-cloudfront-route53/main/certificate.yml
aws cloudformation create-stack --stack-name $STACK_NAME \
--template-body file://certificate.yml \
--parameters \
ParameterKey=DomainName,ParameterValue=$DOMAIN_NAME \
ParameterKey=HostedZoneId,ParameterValue=$HOSTED_ZONE \
--region=$REGION \
--profile=$PROFILE_NAME
After the Stack is complete and successful you can get the certificate’s ARN value. This command will return just the value of the CertificateArn output parameter from the specified stack, without any additional formatting or information.
1
2
3
4
5
6
aws cloudformation describe-stacks \
--stack-name $STACK_NAME \
--query "Stacks[0].Outputs[?OutputKey=='CertificateArn'].OutputValue" \
--output text \
--region=$REGION \
--profile=$PROFILE_NAME
This certificate YAML file is managed in change control on github.