Skip to content

Commit f1f317a

Browse files
jrusso1020claude
andauthored
fix(cli): grant s3 encryption actions in lambda policies user output (#2289)
`hyperframes lambda deploy` runs `sam deploy --resolve-s3`, and SAM's managed artifacts bucket (aws-sam-cli-managed-default) is created with default SSE encryption. Setting that requires s3:PutEncryptionConfiguration, which the generated deploy policy did not grant, so a first deploy by a user provisioned exactly per `lambda policies user` 403s on the bucket and the managed stack rolls back. Add s3:GetEncryptionConfiguration and s3:PutEncryptionConfiguration to the s3Bucket action set (Get pairs with Put for CloudFormation update/drift reads, matching the existing Get/Put pairs in the list). Also add a hint to the sam-deploy failure path pointing at the ROLLBACK_COMPLETE recovery step, since first-time users hit the stuck-rollback error on their retry. Fixes #2137 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent ebbd1eb commit f1f317a

3 files changed

Lines changed: 18 additions & 1 deletion

File tree

packages/cli/src/commands/lambda/policies.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ describe("policies — required actions", () => {
3232
"lambda:CreateFunction",
3333
"states:StartExecution",
3434
"s3:PutObject",
35+
// SAM's --resolve-s3 managed bucket is encrypted; the deploy user must
36+
// be able to set/read that encryption or the first deploy rolls back.
37+
"s3:PutEncryptionConfiguration",
38+
"s3:GetEncryptionConfiguration",
3539
"iam:CreateRole",
3640
"logs:CreateLogGroup",
3741
"cloudwatch:PutMetricAlarm",

packages/cli/src/commands/lambda/policies.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,18 @@ const REQUIRED_ACTIONS = {
123123
"s3:GetBucketPolicy",
124124
"s3:GetBucketTagging",
125125
"s3:GetBucketVersioning",
126+
// SAM's `--resolve-s3` managed bucket (aws-sam-cli-managed-default) sets
127+
// default SSE encryption; CloudFormation reads it on update/drift. Without
128+
// Get/PutEncryptionConfiguration the first `lambda deploy` 403s creating
129+
// that bucket and the managed stack rolls back.
130+
"s3:GetEncryptionConfiguration",
126131
"s3:GetLifecycleConfiguration",
127132
"s3:ListAllMyBuckets",
128133
"s3:ListBucket",
129134
"s3:PutBucketPolicy",
130135
"s3:PutBucketTagging",
131136
"s3:PutBucketVersioning",
137+
"s3:PutEncryptionConfiguration",
132138
"s3:PutLifecycleConfiguration",
133139
"s3:PutPublicAccessBlock",
134140
],

packages/cli/src/commands/lambda/sam.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,14 @@ export function samDeploy(opts: DeployOptions): void {
106106
const samDir = join(opts.repoRoot, "examples", "aws-lambda");
107107
const result = spawnSync("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
108108
if (result.status !== 0) {
109-
throw new Error(`[lambda] sam deploy exited with code ${result.status ?? "unknown"}`);
109+
throw new Error(
110+
`[lambda] sam deploy exited with code ${result.status ?? "unknown"}\n` +
111+
`If a prior attempt left a stack in ROLLBACK_COMPLETE, CloudFormation can't reuse it. ` +
112+
`Delete it before retrying:\n` +
113+
` aws cloudformation delete-stack --stack-name aws-sam-cli-managed-default --region ${opts.region}\n` +
114+
` aws cloudformation delete-stack --stack-name ${opts.stackName} --region ${opts.region}\n` +
115+
`(the first is SAM's managed artifacts stack from --resolve-s3; the second is the render stack).`,
116+
);
110117
}
111118
}
112119

0 commit comments

Comments
 (0)