Skip to content

fix(cfn): preserve S3 bucket physical resource ID on stack update#560

Merged
Nahuel990 merged 4 commits intoministackorg:mainfrom
erick-reis-gran:fix/cfn-s3-bucket-update-preserves-physical-id
May 4, 2026
Merged

fix(cfn): preserve S3 bucket physical resource ID on stack update#560
Nahuel990 merged 4 commits intoministackorg:mainfrom
erick-reis-gran:fix/cfn-s3-bucket-update-preserves-physical-id

Conversation

@erick-reis-gran
Copy link
Copy Markdown
Contributor

@erick-reis-gran erick-reis-gran commented May 4, 2026

Summary

Fixes two bugs in the CloudFormation provisioner that broke Serverless Framework deployments.

Bug 1: Auto-named S3 bucket gets a new name on every stack update

When a CloudFormation stack is updated, AWS::S3::Bucket resources without an explicit BucketName (such as the ServerlessDeploymentBucket created by Serverless Framework) were incorrectly getting a new random bucket name on every update instead of preserving the existing one.

This caused Lambda functions referencing the bucket via {"Ref": "ServerlessDeploymentBucket"} to resolve to the new empty bucket instead of the one where the deployment zip was actually uploaded, resulting in Lambda functions created with no code.

Root cause: _RESOURCE_HANDLERS had no "update" entry for AWS::S3::Bucket. On stack update, _update_resource fell back to _provision_resource(type, physical_id, props, stack_name), passing the old physical resource ID where _s3_create expected a logical ID. _s3_create called _physical_name() which always generates a new random suffix, creating a brand new empty bucket.

Fix: Add _s3_update handler that preserves the existing physical resource ID (bucket name) when the bucket is updated in place (matching real AWS CloudFormation behavior). Also make _s3_create use setdefault to avoid wiping existing bucket data.

Bug 2: Lambda functions deployed via CFN missing CodeSize and proper CodeSha256

The CF provisioner _lambda_create never set CodeSize in the config dict and hardcoded CodeSha256 to "cfn-deployed". This caused UIs (like StackPort) to display "NaN undefined" for code size, even when the code was correctly loaded from S3.

Fix: Compute CodeSize and CodeSha256 from the actual zip bytes when available.

Reproduction

  1. Deploy a Serverless Framework service to ministack using serverless-localstack
  2. Deploy again (update)
  3. Observe: Lambda functions have no code, "NaN undefined" code size, and a new empty S3 bucket is created on each update
  4. S3 bucket list shows multiple deployment buckets, only the oldest has data

Test plan

  • test_cfn_auto_named_s3_bucket_stable_across_updates — auto-named bucket keeps same name and objects across stack updates
  • test_cfn_lambda_s3_ref_bucket_has_code_size — Lambda with Code.S3Bucket: {Ref: Bucket} reports correct CodeSize, real CodeSha256, and code is downloadable
  • Existing CFN tests with explicit BucketName still pass (no regression)
  • Full Serverless Framework deploy + redeploy validated end-to-end locally

When a CloudFormation stack is updated, resources without an explicit
update handler fall through to _provision_resource, which calls the
create handler. For AWS::S3::Bucket resources without an explicit
BucketName (e.g. ServerlessDeploymentBucket created by Serverless
Framework), this generated a new random bucket name on every update.

This caused Lambda functions referencing the bucket via {Ref:
ServerlessDeploymentBucket} to resolve to the new empty bucket instead
of the one where the deployment zip was actually uploaded, resulting in
Lambda functions with no code (NaN undefined code size).

Changes:
- Add _s3_update handler that preserves the existing physical resource
  ID (bucket name) when updating an auto-named bucket in place
- Register the update handler in _RESOURCE_HANDLERS
- Make _s3_create use setdefault to avoid wiping existing bucket data
  if called for an already-existing bucket name

Co-authored-by: Cursor <[email protected]>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Docker image for this PR has been published: ministackorg/ministack-preview-build:pr-560-196b27a8

erick-reis-gran and others added 2 commits May 4, 2026 18:11
…a CloudFormation

The CF provisioner _lambda_create was missing CodeSize in the config
dict and hardcoding CodeSha256 to "cfn-deployed". This caused UIs
(like StackPort) to display "NaN undefined" for code size, even though
the code was correctly loaded from S3.

Now computes both fields from the actual zip bytes when available.

Co-authored-by: Cursor <[email protected]>
Two tests covering the bugs fixed in this PR:

1. test_cfn_auto_named_s3_bucket_stable_across_updates:
   Verifies that an auto-named S3 bucket (no explicit BucketName)
   preserves its physical resource ID and objects across stack updates.
   Before the fix, each update generated a new random bucket name.

2. test_cfn_lambda_s3_ref_bucket_has_code_size:
   Verifies that a Lambda deployed via CFN with Code.S3Bucket using
   {Ref: DeployBucket} reports correct CodeSize and CodeSha256, and
   the code is downloadable. Before the fix, CodeSize was missing
   (shown as NaN) and CodeSha256 was hardcoded to 'cfn-deployed'.

Co-authored-by: Cursor <[email protected]>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Docker image for this PR has been published: ministackorg/ministack-preview-build:pr-560-739c4c0d

1 similar comment
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Docker image for this PR has been published: ministackorg/ministack-preview-build:pr-560-739c4c0d

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Docker image for this PR has been published: ministackorg/ministack-preview-build:pr-560-03d039b1

@Nahuel990
Copy link
Copy Markdown
Collaborator

Thanks for this fix @erick-reis-gran !

@Nahuel990 Nahuel990 merged commit 5bddb6b into ministackorg:main May 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants