Skip to content

Commit 90f97de

Browse files
isadeksbgagentkrokoko
authored
fix(cdk): grant lambda Put/DeleteProvisionedConcurrencyConfig (#409) (#410)
The Slack-events function pins provisioned concurrency on its `live` alias (AWS::Lambda::Alias with ProvisionedConcurrencyConfig), so CloudFormation issues lambda:PutProvisionedConcurrencyConfig at create. The Lambda statement in the bootstrap policy granted only lambda:GetProvisionedConcurrencyConfig, so a fresh `mise //cdk:bootstrap` + deploy of current main rolls back with: cdk-hnb659fds-cfn-exec-role is not authorized to perform lambda:PutProvisionedConcurrencyConfig Add Put/DeleteProvisionedConcurrencyConfig next to the existing Get verb (resource ARN function:backgroundagent-dev-* is already covered), regenerate bootstrap artifacts, update the DEPLOYMENT_ROLES.md golden (+ mirror), and add a regression guard. Fourth instance of bootstrap allow-list drift (after #403, #405, #408). Fixes #409 Co-authored-by: bgagent <bgagent@noreply.github.com> Co-authored-by: Alain Krok <alkrok@amazon.com>
1 parent e6ce821 commit 90f97de

6 files changed

Lines changed: 24 additions & 0 deletions

File tree

cdk/bootstrap/bootstrap-template.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,8 @@ Resources:
10021002
- lambda:GetFunctionCodeSigningConfig
10031003
- lambda:GetFunctionRecursionConfig
10041004
- lambda:GetProvisionedConcurrencyConfig
1005+
- lambda:PutProvisionedConcurrencyConfig
1006+
- lambda:DeleteProvisionedConcurrencyConfig
10051007
- lambda:GetRuntimeManagementConfig
10061008
- lambda:ListVersionsByFunction
10071009
- lambda:InvokeFunction

cdk/bootstrap/policies/application.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
"lambda:GetFunctionCodeSigningConfig",
5151
"lambda:GetFunctionRecursionConfig",
5252
"lambda:GetProvisionedConcurrencyConfig",
53+
"lambda:PutProvisionedConcurrencyConfig",
54+
"lambda:DeleteProvisionedConcurrencyConfig",
5355
"lambda:GetRuntimeManagementConfig",
5456
"lambda:ListVersionsByFunction",
5557
"lambda:InvokeFunction",

cdk/src/bootstrap/policies/application.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export function applicationPolicy(): iam.PolicyDocument {
8484
'lambda:GetFunctionCodeSigningConfig',
8585
'lambda:GetFunctionRecursionConfig',
8686
'lambda:GetProvisionedConcurrencyConfig',
87+
'lambda:PutProvisionedConcurrencyConfig',
88+
'lambda:DeleteProvisionedConcurrencyConfig',
8789
'lambda:GetRuntimeManagementConfig',
8890
'lambda:ListVersionsByFunction',
8991
'lambda:InvokeFunction',

cdk/test/bootstrap/policies.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,20 @@ describe('IaCRole-ABCA-Application', () => {
149149
);
150150
});
151151

152+
it('grants Put/Delete provisioned-concurrency, not just Get (#409)', () => {
153+
// The Slack-events function pins provisioned concurrency on its `live`
154+
// alias, so the exec role needs Put (create/update) and Delete (removal),
155+
// not only the Get verb. Get-without-Put rolled the deploy back with
156+
// AccessDenied on lambda:PutProvisionedConcurrencyConfig.
157+
const resolvedDoc = stack.resolve(doc);
158+
const statements = resolvedDoc.Statement as Array<{ Action: string | string[] }>;
159+
const allActions = statements.flatMap((s) =>
160+
Array.isArray(s.Action) ? s.Action : [s.Action],
161+
);
162+
expect(allActions).toContain('lambda:PutProvisionedConcurrencyConfig');
163+
expect(allActions).toContain('lambda:DeleteProvisionedConcurrencyConfig');
164+
});
165+
152166
it('LambdaEventSourceMappings grants tagging (CDK event-source constructs tag the mapping)', () => {
153167
// Regression guard for #407: DynamoDBEventSource (and peers) tag the
154168
// created event source mapping, so the exec role needs Tag/UntagResource

docs/design/DEPLOYMENT_ROLES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ DynamoDB tables, Lambda functions, API Gateway, Cognito, WAFv2, EventBridge, SQS
319319
"lambda:GetFunctionCodeSigningConfig",
320320
"lambda:GetFunctionRecursionConfig",
321321
"lambda:GetProvisionedConcurrencyConfig",
322+
"lambda:PutProvisionedConcurrencyConfig",
323+
"lambda:DeleteProvisionedConcurrencyConfig",
322324
"lambda:GetRuntimeManagementConfig",
323325
"lambda:ListVersionsByFunction",
324326
"lambda:InvokeFunction",

docs/src/content/docs/architecture/Deployment-roles.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ DynamoDB tables, Lambda functions, API Gateway, Cognito, WAFv2, EventBridge, SQS
323323
"lambda:GetFunctionCodeSigningConfig",
324324
"lambda:GetFunctionRecursionConfig",
325325
"lambda:GetProvisionedConcurrencyConfig",
326+
"lambda:PutProvisionedConcurrencyConfig",
327+
"lambda:DeleteProvisionedConcurrencyConfig",
326328
"lambda:GetRuntimeManagementConfig",
327329
"lambda:ListVersionsByFunction",
328330
"lambda:InvokeFunction",

0 commit comments

Comments
 (0)