aws / aws/aws-cdk-cli

(hotswap): The bootstrap roles don't contain necessary permissions for hotswapping

Open
#867 5 comments 0 reactions 0 assignees View on GitHub
effort/medium feature-request p2
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.