Scripts
Explore the scripts that power F5G.pro with this GitHub-inspired file browser.
setup-all.sh
This is the main script that orchestrates the entire setup process.
#!/bin/bash
# Exit on error
set -e
echo "๐ Starting F5G.pro infrastructure setup..."
# Make scripts executable
chmod +x scripts/*.sh
# Run setup scripts in order
./scripts/setup-s3.sh
echo ""
./scripts/setup-iam.sh
echo ""
./scripts/setup-cloudfront.sh
echo ""
echo "๐ Setup complete!"
echo ""
echo "๐ Next steps:"
echo "1. Add the following secrets to your GitHub repository:"
echo " - AWS_ACCESS_KEY_ID"
echo " - AWS_SECRET_ACCESS_KEY"
echo " - S3_BUCKET (set to 'f5g.pro')"
echo " - CLOUDFRONT_DISTRIBUTION_ID"
echo ""
echo "2. Set up your DNS records to point to your CloudFront distribution"
echo "3. Push your code to GitHub to trigger the first deployment"
fix-cloudfront-cache.sh
This script fixes caching issues by enabling compression and updating the cache policy to include query parameters.
#!/bin/bash
# Exit on error
set -e
echo "โ๏ธ Updating CloudFront distribution to fix caching issues..."
# Get the distribution ID
DISTRIBUTION_ID=$(aws cloudfront list-distributions --query "DistributionList.Items[?Origins.Items[0].DomainName=='f5g.pro.s3.amazonaws.com'].Id" --output text)
if [ -z "$DISTRIBUTION_ID" ]; then
echo "โ Error: CloudFront distribution for f5g.pro not found!"
exit 1
fi
echo "๐ Found CloudFront distribution with ID: $DISTRIBUTION_ID"
# Get the current distribution configuration
echo "๐ฅ Retrieving current configuration..."
aws cloudfront get-distribution-config --id $DISTRIBUTION_ID --output json > distribution-config-old.json
# Extract the ETag value (needed for update)
ETAG=$(grep -o '"ETag"[[:space:]]*:[[:space:]]*"[^"]*"' distribution-config-old.json | sed 's/"ETag"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/')
# Extract just the DistributionConfig portion
jq '.DistributionConfig' distribution-config-old.json > distribution-config-extracted.json
# Enable compression
jq '.DefaultCacheBehavior.Compress = true' distribution-config-extracted.json > distribution-config-compression.json
# Change cache policy to "CachingOptimizedForUncompressedObjects" which includes query strings
# Policy ID: b2884449-e4de-46a7-ac36-70bc7f1ddd6d
jq '.DefaultCacheBehavior.CachePolicyId = "b2884449-e4de-46a7-ac36-70bc7f1ddd6d"' distribution-config-compression.json > distribution-config-new.json
echo "๐ Updating distribution with fixed caching settings..."
aws cloudfront update-distribution --id $DISTRIBUTION_ID --if-match $ETAG --distribution-config file://distribution-config-new.json > /dev/null
echo "๐งน Cleaning up temporary files..."
rm distribution-config-old.json distribution-config-extracted.json distribution-config-compression.json distribution-config-new.json
echo "โ
CloudFront distribution updated with optimal caching settings!"
echo "โฑ๏ธ It may take up to 15-30 minutes for the changes to propagate across all edge locations."
echo "๐ After the propagation is complete, your content will be properly cached by CloudFront."
echo "๐ The changes made:"
echo " - Enabled compression"
echo " - Changed cache policy to include query strings in the cache key"
echo " - This ensures cache busting with query parameters works correctly"
invalidate-cloudfront-cache.sh
This script invalidates the CloudFront cache after deployments.
#!/bin/bash
# Exit on error
set -e
echo "โ๏ธ Invalidating CloudFront distribution cache..."
# Get the distribution ID
DISTRIBUTION_ID=$(aws cloudfront list-distributions --query "DistributionList.Items[?Origins.Items[0].DomainName=='f5g.pro.s3.amazonaws.com'].Id" --output text)
if [ -z "$DISTRIBUTION_ID" ]; then
echo "โ Error: CloudFront distribution for f5g.pro not found!"
exit 1
fi
echo "๐ Found CloudFront distribution with ID: $DISTRIBUTION_ID"
# Create a timestamp for the reference ID
TIMESTAMP=$(date +%Y%m%d%H%M%S)
# Paths to invalidate - '/*' invalidates everything
PATHS_TO_INVALIDATE='/*'
echo "๐ Creating cache invalidation for paths: $PATHS_TO_INVALIDATE"
INVALIDATION_ID=$(aws cloudfront create-invalidation \
--distribution-id $DISTRIBUTION_ID \
--paths "$PATHS_TO_INVALIDATE" \
--caller-reference "deploy-$TIMESTAMP" \
--query 'Invalidation.Id' \
--output text)
echo "โ
Invalidation created with ID: $INVALIDATION_ID"
echo "โฑ๏ธ Invalidation in progress. This may take 5-15 minutes to complete across all edge locations."
echo "๐ After the invalidation is complete, all users will see the latest version of your website."
setup-cloudfront.sh
This script creates and configures the CloudFront distribution for the website.
#!/bin/bash
# Exit on error
set -e
echo "โ๏ธ Setting up CloudFront distribution..."
# Check if distribution already exists for f5g.pro
EXISTING_DIST_ID=$(aws cloudfront list-distributions --query "DistributionList.Items[?Origins.Items[0].DomainName=='f5g.pro.s3.amazonaws.com'].Id" --output text)
if [ ! -z "$EXISTING_DIST_ID" ]; then
echo "โ๏ธ CloudFront distribution already exists with ID: $EXISTING_DIST_ID"
DISTRIBUTION_ID=$EXISTING_DIST_ID
else
# Create a temporary JSON file for the distribution config
cat > distribution-config.json << EOF
{
"CallerReference": "$(date +%s)",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "S3-f5g.pro",
"DomainName": "f5g.pro.s3.amazonaws.com",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "S3-f5g.pro",
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"AllowedMethods": {
"Quantity": 2,
"Items": ["HEAD", "GET"],
"CachedMethods": {
"Quantity": 2,
"Items": ["HEAD", "GET"]
}
}
},
"Comment": "F5G.pro website distribution",
"Enabled": true,
"DefaultRootObject": "index.html"
}
EOF
# Create CloudFront distribution
echo "๐ Creating CloudFront distribution..."
DISTRIBUTION_ID=$(aws cloudfront create-distribution \
--distribution-config file://distribution-config.json \
--query 'Distribution.Id' \
--output text)
# Clean up the temporary file
rm distribution-config.json
fi
echo "โ
CloudFront distribution ID: $DISTRIBUTION_ID"
echo "๐ Please save this Distribution ID for your GitHub secret CLOUDFRONT_DISTRIBUTION_ID"
# Get and display the distribution domain name
DOMAIN_NAME=$(aws cloudfront get-distribution --id $DISTRIBUTION_ID --query 'Distribution.DomainName' --output text)
echo "๐ CloudFront Domain Name: $DOMAIN_NAME"
echo "๐ Update your DNS records to point f5g.pro to this domain name"
setup-counter.sh
This script sets up a visitor counter using S3, Lambda, and API Gateway.
#!/bin/bash
# Exit on error
set -e
echo "๐ข Setting up visitor counter for f5g.pro..."
# Define variables
BUCKET_NAME="f5g.pro"
COUNTER_FILE="counter.json"
LAMBDA_FUNCTION_NAME="f5gVisitorCounter"
API_NAME="F5GCounterAPI"
API_STAGE="prod"
REGION="us-east-1"
LAMBDA_SOURCE="/Users/myleshenderson/src/f5g/lambda/visitor-counter.js"
# Check if counter file exists
echo "๐ Checking if counter file exists..."
if aws s3api head-object --bucket "$BUCKET_NAME" --key "$COUNTER_FILE" >/dev/null 2>&1; then
echo "๐ Counter file already exists"
else
echo "๐ Creating counter file in S3..."
echo '{"count": 0}' > /tmp/counter.json
aws s3 cp /tmp/counter.json "s3://$BUCKET_NAME/$COUNTER_FILE"
rm /tmp/counter.json
fi
# Check if IAM role exists
ROLE_NAME="F5GCounterLambdaRole"
echo "๐ค Checking if IAM role exists..."
if aws iam get-role --role-name "$ROLE_NAME" >/dev/null 2>&1; then
echo "๐ค Role $ROLE_NAME already exists"
ROLE_ARN=$(aws iam get-role --role-name "$ROLE_NAME" --query "Role.Arn" --output text)
else
echo "๐ค Creating IAM role..."
# Create trust policy document
cat > /tmp/trust-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
# Create role
ROLE_ARN=$(aws iam create-role --role-name "$ROLE_NAME" --assume-role-policy-document file:///tmp/trust-policy.json --query "Role.Arn" --output text)
# Create policy document for S3 access
cat > /tmp/s3-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::$BUCKET_NAME/$COUNTER_FILE"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
EOF
# Create and attach policy
POLICY_NAME="F5GCounterS3Access"
POLICY_ARN=$(aws iam create-policy --policy-name "$POLICY_NAME" --policy-document file:///tmp/s3-policy.json --query "Policy.Arn" --output text)
aws iam attach-role-policy --role-name "$ROLE_NAME" --policy-arn "$POLICY_ARN"
# Cleanup temp files
rm /tmp/trust-policy.json /tmp/s3-policy.json
# Wait for IAM role propagation
echo "โณ Waiting for IAM role propagation..."
sleep 10
fi
# Check if Lambda function exists and create/update as needed
echo "ฮป๏ธ Checking Lambda function..."
if aws lambda get-function --function-name "$LAMBDA_FUNCTION_NAME" >/dev/null 2>&1; then
echo "ฮป๏ธ Lambda function $LAMBDA_FUNCTION_NAME exists, updating code..."
# Create temp directory for zip
mkdir -p /tmp/lambda
cp "$LAMBDA_SOURCE" /tmp/lambda/index.js
# Install AWS SDK dependencies
cd /tmp/lambda
npm init -y >/dev/null 2>&1
npm install @aws-sdk/client-s3 --save >/dev/null 2>&1
# Create zip file
zip -r function.zip index.js node_modules >/dev/null
# Update Lambda function code
aws lambda update-function-code \
--function-name "$LAMBDA_FUNCTION_NAME" \
--zip-file fileb://function.zip
# Update environment variables
aws lambda update-function-configuration \
--function-name "$LAMBDA_FUNCTION_NAME" \
--environment "Variables={BUCKET_NAME=$BUCKET_NAME,COUNTER_FILE=$COUNTER_FILE}"
# Cleanup
cd -
rm -rf /tmp/lambda
else
echo "ฮป๏ธ Creating Lambda function..."
# Create temp directory for zip
mkdir -p /tmp/lambda
cp "$LAMBDA_SOURCE" /tmp/lambda/index.js
# Install AWS SDK dependencies
cd /tmp/lambda
npm init -y >/dev/null 2>&1
npm install @aws-sdk/client-s3 --save >/dev/null 2>&1
# Create zip file
zip -r function.zip index.js node_modules >/dev/null
# Create Lambda function
aws lambda create-function \
--function-name "$LAMBDA_FUNCTION_NAME" \
--runtime nodejs18.x \
--role "$ROLE_ARN" \
--handler index.handler \
--zip-file fileb://function.zip \
--environment "Variables={BUCKET_NAME=$BUCKET_NAME,COUNTER_FILE=$COUNTER_FILE}"
# Cleanup
cd -
rm -rf /tmp/lambda
fi
# Check if API Gateway exists
echo "๐ Checking if API Gateway exists..."
API_ID=$(aws apigateway get-rest-apis --query "items[?name=='$API_NAME'].id" --output text)
if [ -n "$API_ID" ]; then
echo "๐ API Gateway $API_NAME already exists with ID: $API_ID"
else
echo "๐ Creating API Gateway..."
API_ID=$(aws apigateway create-rest-api --name "$API_NAME" --query "id" --output text)
ROOT_RESOURCE_ID=$(aws apigateway get-resources --rest-api-id "$API_ID" --query "items[0].id" --output text)
# Create a resource
echo "๐ Creating API resource..."
RESOURCE_ID=$(aws apigateway create-resource --rest-api-id "$API_ID" --parent-id "$ROOT_RESOURCE_ID" --path-part "increment" --query "id" --output text)
# Create method
echo "๐ Creating API method..."
aws apigateway put-method --rest-api-id "$API_ID" --resource-id "$RESOURCE_ID" --http-method GET --authorization-type NONE
# Set Lambda integration
echo "๐ Setting up Lambda integration..."
LAMBDA_ARN="arn:aws:lambda:$REGION:$(aws sts get-caller-identity --query Account --output text):function:$LAMBDA_FUNCTION_NAME"
aws apigateway put-integration \
--rest-api-id "$API_ID" \
--resource-id "$RESOURCE_ID" \
--http-method GET \
--type AWS_PROXY \
--integration-http-method POST \
--uri "arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/$LAMBDA_ARN/invocations"
# Deploy API
echo "๐ Deploying API..."
aws apigateway create-deployment --rest-api-id "$API_ID" --stage-name "$API_STAGE"
# Set Lambda permission for API Gateway
echo "ฮป๏ธ Setting Lambda permissions for API Gateway..."
aws lambda add-permission \
--function-name "$LAMBDA_FUNCTION_NAME" \
--statement-id apigateway \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:$REGION:$(aws sts get-caller-identity --query Account --output text):$API_ID/*/*/increment"
fi
# Create API URL
API_URL="https://$API_ID.execute-api.$REGION.amazonaws.com/$API_STAGE/increment"
# Create a code snippet file
echo "๐ Creating HTML code snippet file..."
cat > /Users/myleshenderson/src/f5g/counter-snippet.html <<EOF
<!-- Visitor Counter -->
<div class="visitor-counter">
<p>Visitor count: <span id="visitor-count">Loading...</span></p>
<script>
// Increment counter on page load
fetch('$API_URL')
.then(response => response.json())
.then(data => {
document.getElementById('visitor-count').textContent = data.count;
})
.catch(error => console.error('Error updating counter:', error));
</script>
</div>
EOF
echo "โ
Counter setup complete!"
echo "๐ API URL: $API_URL"
echo "๐ HTML snippet created at: /Users/myleshenderson/src/f5g/counter-snippet.html"
echo "๐ Add the HTML snippet to your homepage to display the counter"
setup-iam.sh
This script sets up the IAM user and permissions for deployment.
#!/bin/bash
# Exit on error
set -e
echo "๐ค Setting up IAM user and permissions..."
# Check if user exists
if aws iam get-user --user-name f5g-pro-deployer >/dev/null 2>&1; then
echo "๐ค User f5g-pro-deployer already exists"
else
echo "๐ค Creating IAM user..."
aws iam create-user --user-name f5g-pro-deployer
fi
# Create the policy document
echo "๐ Creating policy document..."
cat > policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::f5g.pro",
"arn:aws:s3:::f5g.pro/*"
]
},
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation"
],
"Resource": "*"
}
]
}
EOF
# Check if policy exists
POLICY_ARN="arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):policy/f5g-pro-deploy-policy"
if aws iam get-policy --policy-arn "$POLICY_ARN" >/dev/null 2>&1; then
echo "๐ Policy f5g-pro-deploy-policy already exists"
else
echo "๐ Creating IAM policy..."
aws iam create-policy --policy-name f5g-pro-deploy-policy --policy-document file://policy.json
fi
# Attach the policy to the user if not already attached
echo "๐ Checking policy attachment..."
if aws iam list-attached-user-policies --user-name f5g-pro-deployer | grep -q "$POLICY_ARN"; then
echo "๐ Policy already attached to user"
else
echo "๐ Attaching policy to user..."
aws iam attach-user-policy --user-name f5g-pro-deployer --policy-arn "$POLICY_ARN"
fi
# List existing access keys
echo "๐ Listing existing access keys..."
aws iam list-access-keys --user-name f5g-pro-deployer
echo "โน๏ธ If you need a new access key, please delete one of the existing keys first:"
echo " aws iam delete-access-key --user-name f5g-pro-deployer --access-key-id ACCESS_KEY_ID"
echo " Then run this script again to create a new key."
# Clean up
rm policy.json
echo "โ
IAM setup complete!"
echo "๐ Please save the Access Key ID and Secret Access Key for GitHub secrets!"
setup-route53.sh
This script configures Route 53 DNS records for the domain.
#!/bin/bash
# Exit on error
set -e
# Load environment variables
source .env
# Check if domain name is set
if [ -z "$DOMAIN_NAME" ]; then
echo "Error: DOMAIN_NAME is not set in .env file"
exit 1
fi
echo "Setting up Route 53 configuration for domain: $DOMAIN_NAME"
# Check if hosted zone already exists
echo "Checking for existing hosted zone..."
EXISTING_ZONE=$(aws route53 list-hosted-zones-by-name --dns-name $DOMAIN_NAME --query "HostedZones[?Name=='$DOMAIN_NAME.']" --output text)
if [ -z "$EXISTING_ZONE" ]; then
echo "Creating new hosted zone for $DOMAIN_NAME..."
aws route53 create-hosted-zone \
--name $DOMAIN_NAME \
--caller-reference $(date +%s) \
--hosted-zone-config Comment="Hosted zone for $DOMAIN_NAME" \
| cat
else
echo "Hosted zone already exists for $DOMAIN_NAME"
fi
# Get the hosted zone ID
HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name $DOMAIN_NAME --query "HostedZones[0].Id" --output text | cut -d'/' -f3)
if [ -z "$HOSTED_ZONE_ID" ]; then
echo "Error: Could not retrieve hosted zone ID"
exit 1
fi
# Create DNS records
echo "Creating/updating DNS records..."
# Function to create/update DNS record
update_dns_record() {
local record_name=$1
local hosted_zone_id=$2
local cloudfront_domain=$3
echo "Updating record for $record_name..."
aws route53 change-resource-record-sets \
--hosted-zone-id $hosted_zone_id \
--change-batch '{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "'"$record_name___2___,
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "'"$cloudfront_domain___2___,
"EvaluateTargetHealth": false
}
}
}
]
}' | cat
}
# Update root domain record
update_dns_record "$DOMAIN_NAME" "$HOSTED_ZONE_ID" "$CLOUDFRONT_DOMAIN"
# Update www subdomain record
update_dns_record "www.$DOMAIN_NAME" "$HOSTED_ZONE_ID" "$CLOUDFRONT_DOMAIN"
echo "Route 53 configuration completed successfully!"
setup-s3.sh
This script creates and configures the S3 bucket for website hosting.
#!/bin/bash
# Exit on error
set -e
echo "๐ Setting up S3 bucket for f5g.pro..."
# Check if bucket exists
if aws s3api head-bucket --bucket f5g.pro 2>/dev/null; then
echo "๐ฆ Bucket f5g.pro already exists"
else
echo "๐ฆ Creating S3 bucket..."
aws s3api create-bucket --bucket f5g.pro --region us-east-1
fi
# Disable public access block settings
echo "๐ Disabling public access block settings..."
aws s3api put-public-access-block \
--bucket f5g.pro \
--public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"
# Enable static website hosting
echo "๐ Enabling static website hosting..."
aws s3 website s3://f5g.pro/ --index-document index.html
# Set the bucket policy
echo "๐ Setting bucket policy..."
aws s3api put-bucket-policy --bucket f5g.pro --policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::f5g.pro/*"
}
]
}'
echo "โ
S3 setup complete!"
setup-ssl.sh
This script requests and validates an SSL certificate for the domain.
#!/bin/bash
# Exit on error
set -e
# Load environment variables
source .env
# Check if domain name is set
if [ -z "$DOMAIN_NAME" ]; then
echo "Error: DOMAIN_NAME is not set in .env file"
exit 1
fi
echo "๐ Setting up SSL certificate for $DOMAIN_NAME..."
# Request a new certificate in us-east-1 (required for CloudFront)
echo "๐ Requesting SSL certificate..."
CERTIFICATE_ARN=$(aws acm request-certificate \
--domain-name $DOMAIN_NAME \
--subject-alternative-names "www.$DOMAIN_NAME" \
--validation-method DNS \
--region us-east-1 \
--query 'CertificateArn' \
--output text)
echo "โ
Certificate requested with ARN: $CERTIFICATE_ARN"
# Get the DNS validation records
echo "๐ Getting DNS validation records..."
VALIDATION_RECORDS=$(aws acm describe-certificate \
--certificate-arn $CERTIFICATE_ARN \
--region us-east-1 \
--query 'Certificate.DomainValidationOptions[*].[DomainName,ResourceRecord.Name,ResourceRecord.Value]' \
--output text)
# Get the hosted zone ID
HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name $DOMAIN_NAME --query "HostedZones[0].Id" --output text | cut -d'/' -f3)
# Create DNS validation records
echo "๐ Creating DNS validation records..."
while read -r domain name value; do
echo "Creating record for $domain..."
aws route53 change-resource-record-sets \
--hosted-zone-id $HOSTED_ZONE_ID \
--change-batch '{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "'"$name___2___,
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "'"$value___2___
}
]
}
}
]
}' | cat
done <<< "$VALIDATION_RECORDS"
echo "โณ Waiting for certificate validation..."
aws acm wait certificate-validated --certificate-arn $CERTIFICATE_ARN --region us-east-1
echo "โ
SSL certificate is validated and ready to use!"
echo "๐ Certificate ARN: $CERTIFICATE_ARN"
echo "๐ Please update your CloudFront distribution to use this certificate"
update-cloudfront-cache.sh
This script updates the CloudFront distribution with optimal cache settings.
#!/bin/bash
# Exit on error
set -e
echo "โ๏ธ Updating CloudFront distribution cache settings..."
# Get the distribution ID
DISTRIBUTION_ID=$(aws cloudfront list-distributions --query "DistributionList.Items[?Origins.Items[0].DomainName=='f5g.pro.s3.amazonaws.com'].Id" --output text)
if [ -z "$DISTRIBUTION_ID" ]; then
echo "โ Error: CloudFront distribution for f5g.pro not found!"
exit 1
fi
echo "๐ Found CloudFront distribution with ID: $DISTRIBUTION_ID"
# Get the current distribution configuration
echo "๐ฅ Retrieving current configuration..."
aws cloudfront get-distribution-config --id $DISTRIBUTION_ID --output json > distribution-config-old.json
# Extract the ETag value (needed for update)
ETAG=$(grep -o '"ETag"[[:space:]]*:[[:space:]]*"[^"]*"' distribution-config-old.json | sed 's/"ETag"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/')
# Extract just the DistributionConfig portion
jq '.DistributionConfig' distribution-config-old.json > distribution-config-extracted.json
# Update the cache policy ID from CachingDisabled to CachingOptimized
# CachingOptimized policy ID: 658327ea-f89d-4fab-a63d-7e88639e58f6
sed -i '' 's/"4135ea2d-6df8-44a3-9df3-4b5a84be39ad"/"658327ea-f89d-4fab-a63d-7e88639e58f6"/g' distribution-config-extracted.json
# Prepare the final configuration file
mv distribution-config-extracted.json distribution-config-new.json
echo "๐ Updating distribution with optimized caching policy..."
aws cloudfront update-distribution --id $DISTRIBUTION_ID --if-match $ETAG --distribution-config file://distribution-config-new.json > /dev/null
echo "๐งน Cleaning up temporary files..."
rm distribution-config-old.json distribution-config-new.json
echo "โ
CloudFront distribution updated with optimized caching policy!"
echo "โฑ๏ธ It may take up to 15-30 minutes for the changes to propagate across all edge locations."
echo "๐ After the propagation is complete, your content will be properly cached by CloudFront."
update-cloudfront-ssl.sh
This script updates the CloudFront distribution to use the SSL certificate.
#!/bin/bash
# Exit on error
set -e
# Load environment variables
source .env
# Check if domain name is set
if [ -z "$DOMAIN_NAME" ]; then
echo "Error: DOMAIN_NAME is not set in .env file"
exit 1
fi
echo "๐ Updating CloudFront distribution with SSL certificate..."
# Get the distribution ID
DISTRIBUTION_ID=$(aws cloudfront list-distributions --query "DistributionList.Items[?Origins.Items[0].DomainName=='$DOMAIN_NAME.s3.amazonaws.com'].Id" --output text)
if [ -z "$DISTRIBUTION_ID" ]; then
echo "Error: Could not find CloudFront distribution for $DOMAIN_NAME"
exit 1
fi
# Get the current distribution config
echo "๐ Getting current distribution configuration..."
aws cloudfront get-distribution-config --id $DISTRIBUTION_ID --query 'DistributionConfig' > config.json
# Update the config to use the custom SSL certificate
echo "๐ Updating distribution configuration..."
jq '.ViewerCertificate = {
"ACMCertificateArn": "arn:aws:acm:us-east-1:188150609925:certificate/e0ea7099-c492-4791-975d-f421f45c131e",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021"
} | .Aliases.Items = ["'"$DOMAIN_NAME___1___, "www.'"$DOMAIN_NAME___3___] | .Aliases.Quantity = 2' config.json > updated-config.json
# Update the distribution
echo "๐ Updating CloudFront distribution..."
aws cloudfront update-distribution \
--id $DISTRIBUTION_ID \
--distribution-config file://updated-config.json \
--if-match $(aws cloudfront get-distribution --id $DISTRIBUTION_ID --query 'ETag' --output text) | cat
# Clean up
rm config.json updated-config.json
echo "โ
CloudFront distribution update initiated!"
echo "โณ This may take 15-30 minutes to complete..."
echo "๐ You can check the status with: aws cloudfront get-distribution --id $DISTRIBUTION_ID"
update-counter-url.sh
This script updates the visitor counter API URL after deployment.
#!/bin/bash
# Exit on error
set -e
echo "๐ Updating Counter API URL in build script..."
# Check if API URL argument is provided
if [ -z "$1" ]; then
echo "โ Error: Please provide the Counter API URL as an argument"
echo "Usage: ./scripts/update-counter-url.sh <API_URL>"
exit 1
fi
COUNTER_API_URL="$1"
BUILD_JS_FILE="/Users/myleshenderson/src/f5g/build.js"
# Update the Counter API URL in the build.js file
echo "๐ Setting Counter API URL to: $COUNTER_API_URL"
# Use a temporary file for the replacement
cat "$BUILD_JS_FILE" | awk -v url="$COUNTER_API_URL" '{gsub(/const counterApiUrl = process.env.COUNTER_API_URL \|\| ".*";/, "const counterApiUrl = process.env.COUNTER_API_URL || \"" url "\";"); print}' > /tmp/build.js.tmp
mv /tmp/build.js.tmp "$BUILD_JS_FILE"
echo "โ
Counter API URL updated successfully!"
echo "๐จ Run 'node build.js' to rebuild the site with the new Counter API URL"