Skip to content

Commit 6245192

Browse files
chore: wip
1 parent 4a9ba01 commit 6245192

2 files changed

Lines changed: 62 additions & 55 deletions

File tree

packages/ts-cloud/src/deploy/static-site-external-dns.ts

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -423,32 +423,9 @@ export async function deployStaticSiteWithExternalDns(
423423
const s3 = new S3Client(region)
424424
const cloudfront = new CloudFrontClient()
425425

426-
// Check if S3 bucket exists (orphaned from previous deployment)
427-
try {
428-
const headResult = await s3.headBucket(bucket)
429-
if (headResult.exists) {
430-
console.log(`Found orphaned S3 bucket ${bucket}, cleaning up...`)
431-
try {
432-
const cleanupPromise = s3.emptyBucket(bucket).then(() => s3.deleteBucket(bucket))
433-
const timeoutPromise = new Promise<never>((_, reject) =>
434-
setTimeout(() => reject(new Error('Bucket cleanup timeout')), 30000),
435-
)
436-
await Promise.race([cleanupPromise, timeoutPromise])
437-
console.log(`Deleted orphaned S3 bucket ${bucket}`)
438-
}
439-
catch (cleanupErr: any) {
440-
console.log(`Note: Could not clean up S3 bucket: ${cleanupErr.message}`)
441-
const suffix = Date.now().toString(36)
442-
finalBucket = `${bucket}-${suffix}`
443-
console.log(`Using alternative bucket name: ${finalBucket}`)
444-
}
445-
}
446-
}
447-
catch {
448-
// Bucket doesn't exist, good
449-
}
450-
451-
// Check for existing CloudFront distributions with our domain
426+
// Check for existing CloudFront distributions with our domain FIRST
427+
// before deciding to clean up any "orphaned" buckets
428+
let hasExistingDistribution = false
452429
if (domain) {
453430
try {
454431
console.log(`Checking for existing CloudFront distributions with alias ${domain}...`)
@@ -470,6 +447,7 @@ export async function deployStaticSiteWithExternalDns(
470447
}
471448
}
472449
if (aliases.includes(domain)) {
450+
hasExistingDistribution = true
473451
console.log(`Found existing CloudFront distribution ${dist.Id} with alias ${domain}`)
474452
console.log(`Reusing existing infrastructure for updates...`)
475453

@@ -524,6 +502,33 @@ export async function deployStaticSiteWithExternalDns(
524502
// No distributions or error listing them
525503
}
526504
}
505+
506+
// Only clean up orphaned S3 buckets when no CloudFront distribution references them
507+
if (!hasExistingDistribution) {
508+
try {
509+
const headResult = await s3.headBucket(bucket)
510+
if (headResult.exists) {
511+
console.log(`Found orphaned S3 bucket ${bucket}, cleaning up...`)
512+
try {
513+
const cleanupPromise = s3.emptyBucket(bucket).then(() => s3.deleteBucket(bucket))
514+
const timeoutPromise = new Promise<never>((_, reject) =>
515+
setTimeout(() => reject(new Error('Bucket cleanup timeout')), 30000),
516+
)
517+
await Promise.race([cleanupPromise, timeoutPromise])
518+
console.log(`Deleted orphaned S3 bucket ${bucket}`)
519+
}
520+
catch (cleanupErr: any) {
521+
console.log(`Note: Could not clean up S3 bucket: ${cleanupErr.message}`)
522+
const suffix = Date.now().toString(36)
523+
finalBucket = `${bucket}-${suffix}`
524+
console.log(`Using alternative bucket name: ${finalBucket}`)
525+
}
526+
}
527+
}
528+
catch {
529+
// Bucket doesn't exist, good
530+
}
531+
}
527532
}
528533

529534
// Generate CloudFormation template (without Route53)

packages/ts-cloud/src/deploy/static-site.ts

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -459,35 +459,9 @@ export async function deployStaticSite(config: StaticSiteConfig): Promise<Deploy
459459
const s3 = new S3Client(region)
460460
const cloudfront = new CloudFrontClient()
461461

462-
// Check if S3 bucket exists (orphaned from previous non-CloudFormation deployment)
463-
let bucketCleanedUp = false
464-
try {
465-
const headResult = await s3.headBucket(bucket)
466-
if (headResult.exists) {
467-
// Bucket exists without a stack - try to clean it up with timeout
468-
console.log(`Found orphaned S3 bucket ${bucket}, cleaning up...`)
469-
try {
470-
// Timeout for bucket cleanup (30 seconds)
471-
const cleanupPromise = s3.emptyBucket(bucket).then(() => s3.deleteBucket(bucket))
472-
const timeoutPromise = new Promise<never>((_, reject) =>
473-
setTimeout(() => reject(new Error('Bucket cleanup timeout')), 30000),
474-
)
475-
await Promise.race([cleanupPromise, timeoutPromise])
476-
console.log(`Deleted orphaned S3 bucket ${bucket}`)
477-
bucketCleanedUp = true
478-
}
479-
catch (cleanupErr: any) {
480-
console.log(`Note: Could not clean up S3 bucket: ${cleanupErr.message}`)
481-
// If we can't clean up the bucket, use a unique suffix
482-
const suffix = Date.now().toString(36)
483-
finalBucket = `${bucket}-${suffix}`
484-
console.log(`Using alternative bucket name: ${finalBucket}`)
485-
}
486-
}
487-
}
488-
catch {
489-
// Bucket doesn't exist, good
490-
}
462+
// Check for existing CloudFront distribution FIRST before cleaning up any "orphaned" buckets
463+
// This prevents deleting buckets that are actively used by a CloudFront distribution
464+
let hasExistingDistribution = false
491465

492466
// Check for existing CloudFront distribution that WE created for this domain
493467
// Only reuse distributions that have our domain as an alias - NEVER use other projects' resources
@@ -517,6 +491,7 @@ export async function deployStaticSite(config: StaticSiteConfig): Promise<Deploy
517491

518492
// Only use distribution if it has OUR domain as an alias
519493
if (aliases.includes(domain)) {
494+
hasExistingDistribution = true
520495
console.log(`Found existing CloudFront distribution ${dist.Id} for ${domain}`)
521496

522497
// Get the origin bucket from the distribution
@@ -631,6 +606,33 @@ export async function deployStaticSite(config: StaticSiteConfig): Promise<Deploy
631606
}
632607
}
633608
}
609+
610+
// Only clean up orphaned S3 buckets when no CloudFront distribution references them
611+
if (!hasExistingDistribution) {
612+
try {
613+
const headResult = await s3.headBucket(bucket)
614+
if (headResult.exists) {
615+
console.log(`Found orphaned S3 bucket ${bucket}, cleaning up...`)
616+
try {
617+
const cleanupPromise = s3.emptyBucket(bucket).then(() => s3.deleteBucket(bucket))
618+
const timeoutPromise = new Promise<never>((_, reject) =>
619+
setTimeout(() => reject(new Error('Bucket cleanup timeout')), 30000),
620+
)
621+
await Promise.race([cleanupPromise, timeoutPromise])
622+
console.log(`Deleted orphaned S3 bucket ${bucket}`)
623+
}
624+
catch (cleanupErr: any) {
625+
console.log(`Note: Could not clean up S3 bucket: ${cleanupErr.message}`)
626+
const suffix = Date.now().toString(36)
627+
finalBucket = `${bucket}-${suffix}`
628+
console.log(`Using alternative bucket name: ${finalBucket}`)
629+
}
630+
}
631+
}
632+
catch {
633+
// Bucket doesn't exist, good
634+
}
635+
}
634636
}
635637

636638
// Generate CloudFormation template with final bucket name

0 commit comments

Comments
 (0)