| 
 | 1 | +import {  | 
 | 2 | +  CloudFrontClient,  | 
 | 3 | +  GetDistributionCommand,  | 
 | 4 | +  UpdateDistributionCommand  | 
 | 5 | +} from '@aws-sdk/client-cloudfront'  | 
 | 6 | +import {  | 
 | 7 | +  S3Client,  | 
 | 8 | +  CreateBucketCommand,  | 
 | 9 | +  PutBucketOwnershipControlsCommand,  | 
 | 10 | +  PutBucketAclCommand,  | 
 | 11 | +  PutBucketPolicyCommand  | 
 | 12 | +} from '@aws-sdk/client-s3'  | 
 | 13 | + | 
 | 14 | +const region = process.env.AWS_REGION || 'us-west-2'  | 
 | 15 | +const accountId = '533267091967'  | 
 | 16 | +const distributionId = process.env.CF_DISTRIBUTION_ID || 'E1DLLQU8OGUHTK'  | 
 | 17 | +const logsBucket = process.env.CF_LOG_BUCKET || 'projectm-visualizer-cloudfront-logs'  | 
 | 18 | +const logsPrefix = process.env.CF_LOG_PREFIX || 'cloudfront/'  | 
 | 19 | + | 
 | 20 | +const s3 = new S3Client({ region })  | 
 | 21 | +const cf = new CloudFrontClient({ region })  | 
 | 22 | + | 
 | 23 | +async function ensureBucket() {  | 
 | 24 | +  try {  | 
 | 25 | +    await s3.send(new CreateBucketCommand({  | 
 | 26 | +      Bucket: logsBucket,  | 
 | 27 | +      CreateBucketConfiguration: { LocationConstraint: region }  | 
 | 28 | +    }))  | 
 | 29 | +    console.log(`Created S3 bucket ${logsBucket}`)  | 
 | 30 | +  } catch (error) {  | 
 | 31 | +    if (error.name === 'BucketAlreadyOwnedByYou' || error.$metadata?.httpStatusCode === 409) {  | 
 | 32 | +      console.log(`Bucket ${logsBucket} already exists`)  | 
 | 33 | +    } else {  | 
 | 34 | +      throw error  | 
 | 35 | +    }  | 
 | 36 | +  }  | 
 | 37 | + | 
 | 38 | +  try {  | 
 | 39 | +    await s3.send(new PutBucketOwnershipControlsCommand({  | 
 | 40 | +      Bucket: logsBucket,  | 
 | 41 | +      OwnershipControls: {  | 
 | 42 | +        Rules: [{ ObjectOwnership: 'ObjectWriter' }]  | 
 | 43 | +      }  | 
 | 44 | +    }))  | 
 | 45 | +    console.log('Set bucket ownership to ObjectWriter (enables ACLs)')  | 
 | 46 | +  } catch (error) {  | 
 | 47 | +    if (error.name !== 'OwnershipControlsNotFoundError') {  | 
 | 48 | +      console.warn('Unable to set ownership controls:', error.message)  | 
 | 49 | +    }  | 
 | 50 | +  }  | 
 | 51 | + | 
 | 52 | +  try {  | 
 | 53 | +    await s3.send(new PutBucketAclCommand({  | 
 | 54 | +      Bucket: logsBucket,  | 
 | 55 | +      ACL: 'log-delivery-write'  | 
 | 56 | +    }))  | 
 | 57 | +    console.log('Applied log-delivery-write ACL')  | 
 | 58 | +  } catch (error) {  | 
 | 59 | +    console.warn('Skipping ACL update:', error.message)  | 
 | 60 | +  }  | 
 | 61 | + | 
 | 62 | +  const policy = {  | 
 | 63 | +    Version: '2012-10-17',  | 
 | 64 | +    Statement: [  | 
 | 65 | +      {  | 
 | 66 | +        Effect: 'Allow',  | 
 | 67 | +        Principal: { Service: 'cloudfront.amazonaws.com' },  | 
 | 68 | +        Action: 's3:PutObject',  | 
 | 69 | +        Resource: `arn:aws:s3:::${logsBucket}/${logsPrefix}*`,  | 
 | 70 | +        Condition: {  | 
 | 71 | +          StringEquals: {  | 
 | 72 | +            'AWS:SourceArn': `arn:aws:cloudfront::${accountId}:distribution/${distributionId}`  | 
 | 73 | +          }  | 
 | 74 | +        }  | 
 | 75 | +      }  | 
 | 76 | +    ]  | 
 | 77 | +  }  | 
 | 78 | + | 
 | 79 | +  await s3.send(new PutBucketPolicyCommand({  | 
 | 80 | +    Bucket: logsBucket,  | 
 | 81 | +    Policy: JSON.stringify(policy)  | 
 | 82 | +  }))  | 
 | 83 | +  console.log(`Bucket policy set on ${logsBucket}`)  | 
 | 84 | +}  | 
 | 85 | + | 
 | 86 | +async function enableLogging() {  | 
 | 87 | +  await ensureBucket()  | 
 | 88 | + | 
 | 89 | +  const { Distribution, ETag } = await cf.send(new GetDistributionCommand({ Id: distributionId }))  | 
 | 90 | +  if (!Distribution?.DistributionConfig) {  | 
 | 91 | +    throw new Error('Distribution configuration not found')  | 
 | 92 | +  }  | 
 | 93 | + | 
 | 94 | +  const config = Distribution.DistributionConfig  | 
 | 95 | +  config.Logging = {  | 
 | 96 | +    Enabled: true,  | 
 | 97 | +    IncludeCookies: true,  | 
 | 98 | +    Bucket: `${logsBucket}.s3.amazonaws.com`,  | 
 | 99 | +    Prefix: logsPrefix  | 
 | 100 | +  }  | 
 | 101 | + | 
 | 102 | +  await cf.send(new UpdateDistributionCommand({  | 
 | 103 | +    Id: distributionId,  | 
 | 104 | +    IfMatch: ETag,  | 
 | 105 | +    DistributionConfig: config  | 
 | 106 | +  }))  | 
 | 107 | + | 
 | 108 | +  console.log('CloudFront logging enabled for distribution', distributionId)  | 
 | 109 | +}  | 
 | 110 | + | 
 | 111 | +enableLogging().catch((err) => {  | 
 | 112 | +  console.error('Failed to enable CloudFront logging:', err)  | 
 | 113 | +  process.exit(1)  | 
 | 114 | +})  | 
0 commit comments