|  | #!/usr/bin/env bash | 
        
          |  | ################################################################################ | 
        
          |  | # USAGE: | 
        
          |  | #     ./create-acm-certificate.sh [domain] | 
        
          |  | # | 
        
          |  | # DESCRIPTION: | 
        
          |  | #     This utility create and validates a certificate in ACM, as well as the | 
        
          |  | #     required DNS records for validation. | 
        
          |  | # | 
        
          |  | #     The following requirements need to be met in order to use this utility: | 
        
          |  | #     - The domain's DNS must be hosted by Route 53. | 
        
          |  | #     - The account and region defined in `~/.aws/config` and defined in your | 
        
          |  | #       `AWS_PROFILE` environment variable (or lack thereof) will be assumed. | 
        
          |  | ################################################################################ | 
        
          |  |  | 
        
          |  | ################################################################################ | 
        
          |  | # Requests a certificate based on the provided domain name from ACM. | 
        
          |  | ################################################################################ | 
        
          |  | ACM_CERTIFICATE_ARN=$(aws acm request-certificate \ | 
        
          |  | --domain-name "$1" \ | 
        
          |  | --subject-alternative-names "*.$1" \ | 
        
          |  | --validation-method DNS \ | 
        
          |  | --query CertificateArn \ | 
        
          |  | --output text) | 
        
          |  |  | 
        
          |  | echo "[ACM]          Certificate ARN: $ACM_CERTIFICATE_ARN" | 
        
          |  |  | 
        
          |  | ################################################################################ | 
        
          |  | # The following commands extract the name and value of the required CNAME record | 
        
          |  | # that needs to be created to confirm ownership of the domain the certificate | 
        
          |  | # will be associated with. | 
        
          |  | ################################################################################ | 
        
          |  | VALIDATION_NAME="$(aws acm describe-certificate \ | 
        
          |  | --certificate-arn "$ACM_CERTIFICATE_ARN" \ | 
        
          |  | --query "Certificate.DomainValidationOptions[?DomainName=='$1'].ResourceRecord.Name" \ | 
        
          |  | --output text)" | 
        
          |  |  | 
        
          |  | VALIDATION_VALUE="$(aws acm describe-certificate \ | 
        
          |  | --certificate-arn "$ACM_CERTIFICATE_ARN" \ | 
        
          |  | --query "Certificate.DomainValidationOptions[?DomainName=='$1'].ResourceRecord.Value" \ | 
        
          |  | --output text)" | 
        
          |  |  | 
        
          |  | echo "[ACM]          Certificate validation record: $VALIDATION_NAME CNAME $VALIDATION_VALUE" | 
        
          |  |  | 
        
          |  | ################################################################################ | 
        
          |  | # Request the hosted zone from Route 53 that is associated with the domain that | 
        
          |  | # the validation CNAME record will be associated with. | 
        
          |  | ################################################################################ | 
        
          |  | R53_HOSTED_ZONE_ID="$(aws route53 list-hosted-zones-by-name \ | 
        
          |  | --dns-name "$1" \ | 
        
          |  | --query "HostedZones[?Name=='$1.'].Id" \ | 
        
          |  | --output text)" | 
        
          |  |  | 
        
          |  | R53_HOSTED_ZONE=${R53_HOSTED_ZONE_ID##*/} | 
        
          |  |  | 
        
          |  | echo "[Route 53]     Hosted Zone ID: $R53_HOSTED_ZONE" | 
        
          |  |  | 
        
          |  | ################################################################################ | 
        
          |  | # Create the change batch needed to upset the validation record, then run the | 
        
          |  | # command to apply the change batch. | 
        
          |  | ################################################################################ | 
        
          |  | R53_CHANGE_BATCH=$(cat <<EOM | 
        
          |  | { | 
        
          |  | "Changes": [ | 
        
          |  | { | 
        
          |  | "Action": "UPSERT", | 
        
          |  | "ResourceRecordSet": { | 
        
          |  | "Name": "$VALIDATION_NAME", | 
        
          |  | "Type": "CNAME", | 
        
          |  | "TTL": 300, | 
        
          |  | "ResourceRecords": [ | 
        
          |  | { | 
        
          |  | "Value": "$VALIDATION_VALUE" | 
        
          |  | } | 
        
          |  | ] | 
        
          |  | } | 
        
          |  | } | 
        
          |  | ] | 
        
          |  | } | 
        
          |  | EOM | 
        
          |  | ) | 
        
          |  |  | 
        
          |  | R53_CHANGE_BATCH_REQUEST_ID="$(aws route53 change-resource-record-sets \ | 
        
          |  | --hosted-zone-id "$R53_HOSTED_ZONE" \ | 
        
          |  | --change-batch "$R53_CHANGE_BATCH" \ | 
        
          |  | --query "ChangeInfo.Id" \ | 
        
          |  | --output text)" | 
        
          |  |  | 
        
          |  | ################################################################################ | 
        
          |  | # Wait 1) for the validation record to be created, and 2) for the certificate | 
        
          |  | # to validate the domain and issue the certificate. | 
        
          |  | ################################################################################ | 
        
          |  | echo "[Route 53]     Waiting for validation records to be created..." | 
        
          |  | aws route53 wait resource-record-sets-changed --id "$R53_CHANGE_BATCH_REQUEST_ID" | 
        
          |  |  | 
        
          |  | echo "[ACM]          Waiting for certificate to validate..." | 
        
          |  | aws acm wait certificate-validated --certificate-arn "$ACM_CERTIFICATE_ARN" | 
        
          |  |  | 
        
          |  | ACM_CERTIFICATE_STATUS="$(aws acm describe-certificate \ | 
        
          |  | --certificate-arn "$ACM_CERTIFICATE_ARN" | 
        
          |  | --query "Certificate.Status" | 
        
          |  | --output text)" | 
        
          |  |  | 
        
          |  | ACM_CERTIFICATE="$(aws acm describe-certificate \ | 
        
          |  | --certificate-arn "$ACM_CERTIFICATE_ARN" | 
        
          |  | --output json)" | 
        
          |  |  | 
        
          |  | ################################################################################ | 
        
          |  | # Output the certificate description from ACM, and highlight the status of the | 
        
          |  | # certificate. | 
        
          |  | ################################################################################ | 
        
          |  | if [ "$ACM_CERTIFICATE_STATUS" = "ISSUED" ]; then | 
        
          |  | GREP_GREEN="1;32" | 
        
          |  | echo "$ACM_CERTIFICATE" | GREP_COLOR="$GREP_GREEN" grep --color -E "\"Status\": \"${ACM_CERTIFICATE_STATUS}\"|$" | 
        
          |  | else | 
        
          |  | GREP_RED="1;31" | 
        
          |  | echo "$ACM_CERTIFICATE" | GREP_COLOR="$GREP_RED" grep --color -E "\"Status\": \"${ACM_CERTIFICATE_STATUS}\"|$" | 
        
          |  | fi |