What ?
A simple guide of the steps to follow for updating an SSL/TLS certificate PROGRAMMATICALLY using AWS CLI.
Why ?
Because the official documentation about it is a whole mess when is something rather easy and I'd like to share with others and possibly save some time.
How ?
Once you generate your custom certificate using, for example, Let's Encrypt, you may run these AWS CLI commands to update it using bash:
# Use any name but prefer to use one based on a timestamp since they cannot be repeated on every update
AWS_MY_CERT_NAME=my-cert-$(date +%Y%m%d)
# Set the CloudFront distribution we want to update (found at AWS console)
MY_CLOUDFRONT_ID=EV40L17AXPTKC
# Upload the custom certificate to IAM (using ACM does not work)
aws iam upload-server-certificate --server-certificate-name $AWS_MY_CERT_NAME --certificate-body file://my-cert.pem --private-key file://my-cert-privkey.pem --certificate-chain file://my-cert-chain.pem --path /cloudfront/
# Get certificate ID for the update
AWS_MY_CERT_ID=$(aws iam get-server-certificate --server-certificate-name $AWS_MY_CERT_NAME --query "ServerCertificate.ServerCertificateMetadata.ServerCertificateId" --output text)
# Here the trick: load the current configuration to patch it on the fly (AWS has no other option currently)
aws cloudfront get-distribution-config --id $MY_CLOUDFRONT_ID --query DistributionConfig > config.json
sed -i.bak "s/.*\"IAMCertificateId\".*/\"IAMCertificateId\": \"$AWS_MY_CERT_ID\",/g" config.json
sed -i.bak "s/.*\"Certificate\".*/\"Certificate\": \"$AWS_MY_CERT_ID\",/g" config.json
aws cloudfront update-distribution --id $MY_CLOUDFRONT_ID --distribution-config file://config.json
NOTE: using the /cloudfront/
path is important for making the certificate available for CloudFront usage.
When ?
You can add these commands to a bash script file to run it using cron configuration every month (or sooner depending on the frequency of your updates)
Who ?
These commands are based on these blogs and references:
https://docs.aws.amazon.com/cli/latest/reference/cloudfront/index.html
https://docs.aws.amazon.com/cli/latest/reference/cloudfront/update-distribution.html
https://www.reddit.com/r/aws/comments/5jm7wd/why_is_my_custom_ssl_cert_not_available_when/
https://aws.amazon.com/premiumsupport/knowledge-center/install-ssl-cloudfront/
https://intellipaat.com/community/2745/unable-to-select-custom-ssl-certificate-stored-in-aws-iam
https://aws.amazon.com/premiumsupport/knowledge-center/custom-ssl-certificate-cloudfront/
https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-output.html#cli-usage-output-filter
https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-output.html#cli-usage-output-format
https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-shorthand.html
https://docs.aws.amazon.com/cli/latest/reference/cloudfront/get-distribution-config.html
I keep getting this error first of all.
sed -i.bak "s/.\"ViewerCertificate\"./\"ACMCertificateArn\": \"$AWS_MY_CERT_ID\",/g" config.json
sed: 1: "s/.*"ViewerCertificate" ...": bad flag in substitute command: 'f'
sed -i.bak '' "s/.\"ViewerCertificate\"./\"ACMCertificateArn\": \"$AWS_MY_CERT_ID\",/g" config.json
sed: s/."ViewerCertificate"./"ACMCertificateArn": "arn:aws:acm:us-east-1:316897671968:certificate/9f337eae-09ef-4f4b-8d50-3c7e05bedc75",/g: No such file or directory
➜ owner-webapp git:(SF-727-qa) ✗
Can I use this method to update acm certificate credentials if the certificate is already created?