(hotswap): The bootstrap roles don't contain necessary permissions for hotswapping
- Dominant language
- TypeScript
- Stars
- 105
- Forks
- 122
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 71
Description
### Describe the bug
When we tried to add the `--hotswap` flag to our deployment command in CICD development environments, the deployment failed:
```
❌ Deployment failed: AccessDenied: User: arn:aws:sts::***:assumed-role/github-actions-oidc-deployment-role/cicd is not authorized to perform: cloudformation:DescribeStacks on resource: arn:aws:cloudformation:us-east-1:***:stack/***/2765aac0-eb87-11ed-8a91-0ad92641443b because no identity-based policy allows the cloudformation:DescribeStacks action
```
The hotswap developer comments that the standard CDK bootstrap roles don't contain permissions to update Lambda functions directly (and presumably all of the other necessary hotswappable resource types), so they use some other credentials for the SDK:
https://github.com/aws/aws-cdk/blob/a65cddf77379087e7cecf772ea75299459c13244/packages/aws-cdk/lib/api/hotswap-deployments.ts#L54
### Expected Behavior
We should be able to add the `hotswap` flag while using the CDK deployed bootstrap roles:
```
cdk bootstrap
cdk deploy
# No action needed related to IAM, the following should just work
cdk deploy --hotswap
```
### Current Behavior
```
cdk bootstrap
```
Using an IAM user with these permssions that just allow the IAM user to assume the CDK bootstrap roles:
```
/**
* DeploymentRole that is assumed by GithubAction using OIDC. This role enables
* GitHub action to interact with AWS resources.
*/
this.deploymentRole = new Role(this, `deployment-role`, {
roleName: `github-actions-oidc-deployment-role`,
assumedBy: new FederatedPrincipal(
this.oidcProvider.openIdConnectProviderArn,
oidcConditions,
"sts:AssumeRoleWithWebIdentity",
),
});
/**
* This policy is able to assume cross-account roles using the
* roles created by the CDK Bootstrap command. The `cdk` commands will
* choose the appropriate role for the `cdk` subcommand.
*/
this.assumeCdkPolicy = new Policy(this, "policy", {
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
actions: ["sts:AssumeRole"],
resources: ["arn:aws:iam::*:role/cdk-*"],
}),
],
roles: [this.deploymentRole],
});
```
```
cdk deploy // This works
cdk deploy --hotswap // This fails due to the stack error from before
```
### Reproduction Steps
```
cdk bootsrap
// Initially any CDK app
cdk init app --language typescript
// Add a NodejsFunction to the CDK sample stack because that is hotswappable
// Create IAM user with the "AssumeRole" "arn:aws:iam::*:role/cdk-*" policy above
// Using the IAM user created above...
cdk deploy; // No problems
// Make a change to the lambda to trigger hotswapping
cdk deploy --hotswap
// Expect error related to DescribeStacks
```
### Possible Solution
The bootstrap command should create a more permissive `hotswap` deployment role. An "enable-hotswap-role" or "disable-hotswap-role" flag could be used to toggle the creation of that role -- I'm not sure which is a more sensible default.
As a short-term alternative, documentation of the required permissions on the `CLI` role would be helpful.
### CDK CLI Version
2.86.0
## Maintainer notes
Similarly this is also confusing for cross-account deployments: https://github.com/aws/aws-cdk-cli/issues/876
Needs to be considered if we are addressing this.
Contributor guide
Assessment
This issue has not been assessed yet.