refactor(cell/infra): consume the framework's celld-fleet module - #155
Open
coccyx wants to merge 1 commit into
Open
refactor(cell/infra): consume the framework's celld-fleet module#155coccyx wants to merge 1 commit into
coccyx wants to merge 1 commit into
Conversation
The fleet pattern here (one celld node + one S3 bucket, SSM secrets at boot, Caddy/sslip.io TLS) was extracted into the framework as infra/celld-fleet in PRs #129/#130/#132 so every cell-harness app deploys the same thing. This makes APM consume the extraction instead of carrying the fork, which is what keeps the two from drifting — the next celld-version or cloud-init fix lands once, in the module. What stays in this root is this fleet's identity: cell_name "apm-cell" (so every create-time resource name stays "apm-cell-node"), the cribl-apm-cell-test bucket, the /apm-cell SSM prefix, the six secret_env_keys the real agent loop needs, and the four plain_env values. The provider and the S3 backend stay here too — the module deliberately supplies neither. `moved` blocks migrate all twelve resources from the root addresses into module.fleet.*, so the re-address destroys nothing. Two notes on the plan this produces: - The instance is replaced, once. The generalized user_data differs textually and user_data_replace_on_change is true. That is the designed path: durable state is replicated to the bucket and the EIP is a separate resource, so the URL survives. Rendering both templates side by side shows the env file is functionally identical (same six secret keys, same four plain vars, same log path) — the diff is the generalization itself. - The security group is NOT replaced, because its description is a create-time argument and the group's name is derived from cell_name; the module's generic wording would have been a same-name destroy/create fighting the attached instance. Framework PR #34 adds security_group_description so this root can pin its original text. One behavior change worth knowing: the old template skipped the LLM/Cribl secrets when llm_base_url was empty, a stub-agent fallback. The module reads secret_env_keys unconditionally, so boot now fails on any missing parameter. All six exist in the test account; a stub-mode node would shorten secret_env_keys rather than clear llm_base_url. Documented in the README. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Replaces this stack's hand-rolled fleet infra with the framework's
infra/celld-fleetmodule (extracted from here in PRs #129/#130/#132), keeping the live stack's identity byte-for-byte.Applied to the live cell already — plan read line by line, applied in a quiet window, verified end-to-end. Details below.
Depends on framework PR criblio/cribl-search-app-framework#34 (adds
security_group_description). That must merge, and.framework-shamust move to include it, before this can plan on another machine — see "Before merging".What's here
cell/infra/main.tfis now a module block plusmovedblocks. This root keeps only its identity and its AWS session:cell_nameapm-cell→ every resource staysapm-cell-nodebucket_namecribl-apm-cell-testssm_parameter_prefix/apm-cellsecret_env_keysWEBHOOK_BEARER,UI_BEARER,TICKET_SECRET,LLM_API_KEY,CRIBL_CLIENT_ID,CRIBL_CLIENT_SECRETplain_envLLM_BASE_URL,LLM_MODEL,CRIBL_BASE_URL,CRIBL_DATASETuser_data.sh.tftplis deleted (the module owns it). Thebackendblock andproviderstay in this root unchanged. Outputs are re-exported soterraform output -raw cell_urlandinstance_idkeep working.Plan summary
12
movedblocks re-address every resource intomodule.fleet.*. Final plan:Moved with no replacement (10): the bucket + its 3 config resources, the IAM role / policy / attachment / instance profile, the security group, the EIP.
Replaced (2):
aws_instance.cellandaws_eip_association.cell(the association follows the instance id).Three
forces replacementlines, and it's worth being precise about why, because only one of them is this PR's doing:user_data— the generalized template differs textually underuser_data_replace_on_change = true. This is the designed adoption path.ami— the AL2023data.aws_ssm_parametertracks "latest" and the image rolled. Pre-existing drift, not caused by this refactor.instance_idon the association — a consequence of (1)/(2).I confirmed (2) by planning
origin/master's unmodified config against live state first: it also reported2 to add, 0 to change, 2 to destroyand also wanted the instance replaced. So the refactor itself contributes zero additional churn — same plan shape before and after.The security group did not churn
descriptionis a create-time argument onaws_security_group, and the group'snamederives fromcell_name, so both configs resolve toapm-cell-node— a same-name destroy/create that fights the attached instance. The module's generic wording would have triggered exactly that. Counterfactual, dropping the pin:Hence framework PR #34, which makes it an input so this root pins its original text. With the pin the SG is a pure move.
user_data is functionally identical
Rendered both templates with the live values and diffed: same six secret keys, same four
CELLD_VAR_*plain vars, same/var/log/apm-cell-init.log, both passbash -n. The systemd-unit heredoc changed from quoted to unquoted, but the body contains no$, so nothing expands unexpectedly. The diff is the generalization itself, nothing behavioral.One behavior change
The old template pulled the LLM/Cribl secrets only when
llm_base_urlwas non-empty — a stub-agent fallback. The module readssecret_env_keysunconditionally, so boot now fails loudly on any missing parameter. All six exist in the test account (verifiedSecureString, versions 1–2), so this is a no-op here. But "clearllm_base_urlto get stub mode" no longer works; shortensecret_env_keysinstead. Documented incell/infra/README.md.Verification on the live cell
Applied at ~16:08 UTC with nothing running or queued (
active (running/queued): 0)./healthz→{"ok":true,"disabled":false}, HTTP 200 within 15s.cloud-init status→done;celldandcaddybothactive; celld 0.2.0, Caddy 2.10.2.journalctl -u celld -p warning→-- No entries --. AllInvestigationDOreplicas restored from the bucket (restored remote replica … fresh=false), so durable state survived the replacement.CELLD_VAR_*secrets.frontend-proxyalert, concluded in ~2min, 47 frames: real KQL + PromQL against staging, correct root cause (product-catalogreturningProduct Not Foundfor garbage product IDs, cascading via thefrontendBFF), concluded throughpresent_investigation_summary.started+investigatedrows forinv-58d0afb1…present inotel(record_kind=="investigation").A
paymentalert I fired first hit the 12-turn cap and failed. That's pre-existing agent behavior, not infra:paymentfailed the same way at 05:27 today and afrontend-proxyrun failed at 15:52, both before this apply. Itsstarted/investigation_failedrows committed correctly, so the lifecycle path works. Worth a separate look at turn budget for services whose alert window has already gone quiet.Before merging
main.tfpoints at a sibling checkout (../../../cribl-search-app-framework/infra/celld-fleet), matching how the app consumes the framework's npm packages. Two consequences:.framework-shaneeds to move to a SHA that includes both the module and feat(service-detail): section-grouped layout + always-render metric cards #34 — the currently pinned1c37201predatesinfra/entirely, so a fresh clone can'tterraform initthis. (I planned against a worktree of feat(service-detail): section-grouped layout + always-render metric cards #34's branch; the committed path is what CI/other machines will use.)git::…?ref=<tag>source instead — the module README suggests it for CI. I left the sibling path to match repo convention, but I'd lean toward pinning it; happy to follow up.Test plan
🤖 Generated with Claude Code