|
| 1 | +# Enhanced CLI Deploy Approval With Change Set Review |
| 2 | + |
| 3 | +* **Original Author(s):**: @stevehodgkiss, @orien |
| 4 | +* **Tracking Issue**: #370 |
| 5 | +* **API Bar Raiser**: @{BAR_RAISER_USER} |
| 6 | + |
| 7 | +This feature enhances the existing `--require-approval=any-change` option to show all stack changes (not just |
| 8 | +security changes) and integrates CloudFormation change set creation and review to provide users with an accurate |
| 9 | +preview of what will be applied before deployment execution. |
| 10 | + |
| 11 | +Modern cloud infrastructure contains critical stateful resources—databases, persistent storage, message queues, and |
| 12 | +other systems that hold valuable data and maintain complex state. Engineers deploying changes to these environments |
| 13 | +carry significant responsibility: a single misunderstood deployment can lead to data loss, service outages, or |
| 14 | +security vulnerabilities that affect customers and business operations. While Infrastructure as Code provides |
| 15 | +repeatability and version control, it doesn't eliminate the fundamental need for engineers to understand precisely |
| 16 | +what changes will be applied before execution. Tooling must bridge this gap by providing clear, accurate previews |
| 17 | +of deployment impact—especially for stateful resources where "undo" isn't always possible. This enhancement ensures |
| 18 | +that engineers have the complete information they need to make informed decisions about infrastructure changes. |
| 19 | + |
| 20 | +## Working Backwards |
| 21 | + |
| 22 | +### CHANGELOG |
| 23 | + |
| 24 | +* **feat(cli)**: enhance `--require-approval=any-change` to show all stack changes instead of only security changes |
| 25 | +* **feat(cli)**: integrate CloudFormation change set creation and display when using `--require-approval=any-change` |
| 26 | + with standard (non-hotswap) deployments |
| 27 | + |
| 28 | +The `cdk deploy --require-approval=any-change` command now shows all changes to the stack, not just security-related |
| 29 | +changes. For standard CloudFormation deployments, it creates a CloudFormation change set, displays both the template |
| 30 | +diff and the change set details, and prompts for approval before executing the change set. This provides users with |
| 31 | +the most accurate preview of what changes will actually be applied. |
| 32 | + |
| 33 | +```bash |
| 34 | +# Review all changes before deploying (enhanced behavior) |
| 35 | +cdk deploy --require-approval=any-change MyStack |
| 36 | + |
| 37 | +# Existing security-only behavior unchanged |
| 38 | +cdk deploy --require-approval=broadening MyStack |
| 39 | + |
| 40 | +# No change set review with hotswap (template diff only) |
| 41 | +cdk deploy --require-approval=any-change --hotswap MyStack |
| 42 | +``` |
| 43 | + |
| 44 | +### README |
| 45 | + |
| 46 | +#### Enhanced Change Approval |
| 47 | + |
| 48 | +The `--require-approval=any-change` option has been enhanced to provide comprehensive change review: |
| 49 | + |
| 50 | +##### Standard Deployments (without --hotswap) |
| 51 | + |
| 52 | +When using standard CloudFormation deployments, `--require-approval=any-change` now: |
| 53 | + |
| 54 | +1. **Shows All Changes**: Displays template diffs for all resource changes, not just security changes |
| 55 | +2. **Creates Change Set**: Automatically creates a CloudFormation change set for accurate deployment preview |
| 56 | +3. **Combined Display**: Shows both template diff and change set information |
| 57 | +4. **Accurate Resource Impact**: Displays physical resource changes, replacements, and dependencies |
| 58 | +5. **Requires Approval**: Prompts for confirmation before executing the change set |
| 59 | + |
| 60 | +##### Example Output |
| 61 | + |
| 62 | +``` |
| 63 | +$ cdk deploy --require-approval=any-change ExampleProjectStack |
| 64 | +
|
| 65 | +✨ Synthesis time: 2.07s |
| 66 | +
|
| 67 | +ExampleProjectStack: start: Building ExampleProjectStack Template |
| 68 | +ExampleProjectStack: success: Built ExampleProjectStack Template |
| 69 | +ExampleProjectStack: start: Publishing ExampleProjectStack Template (111111111111-ap-southeast-2-a1178ad2) |
| 70 | +ExampleProjectStack: success: Published ExampleProjectStack Template (111111111111-ap-southeast-2-a1178ad2) |
| 71 | +ExampleProjectStack: creating CloudFormation changeset... |
| 72 | +Changeset arn:aws:cloudformation:ap-southeast-2:111111111111:changeSet/cdk-change-set-1758811656501/c607dcdd-994d-47b1-81ea-cbc8d17f6ccf created and waiting in review for manual execution (--no-execute) |
| 73 | +Stack ExampleProjectStack |
| 74 | +Resources |
| 75 | +[~] AWS::SQS::Queue ExampleProjectQueue ExampleProjectQueue0324465D replace |
| 76 | + ├─ [+] QueueName (requires replacement) |
| 77 | + │ └─ new-custom-name |
| 78 | + └─ [~] VisibilityTimeout |
| 79 | + ├─ [-] 301 |
| 80 | + └─ [+] 300 |
| 81 | +
|
| 82 | +
|
| 83 | +Do you wish to deploy these changes (y/n)? y |
| 84 | +ExampleProjectStack: deploying... [1/1] |
| 85 | +Executing existing change set cdk-change-set-1758811656501 on stack ExampleProjectStack |
| 86 | +
|
| 87 | + ✅ ExampleProjectStack |
| 88 | +
|
| 89 | +✨ Deployment time: 73.13s |
| 90 | +
|
| 91 | +Stack ARN: |
| 92 | +arn:aws:cloudformation:ap-southeast-2:111111111111:stack/ExampleProjectStack/06bd8930-9a19-11f0-a13f-0a8d18d6260b |
| 93 | +
|
| 94 | +✨ Total time: 75.2s |
| 95 | +``` |
| 96 | + |
| 97 | +##### Hotswap Deployments |
| 98 | + |
| 99 | +When using `--require-approval=any-change` with `--hotswap`, the behavior is enhanced: |
| 100 | + |
| 101 | +- Shows template diff for all changes (previously only showed security changes) |
| 102 | +- No change set creation (hotswap bypasses CloudFormation) |
| 103 | +- Proceeds with hotswap deployment after approval |
| 104 | + |
| 105 | +##### Existing Options Unchanged |
| 106 | + |
| 107 | +- `--require-approval=never`: No approval required (default) |
| 108 | +- `--require-approval=broadening`: Only security-broadening changes require approval (unchanged behavior) |
| 109 | + |
| 110 | +--- |
| 111 | + |
| 112 | +Ticking the box below indicates that the public API of this RFC has been |
| 113 | +signed-off by the API bar raiser (the `status/api-approved` label was applied to the |
| 114 | +RFC pull request): |
| 115 | + |
| 116 | +``` |
| 117 | +[ ] Signed-off by API Bar Raiser @xxxxx |
| 118 | +``` |
| 119 | + |
| 120 | +## Public FAQ |
| 121 | + |
| 122 | +### What are we launching today? |
| 123 | + |
| 124 | +We are launching enhanced functionality for the existing `--require-approval=any-change` flag. This enhancement makes |
| 125 | +the flag show all stack changes (not just security changes) and integrates CloudFormation change set creation for |
| 126 | +standard deployments. Users get both template diff information and accurate change set details, showing exactly what |
| 127 | +CloudFormation will execute. |
| 128 | + |
| 129 | +### Why should I use this feature? |
| 130 | + |
| 131 | +The enhanced `--require-approval=any-change` addresses several use cases: |
| 132 | + |
| 133 | +1. **Complete Change Visibility**: See all changes to your stack, not just security changes |
| 134 | +2. **Accurate Deployment Preview**: Change sets show the actual changes CloudFormation will make, including parameter |
| 135 | + updates that don't appear in template diffs |
| 136 | +3. **Resource Replacement Detection**: Change sets indicate when resources will be replaced, preventing data loss |
| 137 | +4. **Production Safety**: Required approval step prevents accidental, destructive deployments |
| 138 | +5. **Compliance**: Manual review process for infrastructure changes |
| 139 | +6. **Parameter-Only Deployments**: Visibility into CloudFormation parameter changes that trigger resource updates |
| 140 | + |
| 141 | +This is particularly valuable for production environments and teams with change management requirements. |
| 142 | + |
| 143 | +## Internal FAQ |
| 144 | + |
| 145 | +### Why are we doing this? |
| 146 | + |
| 147 | +The current `--require-approval=any-change` option is misleading - it only shows security-related changes, not all |
| 148 | +changes as the name implies. This affects both standard and hotswap deployments. Users who want to review all changes |
| 149 | +before deployment don't have a good option. Additionally, template diffs don't show the complete picture of what |
| 150 | +CloudFormation will actually do: |
| 151 | + |
| 152 | +1. **Parameter Changes**: CloudFormation parameter updates that trigger resource changes don't show in template diffs |
| 153 | +2. **Resource Replacement**: Template diffs don't indicate when resources will be replaced vs. updated in-place |
| 154 | +3. **Dependency Changes**: Order of operations and dependencies are not visible in template diffs |
| 155 | +4. **Physical Resource Impact**: Template diffs show logical changes but not physical resource impacts |
| 156 | + |
| 157 | +CloudFormation change sets provide definitive information about what will actually happen during deployment. The |
| 158 | +[original implementation attempt](https://github.com/aws/aws-cdk/pull/15494) demonstrated the value of this approach. |
| 159 | + |
| 160 | +### Why should we _not_ do this? |
| 161 | + |
| 162 | +This change modifies existing behavior, which could be disruptive: |
| 163 | + |
| 164 | +1. **Behavior Change**: `--require-approval=any-change` currently only shows security changes; expanding to all changes |
| 165 | + could be unexpected |
| 166 | +2. **Performance Impact**: Creating change sets adds latency to the deployment process |
| 167 | +3. **Hotswap Incompatibility**: Change sets cannot work with hotswap deployments, creating an inconsistent user experience |
| 168 | +4. **API Dependencies**: Additional CloudFormation API calls and potential rate limiting |
| 169 | +5. **Complexity**: More code paths to maintain and test |
| 170 | + |
| 171 | +However, these concerns are mitigated by the fact that the current behavior is already misleading (the name suggests |
| 172 | +all changes, but only shows security changes), and the performance impact only affects users who explicitly opt into |
| 173 | +the approval process. |
| 174 | + |
| 175 | +### What is the technical solution (design) of this feature? |
| 176 | + |
| 177 | +The implementation enhances the existing `--require-approval` logic with change set integration: |
| 178 | + |
| 179 | +#### High-Level Flow |
| 180 | + |
| 181 | +1. **Synthesis**: Standard CDK app synthesis to generate CloudFormation templates |
| 182 | +2. **Approval Check**: Determine if approval is required based on `--require-approval` value |
| 183 | +3. **Template Diff**: Generate template diff showing all changes (enhanced from current security-only logic) |
| 184 | +4. **Deployment Type Check**: |
| 185 | + - For hotswap deployments: show template diff and proceed with existing approval flow |
| 186 | + - For standard deployments: continue to change set creation |
| 187 | +5. **Change Set Creation**: Call CloudFormation `CreateChangeSet` API |
| 188 | +6. **Combined Display**: Show both template diff and change set information |
| 189 | +7. **User Approval**: Interactive prompt for confirmation |
| 190 | +8. **Change Set Execution**: Call `ExecuteChangeSet` API on approval |
| 191 | + |
| 192 | +#### Key Components |
| 193 | + |
| 194 | +1. **Enhanced DiffAnalyzer**: Modify existing logic to detect all changes instead of only security changes |
| 195 | +2. **ChangeSetCreator**: New component to create and describe CloudFormation change sets |
| 196 | +3. **CombinedDisplayFormatter**: Format both template diff and change set information |
| 197 | +4. **ApprovalPrompt**: Enhanced to handle both template diff and change set approval |
| 198 | + |
| 199 | +#### Change Set Integration |
| 200 | + |
| 201 | +- **Automatic Creation**: Change sets are created automatically for `--require-approval=any-change` on standard |
| 202 | + deployments |
| 203 | +- **Naming Convention**: `cdk-deploy-change-set-{timestamp}` to avoid conflicts |
| 204 | +- **Cleanup**: Change sets are automatically deleted after successful execution or on cancellation |
| 205 | +- **Error Handling**: Graceful fallback to template diff only if change set creation fails |
| 206 | + |
| 207 | +### Is this a breaking change? |
| 208 | + |
| 209 | +This is technically a breaking change in behavior, but it aligns with user expectations: |
| 210 | + |
| 211 | +**Breaking aspects**: |
| 212 | + |
| 213 | +- `--require-approval=any-change` will now show all changes instead of only security changes (affects both standard and hotswap deployments) |
| 214 | +- Additional latency due to change set creation for standard deployments |
| 215 | +- Different approval prompts that include change set information for standard deployments |
| 216 | +- Hotswap deployments will show template diffs for all changes instead of only security changes |
| 217 | + |
| 218 | +**Mitigation**: |
| 219 | + |
| 220 | +- The current behavior is misleading - users expect "any-change" to mean all changes |
| 221 | +- Users explicitly opt into this behavior with the flag |
| 222 | +- Existing `--require-approval=broadening` behavior remains unchanged |
| 223 | +- Performance impact only affects users who choose to use approval |
| 224 | + |
| 225 | +**Migration path**: |
| 226 | + |
| 227 | +- Users who want the old security-only behavior should use `--require-approval=broadening` |
| 228 | +- Documentation will clearly explain the enhanced behavior |
| 229 | + |
| 230 | +### What alternative solutions did you consider? |
| 231 | + |
| 232 | +#### 1. Add New `--require-approval=all-changes` Option |
| 233 | + |
| 234 | +Add a new option value instead of changing existing behavior. |
| 235 | +**Rejected**: Would leave the misleading `any-change` option unchanged and create confusion between `any-change` and |
| 236 | +`all-changes`. |
| 237 | + |
| 238 | +#### 2. Create Separate `--review-changeset` Flag |
| 239 | + |
| 240 | +Add a separate flag specifically for change set review. |
| 241 | +**Rejected**: Creates fragmented functionality; approval and change set review are closely related concerns that should |
| 242 | +be unified. |
| 243 | + |
| 244 | +#### 3. Always Create Change Sets for Any Approval |
| 245 | + |
| 246 | +Create change sets for all `--require-approval` modes. |
| 247 | +**Rejected**: Unnecessary overhead for security-only approval workflows. |
| 248 | + |
| 249 | +#### 4. Only Show Change Sets, Remove Template Diff |
| 250 | + |
| 251 | +Show only change set information without template diff. |
| 252 | +**Rejected**: Template diffs provide valuable context about CDK-level changes that complement change set physical |
| 253 | +resource information. |
| 254 | + |
| 255 | +### What are the drawbacks of this solution? |
| 256 | + |
| 257 | +1. **Behavioral Breaking Change**: Existing `--require-approval=any-change` users will see different behavior |
| 258 | +2. **Performance Impact**: Change set creation adds 5-15 seconds to the deployment process |
| 259 | +3. **Inconsistent Experience**: Different behavior between hotswap and standard deployments |
| 260 | +4. **Additional API Calls**: More CloudFormation API usage and potential throttling |
| 261 | +5. **Complexity**: More code paths and error handling scenarios |
| 262 | +6. **User Confusion**: Users may not understand why some deployments show change sets and others don't |
| 263 | + |
| 264 | +### What is the high-level project plan? |
| 265 | + |
| 266 | +#### Phase 1: Core Implementation |
| 267 | + |
| 268 | +- Modify existing `--require-approval=any-change` logic to show all changes instead of security-only |
| 269 | +- Implement change set creation for standard (non-hotswap) deployments |
| 270 | +- Add combined display of template diff and change set information |
| 271 | +- Update approval prompt to handle change set confirmation |
| 272 | + |
| 273 | +#### Phase 2: Polish & Integration |
| 274 | + |
| 275 | +- Implement change set cleanup on success/failure |
| 276 | +- Add comprehensive error handling for change set creation failures |
| 277 | +- Optimize display formatting for large change sets |
| 278 | +- Add a configuration option in `cdk.json` for change set timeout |
| 279 | + |
| 280 | +#### Phase 3: Documentation & Migration |
| 281 | + |
| 282 | +- Update CLI help text and documentation |
| 283 | +- Create a migration guide for users affected by the behavior change |
| 284 | +- Add examples and best practices |
| 285 | +- Performance optimization based on usage patterns |
| 286 | + |
| 287 | +### Are there any open issues that need to be addressed later? |
| 288 | + |
| 289 | +1. **User Communication**: How to best communicate the behavior change to existing users |
| 290 | +2. **Change Set Cleanup**: Automatic cleanup strategy for failed or cancelled deployments |
| 291 | +3. **Large Change Sets**: Optimal display format for deployments with hundreds of resources |
| 292 | +4. **Nested Stacks**: Change set behavior with nested stack deployments |
| 293 | +5. **Performance Optimization**: Caching strategies to reduce change set creation time |
| 294 | +6. **Error Recovery**: Fallback strategies when change set creation fails |
| 295 | +7. **Configuration**: Options to disable change set creation for specific environments |
| 296 | + |
| 297 | +## Appendix |
| 298 | + |
| 299 | +### CloudFormation Change Set API Reference |
| 300 | + |
| 301 | +- [`CreateChangeSet`](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateChangeSet.html): |
| 302 | + Create change set for deployment preview |
| 303 | +- [`DescribeChangeSet`](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeChangeSet.html): |
| 304 | + Get detailed change set information |
| 305 | +- [`ExecuteChangeSet`](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ExecuteChangeSet.html): |
| 306 | + Execute approved changes |
| 307 | +- [`DeleteChangeSet`](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DeleteChangeSet.html): |
| 308 | + Clean up change sets after execution or cancellation |
| 309 | + |
| 310 | +### Current vs Enhanced Behavior |
| 311 | + |
| 312 | +| Scenario | Current Behavior | Enhanced Behavior | |
| 313 | +|----------|------------------|-------------------| |
| 314 | +| `--require-approval=any-change` (standard deploy) | Shows only security changes, direct deploy | Shows all changes + change set, execute change set | |
| 315 | +| `--require-approval=any-change` (hotswap) | Shows only security changes, hotswap deploy | Shows all changes, hotswap deploy | |
| 316 | +| `--require-approval=broadening` | Shows security changes, direct deploy | **Unchanged** | |
| 317 | +| `--require-approval=never` | No approval, direct deploy | **Unchanged** | |
| 318 | + |
| 319 | +### Hotswap Compatibility |
| 320 | + |
| 321 | +Hotswap deployments bypass CloudFormation entirely, making them incompatible with change sets: |
| 322 | + |
| 323 | +- **With hotswap**: Template diff shows all changes, approval prompt, then hotswap deployment (no change set) |
| 324 | +- **Without hotswap**: Template diff + change set details, approval prompt, then change set execution |
| 325 | + |
| 326 | +### Migration Guide |
| 327 | + |
| 328 | +**For users currently using `--require-approval=any-change`:** |
| 329 | + |
| 330 | +**Before (current behavior):** |
| 331 | + |
| 332 | +- Only security-related changes shown in template diff |
| 333 | +- Direct CloudFormation deployment (standard) or hotswap deployment |
| 334 | +- Fast deployment after approval |
| 335 | + |
| 336 | +**After (enhanced behavior):** |
| 337 | + |
| 338 | +- All changes shown in template diff (security + non-security) |
| 339 | +- **Standard deployments**: Change set creation and review + template diff |
| 340 | +- **Hotswap deployments**: Enhanced template diff showing all changes (no change set) |
| 341 | +- Slightly slower for standard deployments due to change set creation |
| 342 | +- More accurate preview of deployment impact |
| 343 | + |
| 344 | +**If you want the old behavior:** |
| 345 | +Use `--require-approval=broadening` which maintains the current security-only focus. |
| 346 | + |
| 347 | +### Example Scenarios |
| 348 | + |
| 349 | +#### Scenario 1: Lambda Function Update |
| 350 | + |
| 351 | +```bash |
| 352 | +# Template shows: Lambda function code change |
| 353 | +# Change set shows: UpdateFunctionCode API call, no replacement |
| 354 | +# User sees: Both perspectives for complete understanding |
| 355 | +``` |
| 356 | + |
| 357 | +#### Scenario 2: RDS Parameter Change |
| 358 | + |
| 359 | +```bash |
| 360 | +# Template shows: No visible changes (parameter-only update) |
| 361 | +# Change set shows: Database replacement required due to parameter change, ALL DATA WILL BE LOST |
| 362 | +# User sees: Critical information that template diff cannot provide |
| 363 | +``` |
| 364 | + |
| 365 | +#### Scenario 3: Security Group Modification |
| 366 | + |
| 367 | +```bash |
| 368 | +# Template shows: Security group rule changes |
| 369 | +# Change set shows: Which EC2 instances will be affected by the change |
| 370 | +# User sees: Both logical and physical impact of the change |
| 371 | +``` |
0 commit comments