Skip to content

feat(s3-legacy): use param store to retrieve attachment bucket name#1779

Open
benjaminpaige wants to merge 2 commits intomainfrom
s3-legacy
Open

feat(s3-legacy): use param store to retrieve attachment bucket name#1779
benjaminpaige wants to merge 2 commits intomainfrom
s3-legacy

Conversation

@benjaminpaige
Copy link
Copy Markdown
Collaborator

Implement Shared Attachment Bucket Strategy with SSM Parameter Store Configuration

Overview

This PR implements a shared attachment bucket strategy to optimize resource usage and simplify infrastructure management for the MacPro-MAKO application. The change moves bucket name configuration from hardcoded construction to SSM Parameter Store and introduces intelligent environment-based bucket sharing for ephemeral development branches.

Problem

The previous implementation had several limitations:

  1. Resource Proliferation: Every ephemeral development branch created its own S3 bucket, leading to:

    • Unnecessary AWS resource consumption
    • Increased costs for short-lived environments
    • Management overhead tracking and cleaning up orphaned buckets
  2. Configuration Rigidity: Bucket names were constructed dynamically using a pattern (${project}-${stage}-attachments-${accountId}), making it:

    • Difficult to manage bucket lifecycle independently from stack lifecycle
    • Impossible to preserve buckets across stack recreations
    • Challenging to implement bucket sharing strategies
  3. Migration Complexity: As part of the larger cross-account bucket migration effort, the hardcoded naming prevented flexible bucket reassignment and fallback strategies.

Solution

This PR introduces a centralized configuration approach with environment-aware bucket management:

1. SSM Parameter Store Configuration

Bucket names are now loaded from AWS Systems Manager Parameter Store with the following hierarchy:

  • Stage-specific: /{project}/{stage}/attachmentsBucketName (for permanent environments)
  • Fallback: /{project}/main/attachmentsBucketName (for ephemeral branches)

2. Environment-Based Bucket Strategy

Permanent Environments (main, val, production):

  • Create dedicated S3 buckets with proper lifecycle management
  • Apply RETAIN removal policy to preserve data on stack deletion
  • Configure comprehensive security policies (encryption, block public access, virus scanning)
  • Enable versioning for data protection

Development/Ephemeral Environments:

  • Import and share the main environment's bucket by name
  • Avoid creating separate buckets for short-lived branches
  • Reduced infrastructure overhead and cleanup requirements

3. Graceful Fallback Logic

For ephemeral branches without stage-specific SSM parameters:

  • Automatically fall back to main bucket configuration
  • Log the fallback for operational visibility
  • Enable seamless development environment provisioning

Changes Made

Configuration Layer (lib/config/deployment-config.ts)

  • ✅ Added attachmentsBucketName property to InjectedConfigProperties interface
  • ✅ Implemented loadBucketName() method with SSM Parameter Store integration
  • ✅ Added fallback logic for ephemeral environments to use main bucket
  • ✅ Integrated bucket name into configuration validation checks
  • ✅ Added AWS SSM SDK client dependency

Infrastructure Layer (lib/stacks/parent.ts)

  • ✅ Pass attachmentsBucketName from configuration to uploads stack

Uploads Stack (lib/stacks/uploads.ts)

  • ✅ Accept attachmentsBucketName as stack property
  • ✅ Implement conditional bucket creation logic:
    • Non-dev: Create new bucket with security hardening and RETAIN policy
    • Dev: Import existing bucket by name
  • ✅ Apply security policies (insecure request denial, virus scan validation) only to managed buckets
  • ✅ Maintain backward compatibility with ClamAV scanner integration
  • ✅ Remove dynamic bucket naming construction

Modified Files

lib/config/deployment-config.ts
lib/stacks/parent.ts
lib/stacks/uploads.ts

Technical Details

SSM Parameter Store Schema

/{project}/{stage}/attachmentsBucketName

Example Values:

  • /mako/main/attachmentsBucketNamemako-main-attachments-116229642442
  • /mako/val/attachmentsBucketNamemako-val-attachments-116229642442
  • /mako/production/attachmentsBucketNamemako-production-attachments-116229642442

Bucket Creation vs Import Logic

Non-Dev Environments (isDev: false):

const attachmentsBucket = new cdk.aws_s3.Bucket(this, "AttachmentsBucket", {
  bucketName: attachmentsBucketName,
  versioned: true,
  encryption: cdk.aws_s3.BucketEncryption.S3_MANAGED,
  removalPolicy: cdk.RemovalPolicy.RETAIN,
  autoDeleteObjects: false,
  // ... security configurations
});

Dev Environments (isDev: true):

const attachmentsBucket = cdk.aws_s3.Bucket.fromBucketName(
  this,
  "AttachmentsBucket",
  attachmentsBucketName,
) as cdk.aws_s3.Bucket;

Security Posture

The following security controls remain enforced for all created buckets:

  • ✅ S3-managed encryption at rest
  • ✅ Block all public access
  • ✅ Versioning enabled
  • ✅ Insecure request denial (HTTPS enforcement)
  • ✅ ClamAV virus scanning integration
  • ✅ Virus-tagged object access denial

Imported buckets (dev environments) rely on manually configured policies from the main bucket.

Deployment Considerations

Prerequisites:

  1. SSM parameters must be created before stack deployment:

    aws ssm put-parameter \
      --name "/mako/{stage}/attachmentsBucketName" \
      --value "mako-{stage}-attachments-{accountId}" \
      --type "String" \
      --region us-east-1
  2. For ephemeral branches, no parameter is required (automatic fallback to main)

Migration Path:

  • Existing permanent environment stacks can be updated in place
  • CDK will recognize existing buckets by name and import them
  • No data migration required for this change
  • Ephemeral branches will transition to shared bucket on next deployment

Testing Strategy

  • ✅ Verify SSM parameter retrieval for permanent environments
  • ✅ Confirm fallback logic for ephemeral branches
  • ✅ Test bucket creation for new permanent environments
  • ✅ Validate bucket import for dev environments
  • ✅ Ensure virus scanning continues to function
  • ✅ Verify CORS and security policies are properly applied

Related Documentation (these documents can be found in the jira work item)

  • See ATTACHMENT_BUCKET_MIGRATION.md for broader migration context
  • See ATTACHMENT_BUCKET_MIGRATION_RUNBOOK.md for operational procedures

Benefits

  1. Cost Optimization: Eliminates unnecessary S3 buckets for ephemeral branches
  2. Operational Simplicity: Centralized bucket configuration via SSM Parameter Store
  3. Data Safety: RETAIN policies prevent accidental data loss
  4. Flexibility: SSM-based configuration enables easy bucket reassignment
  5. Migration Support: Facilitates ongoing cross-account bucket migration efforts

Migration Status: This PR is part of the larger attachment bucket migration initiative. It establishes the infrastructure foundation for consolidating attachment storage and eventual decommissioning of legacy cross-account access.

@benjaminpaige benjaminpaige added the type: FEAT Submit new features label Nov 5, 2025
@macpro-snyk-service-account
Copy link
Copy Markdown
Collaborator

macpro-snyk-service-account commented Nov 5, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Nov 5, 2025

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 90.18% (🎯 90%)
⬇️ -0.20%
6181 / 6854
🔵 Statements 89.73% (🎯 90%)
⬇️ -0.23%
6722 / 7491
🔵 Functions 84.34% (🎯 85%)
⬇️ -0.07%
1772 / 2101
🔵 Branches 77.67% (🎯 80%)
⬇️ -0.46%
3435 / 4422
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
lib/config/deployment-config.ts 89.47%
⬇️ -7.19%
93.54%
⬆️ +0.21%
100%
🟰 ±0%
89.47%
⬇️ -7.19%
82-86, 133-135
lib/libs/opensearch-lib.ts 74.21%
⬇️ -11.37%
54.8%
⬇️ -18.27%
82.6%
⬇️ -7.87%
76.03%
⬇️ -9.15%
38-40, 78-102, 108-114, 139, 218-219, 233, 271
Generated in workflow #4438 for commit fe5f55a by the Vitest Coverage Report Action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: FEAT Submit new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants