fix(iam): stop the decommissioned slack-bot role breaking every stack update

seahaven-slack-bot was retired in favour of sh-mcp and its deploy role was
deleted directly in IAM on 2026-07-23, leaving the stack holding a
resource that no longer exists. The Outputs section resolved
!GetAtt SeahavenSlackBotDeployRole.Arn as a LIVE IAM read at the end of
every update, so the role's absence failed the whole thing:

  Unable to retrieve Arn attribute for AWS::IAM::Role, with error message
  The role with name githubdeploy-seahaven-slack-bot cannot be found. (404)

This is latent and invisible: the resource definition is unchanged, so it
produces no change-set entry, and change sets do not preview Outputs
resolution. A clean change set was not evidence the update would succeed.
It surfaced when the Phase A boundary-Deny change failed on it.

Step 1 of two. Removes the Output so updates stop resolving the ghost, and
records DeletionPolicy/UpdateReplacePolicy Retain so that step 2 can drop
the resource without CloudFormation issuing DeleteRole against a role that
is not there. Verified from the change set that this step touches only
DeletionPolicy and UpdateReplacePolicy -- metadata, requiresRecreation
Never -- so no IAM call is made against the missing role.

Nothing imported the Output: it had no ExportName, and no stack imports
any export from this stack.

Step 2 deletes the resource block itself.
This commit is contained in:
Adam Moussa 2026-07-27 18:00:38 -04:00
parent b7d7be2727
commit 2f232b6efd
No known key found for this signature in database

View file

@ -1101,8 +1101,24 @@ Resources:
# CDK deploy roles (4 repos)
# ---------------------------------------------------------------------------
# DECOMMISSIONED — being removed from this stack in two steps.
#
# seahaven-slack-bot was retired (superseded by sh-mcp) and this role was
# deleted directly in IAM on 2026-07-23, leaving the stack holding a resource
# that no longer exists. That ghost broke EVERY subsequent stack update: the
# Outputs section resolved !GetAtt SeahavenSlackBotDeployRole.Arn as a live
# IAM read, which 404s. A change-set does not reveal this, because the
# resource itself is unchanged and Outputs are not previewed.
#
# Step 1 (this change): drop the Output so updates stop resolving the ghost,
# and record Retain so that step 2 cannot issue DeleteRole against a role
# that is not there.
# Step 2 (follow-up): delete the resource block itself. With Retain recorded,
# CloudFormation simply stops managing it — no IAM call is made.
SeahavenSlackBotDeployRole:
Type: AWS::IAM::Role
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
RoleName: githubdeploy-seahaven-slack-bot
AssumeRolePolicyDocument:
@ -1283,8 +1299,10 @@ Outputs:
Value: !GetAtt AfiBackupMonitorDeployRole.Arn
PaymentsDashboardDeployRoleArn:
Value: !GetAtt PaymentsDashboardDeployRole.Arn
SeahavenSlackBotDeployRoleArn:
Value: !GetAtt SeahavenSlackBotDeployRole.Arn
# SeahavenSlackBotDeployRoleArn removed 2026-07-27: the role was deleted
# out-of-band on 2026-07-23, so this !GetAtt failed as a live IAM read and
# broke every stack update. Nothing imported it (the Output had no
# ExportName, and no stack imports any export from this stack).
ExecAideDeployRoleArn:
Value: !GetAtt ExecAideDeployRole.Arn
SeahavenDoorUnlockApiDeployRoleArn: