(deploy): Resource Change Filter for `cdk diff` and `cdk deploy`
- Dominant language
- TypeScript
- Stars
- 105
- Forks
- 122
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 71
Description
## Summary
Add a safety mechanism to `cdk diff` and `cdk deploy` that allows specifying one or multiple resource filters. If changes to resources **not** matching these filters are detected, the operation should abort. This provides a safeguard against unintended infrastructure changes, particularly useful in CI/CD pipelines.
## Use Case
In many CDK applications, stacks contain numerous resources, but developers should only be allowed to modify specific resource types during certain deployments. For example:
- A developer pushing Lambda function code updates should only modify `AWS::Lambda::Function` resources
- Automated deployments should only affect specific resource properties like `AWS::Lambda::Function.Code.S3Key`
- CI/CD pipelines should abort if unexpected infrastructure changes (e.g., IAM roles, VPCs, databases) are detected alongside application code changes
Currently, there's no built-in way to validate that a deployment only affects specific resources, leading to potential risks of accidentally deploying unwanted infrastructure changes.
## Proposed Solution
### Command Line Options
Add new options to `cdk diff` and `cdk deploy`:
```bash
# Allow only specific resource types
cdk deploy --allow-resource-changes AWS::Lambda::Function,Custom::CDKBucketDeployment
# Allow only specific resource properties
cdk deploy --allow-resource-changes AWS::Lambda::Function.Code.S3Key
# Multiple filters (any match allows the change)
cdk deploy --allow-resource-changes AWS::Lambda::Function.Runtime \
--allow-resource-changes AWS::Lambda::Function.Code
# Combined with other options
cdk diff Stack1 --allow-resource-changes AWS::Lambda::Function --fail
```
### Behavior
1. **During diff/deploy**: After generating the changeset or template diff, analyze all resource changes
2. **Filter matching**: Check each changed resource against the specified filters:
- **Resource type filter**: `AWS::Lambda::Function` - matches any change to Lambda functions
- **Property-specific filter**: `AWS::Lambda::Function.Code.S3Key` - matches only changes to the S3Key property of Lambda function code
- **Wildcard support**: `AWS::Lambda::*` - matches all Lambda-related resources
3. **Abort behavior**: If **any** resource change does not match **at least one** filter, abort the operation with:
- Exit code 1
- Clear error message listing the unmatched changes
- Suggestion to review changes or update filters
### Example Scenarios
#### Scenario 1: Lambda-only deployment
```bash
cdk deploy --allow-resource-changes AWS::Lambda::Function
```
**Allowed changes:**
- Lambda function runtime update
- Lambda function memory size change
- Lambda function code update
**Blocked changes:**
- IAM role modifications
- DynamoDB table changes
- VPC configuration updates
#### Scenario 2: Code-only deployment
```bash
cdk deploy --allow-resource-changes AWS::Lambda::Function.Code.S3Key
```
**Allowed changes:**
- Lambda function code S3 key update (code deployment only)
**Blocked changes:**
- Lambda function runtime change
- Lambda function memory size change
- Any other Lambda property changes
- Any changes to other resource types
#### Scenario 3: Multiple allowed resources
```bash
cdk deploy --allow-resource-changes AWS::Lambda::Function \
--allow-resource-changes Custom::CDKBucketDeployment
```
**Allowed changes:**
- Any Lambda function changes
- Any CDK bucket deployment changes
**Blocked changes:**
- All other resource types
#### Scenario 4: API Gateway definition-only deployment
```bash
cdk deploy --allow-resource-changes AWS::ApiGateway::RestApi.Body
```
**Allowed changes:**
- API Gateway REST API definition/specification updates (OpenAPI/Swagger changes)
**Blocked changes:**
- API Gateway stage configuration changes
- API Gateway deployment settings
- Lambda function changes
- IAM role modifications
- Any other resource types
### Error Output Example
When unwanted changes are detected:
```
❌ Deployment aborted: Detected changes to resources outside allowed filters
Allowed resource changes:
• AWS::Lambda::Function.Code.S3Key
Detected changes that violate the filter:
• MyFunction (AWS::Lambda::Function)
- Property: Runtime (changed from nodejs18.x to nodejs20.x)
• MyRole (AWS::IAM::Role)
- Property: Policies (changed)
To proceed with these changes, either:
1. Review and remove the unwanted changes from your CDK code
2. Update your --allow-resource-changes filters to include these resource types
3. Remove the --allow-resource-changes option to deploy all changes
```
## Implementation Considerations
### Integration Points
1. **Diff Stage**: After computing the template diff (in `DiffFormatter`), apply resource filters before displaying/evaluating
2. **Deploy Stage**: Before executing the changeset (in `FullCloudFormationDeployment`), validate against filters
3. **Filter Matching Logic**:
- Parse filter strings into resource type and optional property path
- Match against `ResourceDifference` objects from `@aws-cdk/cloudformation-diff`
- Support dot notation for property paths (e.g., `Properties.Code.S3Key`)
### Configuration Options
Support multiple ways to specify filters:
1. **CLI flags**: `--allow-resource-changes` (as shown above)
2. **cdk.json**:
```json
{
"allowResourceChanges": [
"AWS::Lambda::Function.Code.S3Key",
"Custom::CDKBucketDeployment"
]
}
```
3. **Environment variable**: `CDK_ALLOW_RESOURCE_CHANGES="AWS::Lambda::Function,Custom::CDKBucketDeployment"`
CLI flags should take precedence over configuration file, which takes precedence over environment variables.
### Filter Syntax
- `AWS::Lambda::Function` - Match any changes to Lambda functions
- `AWS::Lambda::Function.Properties.Code` - Match changes to the Code property
- `AWS::Lambda::Function.Properties.Code.S3Key` - Match only S3Key changes within Code
- `AWS::Lambda::*` - Match all Lambda-related resource types (with wildcard support)
- `*.Properties.Tags` - Match tag changes on any resource type
## Benefits
1. **Safety**: Prevents accidental deployment of unintended infrastructure changes
2. **CI/CD Integration**: Enables fine-grained deployment controls in automated pipelines
3. **Developer Workflow**: Allows limiting developer permissions to specific resource types
4. **Audit & Compliance**: Provides clear validation of what changed in each deployment
5. **Fail-Fast**: Catches issues during diff/deploy rather than after deployment completes
## Alternatives Considered
1. **Manual review**: Requires human inspection of every diff, error-prone and time-consuming
2. **Separate stacks**: Splitting resources into multiple stacks creates complexity and cross-stack dependencies
3. **Custom scripts**: External validation scripts are fragile and don't integrate with CDK workflow
4. **Stack policies**: CloudFormation stack policies are resource-level only and don't support property-level granularity
## Related Features
- Similar to `--exclusively` flag (which filters stacks)
- Complements `--fail` flag for `cdk diff` (which fails on any diff)
- Extends security approval prompts (which warn on IAM changes)
- Conceptually similar to [CloudFormation Hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-concepts.html) but executed client-side before deployment rather than server-side during deployment
## Additional Notes
This feature would be particularly valuable for:
- **Serverless applications**: Frequent Lambda code deployments with stable infrastructure
- **GitOps workflows**: Automated deployments with safety constraints
- **Multi-team environments**: Different teams with different permission boundaries
- **Compliance requirements**: Enforcing change management policies
Contributor guide
Assessment
This issue has not been assessed yet.