fix: retain QuoteLambdaEIP on stack delete/replace - #487
Merged
Conversation
Apply RemovalPolicy.RETAIN to the QuoteLambdaElasticIp CfnEIP so both DeletionPolicy and UpdateReplacePolicy render as "Retain". Market makers allowlist this exact egress address; CloudFormation's default releases an EIP back to the public pool on resource removal or stack deletion, which is unrecoverable. No logical-ID or property changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
SocksNFlops
approved these changes
Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Apply
RemovalPolicy.RETAINto theQuoteLambdaElasticIpCfnEIPinbin/stacks/api-stack.ts, so the synthesizedAWS::EC2::EIPresource carries both:Nothing else changes: same construct ID, same logical ID (
QuoteLambdaElasticIp), same properties. Beta and prod share this code path, so one change covers both stages.Why
This EIP is the service's static egress address. It feeds the NAT gateway of the quote-lambda VPC, so every outbound RFQ webhook call to market makers originates from it. Market makers firewall-allowlist this exact IP; their servers reject RFQ traffic from any other source.
CloudFormation's default behaviour for an
AWS::EC2::EIPwith noDeletionPolicyis to release the allocation back to the public AWS pool whenever the resource is removed from the template or the stack is deleted. A released EIP cannot be reliably recovered, and every market maker would have to re-allowlist a new address. An upcoming migration depends on keeping this exact address, so this PR is the safety net against that failure mode:DeletionPolicy: Retainkeeps the allocation if the resource is removed or the stack is deleted.UpdateReplacePolicy: Retainkeeps the old allocation if a future change ever forces a replacement.A
RemovalPolicychange is metadata-only from CloudFormation's point of view. Applying it does not modify or replace the EIP, so deploying this is a no-op for the live address.Explicitly out of scope
Removing or orphaning the EIP from the stack is not done here. That happens at migration cutover and requires hardcoded allocation IDs on the consuming side. This PR only guarantees that when that step happens, the address survives it.
The three NAT EIPs in the nested
AnalyticsStack(Redshift VPC) are left as-is; nothing external depends on those addresses.Verification
yarn install --frozen-lockfile && yarn buildclean.npx cdk synthfrommainand from this branch into separate output directories, thendiff -uon every*.template.json. The only difference across all templates is the two policy lines above on theQuoteLambdaElasticIpresource inGoudaParameterizationStack.template.json. No logical-ID or property changes, no changes to nested templates or the pipeline stack.yarn lint: 0 errors (86 pre-existing warnings, unchanged).cdk deploywas not run.Reviewer note
Merging to
mainauto-deploys to beta and prod via the CDK pipeline. Please review before merging.🤖 Generated with Claude Code