github.com/pachyderm/pachyderm@v1.13.4/etc/deploy/cloudfront/secure-cloudfront.sh (about) 1 #!/bin/bash 2 3 CLOUDFRONT_OAI_ID= 4 set -euxo pipefail 5 6 parse_flags() { 7 # Check prereqs 8 command -v aws 9 command -v jq 10 command -v uuid 11 # Common config 12 export AWS_REGION=us-east-1 13 export AWS_AVAILABILITY_ZONE=us-east-1a 14 15 # Parse flags 16 eval "set -- $( getopt -l "state:,region:,zone:,bucket:,cloudfront-distribution-id:,cloudfront-keypair-id:,cloudfront-private-key-file:" "--" "${0}" "${@}" )" 17 while true; do 18 case "${1}" in 19 --region) 20 export AWS_REGION="${2}" 21 shift 2 22 ;; 23 --zone) 24 export AWS_AVAILABILITY_ZONE="${2}" 25 shift 2 26 ;; 27 --bucket) 28 export BUCKET="${2}" 29 shift 2 30 ;; 31 --cloudfront-distribution-id) 32 export CLOUDFRONT_DISTRIBUTION_ID="${2}" 33 shift 2 34 ;; 35 --cloudfront-keypair-id) 36 export CLOUDFRONT_KEYPAIR_ID="${2}" 37 shift 2 38 ;; 39 --cloudfront-private-key-file) 40 export CLOUDFRONT_PRIVATE_KEY_FILE="${2}" 41 shift 2 42 ;; 43 --) 44 shift 45 break 46 ;; 47 esac 48 done 49 50 51 set +euxo pipefail 52 53 if [ -z "$CLOUDFRONT_KEYPAIR_ID" ]; then 54 echo "--cloudfront-keypair-id must be set" 55 exit 1 56 fi 57 58 if [ -z "$CLOUDFRONT_PRIVATE_KEY_FILE" ]; then 59 echo "--cloudfront-private-key-file must be set" 60 exit 1 61 fi 62 63 if [ -z "$BUCKET" ]; then 64 echo "--bucket must be set" 65 exit 1 66 fi 67 68 if [ -z "$CLOUDFRONT_DISTRIBUTION_ID" ]; then 69 echo "--cloudfront-distribution-id must be set" 70 exit 1 71 fi 72 73 set -euxo pipefail 74 75 echo "Region: ${AWS_REGION}" 76 zone_suffix=${AWS_AVAILABILITY_ZONE#$AWS_REGION} 77 if [[ ${#zone_suffix} -gt 3 ]]; then 78 echo "Availability zone \"${AWS_AVAILABILITY_ZONE}\" may not be in region \"${AWS_REGION}\"" 79 echo "Try setting both --region and --zone" 80 echo "Exiting to be safe..." 81 exit 1 82 fi 83 } 84 85 86 # Update bucket access policy 87 88 update_bucket_policy() { 89 aws s3api delete-bucket-policy --bucket "$BUCKET" --region "$AWS_REGION" 90 91 # Create Origin Access Identity 92 someuuid=$(uuid | cut -f 1 -d-) 93 mkdir -p tmp 94 jq ".CallerReference = \"$someuuid\" | .Comment = \"$BUCKET auto generated OAI\"" < etc/deploy/cloudfront/origin-access-identity.json.template > tmp/cloudfront-origin-access-identity.json 95 aws cloudfront create-cloud-front-origin-access-identity --cloud-front-origin-access-identity-config file://tmp/cloudfront-origin-access-identity.json > tmp/cloudfront-origin-access-identity-info.json 96 CLOUDFRONT_OAI_CANONICAL=$(jq -r ".CloudFrontOriginAccessIdentity.S3CanonicalUserId" < tmp/cloudfront-origin-access-identity-info.json) 97 echo "Got Cloudfront Origin Access Identity Canonical user id : ${CLOUDFRONT_OAI_CANONICAL}" 98 CLOUDFRONT_OAI_ID=$(jq -r ".CloudFrontOriginAccessIdentity.Id" < tmp/cloudfront-origin-access-identity-info.json) 99 echo "Got Cloudfront Origin Access Identity ID : ${CLOUDFRONT_OAI_ID}" 100 101 # Create secure bucket policy w the new OAI 102 jq ".Statement[0].Resource = \"arn:aws:s3:::$BUCKET/*\" | .Statement[0].Principal.CanonicalUser = \"$CLOUDFRONT_OAI_CANONICAL\"" < etc/deploy/cloudfront/bucket-policy-secure.json.template > tmp/bucket-policy-secure.json 103 aws s3api put-bucket-policy --bucket "$BUCKET" --policy file://tmp/bucket-policy-secure.json --region="${AWS_REGION}" 104 105 } 106 107 # Update cloudfront distribution 108 109 update_cloudfront_distribution() { 110 111 # Get the ETAG (required to update) 112 mkdir -p tmp 113 aws cloudfront get-distribution --id "$CLOUDFRONT_DISTRIBUTION_ID" > tmp/existing-cloudfront-distribution.json 114 ETAG=$(jq -r .ETag < tmp/existing-cloudfront-distribution.json) 115 # Update the fields we need 116 jq ".Distribution.DistributionConfig.Origins.Items[0].S3OriginConfig.OriginAccessIdentity = \"origin-access-identity/cloudfront/${CLOUDFRONT_OAI_ID}\"" < tmp/existing-cloudfront-distribution.json > tmp-result.json 117 # There doesn't seem to be a way to use jq to replace 'in place': 118 mv tmp-result.json tmp/updated-cloudfront-distribution.json 119 jq '.Distribution.DistributionConfig.DefaultCacheBehavior.TrustedSigners = {"Enabled": true,"Items": ["self"],"Quantity":1}' < tmp/updated-cloudfront-distribution.json > tmp-result.json 120 mv tmp-result.json tmp/updated-cloudfront-distribution.json 121 122 jq .Distribution.DistributionConfig < tmp/updated-cloudfront-distribution.json > tmp/updated-cloudfront-distribution-config.json 123 aws cloudfront update-distribution --id "$CLOUDFRONT_DISTRIBUTION_ID" --if-match "$ETAG" --distribution-config file://tmp/updated-cloudfront-distribution-config.json > tmp/updated-cloudfront-distribution-info.json 124 # This isn't used anywhere in this script, but still is good to report to the user 125 CLOUDFRONT_DOMAIN=$(jq -r ".Distribution.DomainName" < tmp/updated-cloudfront-distribution-info.json | cut -f 1 -d .) 126 echo "Setup cloudfront distribution with domain ${CLOUDFRONT_DOMAIN}" 127 } 128 129 deploy_secrets() { 130 # Update the amazon secret to include: cloudfront-keypair-id and cloudfront-private-key 131 echo "Updating secrets for cluster:" 132 kubectl cluster-info 133 mkdir -p tmp 134 kubectl get secrets/pachyderm-storage-secret -o json > tmp/existing-amazon-secrets.json 135 ENCODED_KEYPAIR=$(echo "$CLOUDFRONT_KEYPAIR_ID" | base64 -w0) 136 jq ".data.cloudfrontKeyPairId = \"$ENCODED_KEYPAIR\"" < tmp/existing-amazon-secrets.json > tmp-result.json 137 mv tmp-result.json tmp/updated-amazon-secrets.json 138 CLOUDFRONT_PRIVATE_KEY=$(base64 -w0 < "$CLOUDFRONT_PRIVATE_KEY_FILE") 139 jq ".data.cloudfrontPrivateKey = \"$CLOUDFRONT_PRIVATE_KEY\"" < tmp/updated-amazon-secrets.json > tmp-result.json 140 mv tmp-result.json tmp/updated-amazon-secrets.json 141 kubectl replace -f tmp/updated-amazon-secrets.json 142 } 143 144 parse_flags "${@}" 145 update_bucket_policy 146 update_cloudfront_distribution 147 deploy_secrets 148 149 150 echo "Waiting on distribution to enter 'deployed' state" 151 echo "This is the last step of the script ... if it times out, thats ok. Just make sure that your CF distribution's status is 'Deployed' on the UI before you run anything on pachyderm" 152 date 153 # We need to wait for this, otherwise if you try and access objects while it's 'pending' CF redirects you to S3 and it'll cache the 307 redirect responses 154 aws cloudfront wait distribution-deployed --id "$CLOUDFRONT_DISTRIBUTION_ID" 155 echo "Cloudfront distribution ($CLOUDFRONT_DISTRIBUTION_ID) deployed" 156 date 157