Skip to content

fix(ci): let the RDS unprotect step pass on a state that never created its instance - #486

Merged
cristim merged 1 commit into
mainfrom
fix/485-rds-unprotect-no-instance
Oct 5, 2026
Merged

cristim merged 1 commit into
mainfrom
fix/485-rds-unprotect-no-instance

Conversation

@cristim

@cristim cristim commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Summary

scripts/disable-owned-rds-deletion-protection.sh now exits 0 when a state has outputs but no database_instance_identifier and no aws_db_instance resource. Before this change it exited 1 on that state. This unblocks destroy-fargate-dev.yml on a partially applied stack.

Why

Deploy run 37244250140 failed on aws_db_instance.main with InsufficientDBInstanceCapacity. The github-fargate-dev state kept the outputs of the resources that were created, but not the identifier, which depends on the instance. The script treated this state as a pre-#1821 state and told the operator to re-apply. No instance exists here, so nothing needs unprotecting, and re-applying fails again until AWS has capacity.

Change

  • The jq-failure branch runs only when the identifier key is absent. In that case the script runs terraform -chdir="$STATE_DIR" state list and counts addresses ending in an aws_db_instance resource (any module path, optional [index]). The match is on the exact type, so aws_db_instance_automated_backups_replication.x does not count.
    • Count 0: the script prints that the state owns no RDS instance and exits 0 without calling aws.
    • Count > 0: the existing exit 1 with the re-apply remedy.
  • A failing state list exits through set -e. It is never read as "no instance". The count uses awk, so a matcher error is not mistaken for "no match".
  • The null and empty-string rows, and the no-state and no-outputs rows, behave as before. There is no identifier-prefix fallback.
  • The header table and exit-code docs list the new row.

Tests

Added to scripts/test-rds-deletion-protection-scope.sh. The terraform stub now dispatches output and state list. TF_STATE_LIST is read with ?, so a case that reaches state list without setting it fails.

  • (a) outputs without the identifier, no instance in the state: exit 0, no aws calls
  • (b) module.database.aws_db_instance.main present: exit 1 with the remedy (the existing case, now given an explicit state list), plus an indexed root aws_db_instance.main[0] case
  • (c) state list fails: non-zero, no aws calls
  • (d) addresses that only contain the text aws_db_instance do not count as an instance

Pre-fix output (new suite run against the parent script):

FAIL: behaviour: outputs without the identifier and no aws_db_instance in state exit 0 without calling aws
      exit 1, stderr: error: state '/var/folders/.../tmp.LP1bmqWtD2' has outputs, but 'database_instance_identifier' is
       absent or null, so the instance this state owns cannot be identified.
       This state was last applied before that output existed (#1821).
FAIL: behaviour: resources that merely contain 'aws_db_instance' do not count as an instance
      exit 1, stderr: error: state '...' has outputs, but 'database_instance_identifier' is
passed: 55, failed: 2

(b) and (c) guard behaviour the parent already had, because the parent exits 1 on every absent key, so they cannot fail on the parent. Instead, I applied each of these mutations to the new script and confirmed the matching test fails:

  • state list || printf "": (c) fails
  • ignore the instance count: (b) and the indexed case fail
  • substring /aws_db_instance/ matcher: (d) fails
  • index group made mandatory: (b) fails

Verification

  • bash scripts/test-rds-deletion-protection-scope.sh: passed 57, failed 0 (was 53)
  • bash scripts/test-ecr-delete-selection.sh: passed 56, failed 0
  • shellcheck -x scripts/disable-owned-rds-deletion-protection.sh: clean. The test file still has its three SC2016 info findings, the same ones it has on the parent, at lines this PR does not touch.
  • Pre-commit hooks passed on commit.
  • Not run: no terraform against a real state, no cloud commands.

Closes #485

🤖 Generated with claude-flow

Summary by CodeRabbit

  • Bug Fixes
    • RDS deletion-protection checks now complete successfully when the deployment state contains no database instance, without attempting an AWS operation.
    • Checks continue to report an error when a database instance exists but its identifier is missing, or when the state cannot be listed.
    • Added coverage for these scenarios, including indexed instances and resource names that do not represent actual database instances.

…d its instance

A partially applied state whose apply failed on aws_db_instance.main
stores outputs but no database_instance_identifier, and the script
treated it as a pre-#1821 state and exited 1, so destroy-fargate-dev
could never clean it up.

When the identifier key is absent, read terraform state list: no
aws_db_instance resource (any module path, exact type) means nothing to
unprotect and exits 0; one present keeps the loud exit 1. A failing
state list stays a failure. No identifier-prefix fallback.

Closes #485
@cristim cristim added priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-sprint Within the current sprint impact/internal Team-internal only triaged Item has been triaged effort/xs Trivial / one-liner type/bug Defect labels Oct 5, 2026
@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-platform/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: c47025c8-1d22-49ec-800b-e217a5fd1160
📥 Commits

Reviewing files that changed from the base of the PR and between a11cacc and 2b2ecce.

📒 Files selected for processing (2)
  • scripts/disable-owned-rds-deletion-protection.sh
  • scripts/test-rds-deletion-protection-scope.sh

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

The script now checks Terraform state when database_instance_identifier is absent. It exits successfully if the state has no aws_db_instance resource and retains the error path if an instance exists. Tests cover both outcomes and state-list failures.

Changes

RDS state handling

Layer / File(s) Summary
Handle missing identifier output
scripts/disable-owned-rds-deletion-protection.sh, scripts/test-rds-deletion-protection-scope.sh
The script uses terraform state list to distinguish a state without an RDS instance from one with an instance but no identifier output. Tests cover resource address matching and state-list failures.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 2b2ec

The script can skip states that own no RDS instance without calling AWS, while retaining the error for an instance missing its identifier. No merge-blocking issue is identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: the RDS unprotect step succeeds when the Terraform state has no RDS instance.
Linked Issues check ✅ Passed Issue #485 requires success when outputs exist but the state has no aws_db_instance, and the existing failure with re-apply guidance when the identifier key is absent but an instance exists. The scr…
Out of Scope Changes check ✅ Passed The script documentation and test changes support issue #485 by documenting and verifying the new absent-key behavior. No unrelated changes appear in the whole-PR diff.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@cristim
cristim merged commit 115ff70 into main Oct 5, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/xs Trivial / one-liner impact/internal Team-internal only priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ci): disable-owned-rds-deletion-protection.sh fails on a state whose RDS instance was never created

1 participant