AWS AmazonCloudFront medium security documentation change
Summary
Enhanced CloudFront setup script with improved error handling, security validations, and resource management. Added input validation, secure permissions for temp files, encryption configurations, resource tagging, and non-interactive cleanup.
Security assessment
Changes include: 1) Public access block configuration for S3 buckets to prevent public exposure, 2) Server-side encryption enforcement for S3, 3) Strict file permissions (chmod 600/700) for sensitive files, 4) Input validation for security-critical IDs, 5) Secure credential handling through AWS validation. These directly mitigate misconfiguration risks like accidental data exposure.
Diff
diff --git a/AmazonCloudFront/latest/DeveloperGuide/example_cloudfront_GettingStarted_section.md b/AmazonCloudFront/latest/DeveloperGuide/example_cloudfront_GettingStarted_section.md index 3aaa83adf..7bbfd4ce3 100644 --- a//AmazonCloudFront/latest/DeveloperGuide/example_cloudfront_GettingStarted_section.md +++ b//AmazonCloudFront/latest/DeveloperGuide/example_cloudfront_GettingStarted_section.md @@ -38,0 +39,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + set -euo pipefail + @@ -47 +49 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "ERROR: $1" + echo "ERROR: $1" >&2 @@ -49 +51 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$BUCKET_NAME" ]; then + if [ -n "${BUCKET_NAME:-}" ]; then @@ -52 +54 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$OAC_ID" ]; then + if [ -n "${OAC_ID:-}" ]; then @@ -55 +57 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$DISTRIBUTION_ID" ]; then + if [ -n "${DISTRIBUTION_ID:-}" ]; then @@ -68 +70 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$DISTRIBUTION_ID" ]; then + if [ -n "${DISTRIBUTION_ID:-}" ]; then @@ -71,3 +73,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Get the current configuration and ETag - ETAG=$(aws cloudfront get-distribution-config --id "$DISTRIBUTION_ID" --query 'ETag' --output text) - if [ $? -ne 0 ]; then + # Get the current configuration and ETag in one call + DIST_CONFIG=$(aws cloudfront get-distribution-config --id "$DISTRIBUTION_ID" 2>/dev/null) || { @@ -75,4 +76,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - else - # Create a modified configuration with Enabled=false - aws cloudfront get-distribution-config --id "$DISTRIBUTION_ID" | \ - jq '.DistributionConfig.Enabled = false' > temp_disabled_config.json + DIST_CONFIG="" + } + + if [ -n "$DIST_CONFIG" ]; then + ETAG=$(echo "$DIST_CONFIG" | jq -r '.ETag') @@ -80 +82,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Update the distribution to disable it + # Modify and update distribution in one pipeline + if echo "$DIST_CONFIG" | jq '.DistributionConfig.Enabled = false' | \ @@ -83,2 +86,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - --distribution-config file://<(jq '.DistributionConfig' temp_disabled_config.json) \ - --if-match "$ETAG" + --distribution-config "$(cat)" \ + --if-match "$ETAG" 2>/dev/null; then @@ -86,3 +88,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ $? -ne 0 ]; then - echo "Failed to disable distribution. Continuing with cleanup..." - else @@ -90 +90,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - aws cloudfront wait distribution-deployed --id "$DISTRIBUTION_ID" + aws cloudfront wait distribution-deployed --id "$DISTRIBUTION_ID" 2>/dev/null || { + echo "Distribution deployment wait timed out. Proceeding with deletion..." + } @@ -92,4 +94,10 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Delete the distribution - ETAG=$(aws cloudfront get-distribution-config --id "$DISTRIBUTION_ID" --query 'ETag' --output text) - aws cloudfront delete-distribution --id "$DISTRIBUTION_ID" --if-match "$ETAG" - if [ $? -ne 0 ]; then + # Get fresh ETag for deletion + DIST_CONFIG=$(aws cloudfront get-distribution-config --id "$DISTRIBUTION_ID" 2>/dev/null) || { + echo "Failed to get updated config. Skipping distribution deletion..." + DIST_CONFIG="" + } + + if [ -n "$DIST_CONFIG" ]; then + ETAG=$(echo "$DIST_CONFIG" | jq -r '.ETag') + aws cloudfront delete-distribution --id "$DISTRIBUTION_ID" --if-match "$ETAG" 2>/dev/null && \ + echo "CloudFront distribution deleted." || \ @@ -97,2 +104,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - else - echo "CloudFront distribution deleted." @@ -99,0 +106,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + else + echo "Failed to disable distribution. Continuing with cleanup..." @@ -104 +112 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$OAC_ID" ]; then + if [ -n "${OAC_ID:-}" ]; then @@ -106,6 +114,9 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - OAC_ETAG=$(aws cloudfront get-origin-access-control --id "$OAC_ID" --query 'ETag' --output text 2>/dev/null) - if [ $? -ne 0 ]; then - echo "Failed to get Origin Access Control ETag. You may need to delete it manually." - else - aws cloudfront delete-origin-access-control --id "$OAC_ID" --if-match "$OAC_ETAG" - if [ $? -ne 0 ]; then + OAC_DATA=$(aws cloudfront get-origin-access-control --id "$OAC_ID" 2>/dev/null) || { + echo "Failed to get Origin Access Control. You may need to delete it manually." + OAC_DATA="" + } + + if [ -n "$OAC_DATA" ]; then + OAC_ETAG=$(echo "$OAC_DATA" | jq -r '.ETag') + aws cloudfront delete-origin-access-control --id "$OAC_ID" --if-match "$OAC_ETAG" 2>/dev/null && \ + echo "Origin Access Control deleted." || \ @@ -113,3 +123,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - else - echo "Origin Access Control deleted." - fi @@ -119 +127 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$BUCKET_NAME" ]; then + if [ -n "${BUCKET_NAME:-}" ] && [ "$BUCKET_IS_SHARED" != "true" ]; then @@ -121,2 +129 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - aws s3 rm "s3://$BUCKET_NAME" --recursive - if [ $? -ne 0 ]; then + aws s3 rm "s3://$BUCKET_NAME" --recursive 2>/dev/null || { @@ -124 +131 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - fi + } @@ -126,2 +133,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - aws s3 rb "s3://$BUCKET_NAME" - if [ $? -ne 0 ]; then + aws s3 rb "s3://$BUCKET_NAME" 2>/dev/null && \ + echo "S3 bucket deleted." || \ @@ -129,3 +135,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - else - echo "S3 bucket deleted." - fi @@ -135,2 +139,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - rm -f temp_disabled_config.json - rm -rf temp_content + rm -f temp_disabled_config.json distribution-config.json bucket-policy.json 2>/dev/null || true + rm -rf temp_content 2>/dev/null || true @@ -139 +143,25 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Generate a random identifier for the bucket name + # Trap errors and cleanup + trap 'handle_error "Script interrupted"' INT TERM + + # Validate AWS CLI is available + if ! command -v aws &> /dev/null; then + handle_error "AWS CLI is not installed or not in PATH" + fi + + # Validate jq is available + if ! command -v jq &> /dev/null; then + handle_error "jq is not installed or not in PATH" + fi + + # Validate AWS credentials are configured + if ! aws sts get-caller-identity &> /dev/null; then + handle_error "AWS credentials are not configured or invalid" + fi + + # Initialize variables + BUCKET_NAME="" + OAC_ID="" + DISTRIBUTION_ID="" + BUCKET_IS_SHARED=false + + # Generate a random identifier for the bucket name using secure random @@ -141 +169,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Check for shared prereq bucket + if [ -z "$RANDOM_ID" ]; then + handle_error "Failed to generate random identifier" + fi + + # Check for shared prereq bucket and get account ID in parallel calls @@ -143 +175,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' --output text 2>/dev/null) + --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' --output text 2>/dev/null) || PREREQ_BUCKET="" + @@ -154 +187,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Create a temporary directory for content + # Get AWS account ID early + ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) + if [ $? -ne 0 ]; then + handle_error "Failed to get AWS account ID" + fi + + # Validate account ID format + if ! [[ "$ACCOUNT_ID" =~ ^[0-9]{12}$ ]]; then + handle_error "Invalid AWS account ID format: $ACCOUNT_ID" + fi + + # Create a temporary directory for content with restrictive permissions @@ -156,0 +201 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + chmod 700 "$TEMP_DIR" @@ -161 +206,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Step 1: Create an S3 bucket + # Step 1: Create an S3 bucket (only if not shared) + if [ "$BUCKET_IS_SHARED" != "true" ]; then @@ -163 +209 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - aws s3 mb "s3://$BUCKET_NAME" + aws s3 mb "s3://$BUCKET_NAME" --region us-east-1 @@ -167,0 +214,21 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + aws s3api put-bucket-tagging --bucket "$BUCKET_NAME" --tagging 'TagSet=[{Key=project,Value=doc-smith},{Key=tutorial,Value=cloudfront-gettingstarted}]' + + # Batch bucket configuration calls for efficiency + aws s3api put-bucket-versioning --bucket "$BUCKET_NAME" --versioning-configuration Status=Enabled & + aws s3api put-public-access-block \ + --bucket "$BUCKET_NAME" \ + --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true" & + aws s3api put-bucket-encryption \ + --bucket "$BUCKET_NAME" \ + --server-side-encryption-configuration '{ + "Rules": [ + { + "ApplyServerSideEncryptionByDefault": { + "SSEAlgorithm": "AES256"