feat(iac): scaffolding for Archera integration perms across AWS/Azure/GCP (closes #305)#310
feat(iac): scaffolding for Archera integration perms across AWS/Azure/GCP (closes #305)#310cristim wants to merge 3 commits into
Conversation
…/GCP (closes #305) Adds enable_archera = false tfvars flag to each cloud environment. When flipped to true, each cloud conditionally creates: - AWS: cross-account IAM role (cudly-archera-integration) with least- privilege Cost Explorer read + RI/SP purchase policy - Azure: custom RBAC role (CUDly Archera Integration) with cost read + reservation purchase actions, assigned to Archera's service principal - GCP: custom project IAM role (cudlyArcheraIntegration) with billing read + CUD purchase permissions, granted to Archera's service account All permission lists are clearly marked PROVISIONAL — they must be confirmed against Archera's integration docs before any environment sets enable_archera = true. TODO(@cristim) comments in archera.tf per cloud call this out explicitly. Per the bootstrap-vs-runtime IAM split: Archera is a runtime integration (cost telemetry reads + commitment purchases during normal operation), so archera.tf lives in the main environment alongside compute.tf, NOT in ci-cd-permissions/. README addendums added to all three cloud envs. terraform fmt and terraform validate pass for all three environments with the flag both on and off.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds gated Archera integration across AWS, Azure, and GCP: new variables and tfvars examples, per-cloud conditional IAM/RBAC resources (read-only + optional purchase actions), and README documentation describing enablement and resulting resources. Changes are confined to terraform/environments/*. ChangesArchera Integration Across Cloud Environments
Sequence Diagram(s)sequenceDiagram
autonumber
participant Operator
participant Terraform
participant CloudProvider
participant Archera
Operator->>Terraform: set enable_archera=true + cloud-specific identifier + external id (if AWS)
Terraform->>CloudProvider: create IAM/RBAC resources (role/role definition/custom role, policies, attachments) [conditional on flags]
CloudProvider-->>Terraform: return created resource ARNs/IDs
Archera->>CloudProvider: assume/act using created identity (uses ExternalId/trust or service account)
CloudProvider-->>Archera: grant access per created IAM/RBAC permissions
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
terraform/environments/azure/archera.tf (1)
55-59: ⚡ Quick winSeparate purchase capability behind a second explicit flag.
enable_archeracurrently enables both telemetry read and purchase write. A dedicatedenable_archera_purchase_actions(defaultfalse) reduces accidental financial writes during initial rollout.💡 Proposed refactor
resource "azurerm_role_definition" "archera_integration" { @@ permissions { - actions = [ + actions = concat([ # ── Read-only: Cost Management ────────────────────────────────────── @@ # ── Read-only: Reserved Instances ───────────────────────────────── @@ - # ── Purchase-execution: Reserved Instances ──────────────────────── - # TODO(`@cristim`): enable only after confirming approval workflow with - # Archera (i.e. Archera requires customer approval before purchases). - "Microsoft.Capacity/reservationOrders/write", - ] + ], var.enable_archera_purchase_actions ? [ + "Microsoft.Capacity/reservationOrders/write", + ] : []) not_actions = [] }# variables.tf (add) variable "enable_archera_purchase_actions" { description = "Allow Archera purchase actions (RI/SP). Keep false until approval workflow is confirmed." type = bool default = false }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@terraform/environments/azure/archera.tf` around lines 55 - 59, Current setup ties telemetry and purchase permissions to a single flag (enable_archera); add a new variable enable_archera_purchase_actions (bool, default false) and change the permission assembly where the write permission "Microsoft.Capacity/reservationOrders/write" is added so that it is included only when both enable_archera and enable_archera_purchase_actions are true; update any places referencing enable_archera to leave read/telemetry behavior unchanged and gate purchase-related actions/role bindings on enable_archera_purchase_actions in addition to enable_archera.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@terraform/environments/aws/archera.tf`:
- Around line 133-155: Split the high-risk purchase permissions (the statements
with Sid "ReservedInstancesPurchase" and "SavingsPlansPurchase") out of the
existing Archera IAM policy and move them into a new, separate IAM policy
resource; add a new boolean input variable enable_archera_purchase_actions and
conditionally create/attach that new purchase policy only when
enable_archera_purchase_actions is true, leaving the original enable_archera =
true behavior to continue granting only read/telemetry permissions; update any
IAM attachment/module invocation that currently uses the single policy to
reference both policies conditionally and preserve the TODO comments about
requiring Archera approval.
- Around line 32-47: Update the Archera role trust policy to require
sts:ExternalId by un-commenting and enforcing the Condition block (add the
StringEquals = { "sts:ExternalId" = var.archera_external_id } clause in the
assume_role_policy Statement for "ArcheraAssumeRole") so the trust policy always
validates ExternalId when Archera assumes the role; additionally add a new
Terraform variable archera_external_id (string) and in the variables.tf add
validation that it is non-empty and required whenever enable_archera is true
(use a validation rule or conditional check to fail plan/apply if enable_archera
&& var.archera_external_id == ""), referencing the existing enable_archera flag
and the archera_external_id variable in the module.
In `@terraform/environments/azure/variables.tf`:
- Around line 545-556: Add a Terraform variable validation for
archera_azure_sp_object_id that enforces a non-empty, well-formed value when
enable_archera is true: inside the variable "archera_azure_sp_object_id"
declaration add a validation block that checks (var.enable_archera == false) OR
(the value is not empty and matches a GUID/UUID pattern) and return a clear
error message if the check fails; reference var.enable_archera and
var.archera_azure_sp_object_id in the validation to ensure early, descriptive
failure instead of deferring to apply-time role assignment.
In `@terraform/environments/gcp/archera.tf`:
- Around line 55-60: The listed permission
recommender.commitmentUtilizationInsights.update grants write access and should
be removed from the read-only block; edit the array where
"recommender.commitmentUtilizationInsights.update" appears (near the read-only
Recommender / Committed Use Discounts section) and delete that entry so only
"recommender.commitmentUtilizationInsights.get" and
"recommender.commitmentUtilizationInsights.list" remain, preserving formatting
and comments around the block.
In `@terraform/environments/gcp/variables.tf`:
- Around line 493-506: Add a validation block to the variable
"archera_gcp_service_account" so Terraform will fail fast when enable_archera is
true and the service account is empty or malformed; specifically, add a
conditional check that if var.enable_archera == true then
var.archera_gcp_service_account must be non-empty and match an
email/service-account pattern (e.g., user@project.iam.gserviceaccount.com) to
prevent creating a member value of "serviceAccount:". Update the variable
"archera_gcp_service_account" definition to include the validation rule and an
appropriate error_message referencing the variable and the enable_archera flag
so callers know to provide a valid service account email before applying.
---
Nitpick comments:
In `@terraform/environments/azure/archera.tf`:
- Around line 55-59: Current setup ties telemetry and purchase permissions to a
single flag (enable_archera); add a new variable enable_archera_purchase_actions
(bool, default false) and change the permission assembly where the write
permission "Microsoft.Capacity/reservationOrders/write" is added so that it is
included only when both enable_archera and enable_archera_purchase_actions are
true; update any places referencing enable_archera to leave read/telemetry
behavior unchanged and gate purchase-related actions/role bindings on
enable_archera_purchase_actions in addition to enable_archera.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: eccb27a1-a829-47ef-8961-73ecc27f9382
📒 Files selected for processing (12)
terraform/environments/aws/README.mdterraform/environments/aws/archera.tfterraform/environments/aws/dev.tfvars.exampleterraform/environments/aws/variables.tfterraform/environments/azure/README.mdterraform/environments/azure/archera.tfterraform/environments/azure/dev.tfvars.exampleterraform/environments/azure/variables.tfterraform/environments/gcp/README.mdterraform/environments/gcp/archera.tfterraform/environments/gcp/dev.tfvars.exampleterraform/environments/gcp/variables.tf
…lit, validation AWS: - enforce ExternalId in assume-role trust policy (confused-deputy protection) - split archera_purchase into a separate IAM policy gated by enable_archera_purchase_actions (default false) so read-only rollouts never accidentally include financial writes - add archera_external_id variable (sensitive, required when enable_archera=true) - add enable_archera_purchase_actions variable (bool, default false) Azure: - add UUID validation on archera_azure_sp_object_id when enable_archera=true - add enable_archera_purchase_actions variable; gate reservationOrders/write behind it via concat() so the initial rollout is read-only GCP: - remove recommender.commitmentUtilizationInsights.update (write action incorrectly placed in read-only block) - add email format validation on archera_gcp_service_account when enable_archera=true - add enable_archera_purchase_actions variable; gate recommender.commitments.create behind it via concat() All environments: dev.tfvars.example updated to include enable_archera_purchase_actions = false terraform fmt + validate pass for all three clouds.
CodeRabbit review — round 1 fixes (commit f3ba36a)All 5 Actionable items addressed, plus the Nitpick: AddressedAWS
Azure
GCP
All clouds:
@coderabbitai review |
|
Tip For best results, initiate chat on the files or code changes.
Triggering a fresh review of commit [review] |
|
@coderabbitai full review The 10 min since the previous re-review trigger have passed without a posted review. Please review commit f3ba36a which addresses the 5 actionable items + 1 nitpick from your round-1 review (ExternalId enforcement, AWS read/purchase policy split, Azure UUID validation, GCP removed update perm, GCP email validation, all clouds gained enable_archera_purchase_actions flag). |
|
Tip For best results, initiate chat on the files or code changes.
[full_review] |
|
@coderabbitai resolve The previous |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@terraform/environments/aws/README.md`:
- Around line 48-76: Update the README enablement example and resource table to
match the current Terraform split: add the required archera_external_id variable
and mention the optional enable_archera_purchase_actions flag; replace
references to the removed aws_iam_policy.archera_integration and
aws_iam_role_policy_attachment.archera_integration with
aws_iam_policy.archera_read and aws_iam_role_policy_attachment.archera_read, and
add entries for aws_iam_policy.archera_purchase and
aws_iam_role_policy_attachment.archera_purchase (note purchase policy is
conditional on enable_archera_purchase_actions), and ensure the example shows
enabling enable_archera = true alongside archera_aws_account_id and
archera_external_id.
In `@terraform/environments/aws/variables.tf`:
- Around line 503-515: Add a validation block to the variable
"archera_aws_account_id" so that when set it must be a 12-digit AWS account ID;
specifically ensure the value is either empty or matches the regex for twelve
digits (e.g., ^\d{12}$) and provide a clear message referencing enable_archera;
also update aws/archera.tf to guard generation of the trust principal ARN with
var.enable_archera to avoid building an ARN from an empty/malformed ID.
In `@terraform/environments/azure/README.md`:
- Around line 43-70: Update the README's "Enabling Archera" section to
accurately document the purchase-action flag: clarify that reservation purchase
write permission ("Microsoft.Capacity/reservationOrders/write") is only added
when enable_archera_purchase_actions = true, show the optional tfvars entry for
enable_archera_purchase_actions, and adjust the table entry for
azurerm_role_definition.archera_integration[0] to state it provides read-only
cost access by default and only adds RI purchase writes when
enable_archera_purchase_actions is enabled; reference the enable_archera and
archera_azure_sp_object_id example and the
azurerm_role_definition.archera_integration[0] and
azurerm_role_assignment.archera_integration[0] resources so operators review the
correct permission set before flipping flags.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 13a8b046-446b-4011-a64a-06ddc17c2758
📒 Files selected for processing (12)
terraform/environments/aws/README.mdterraform/environments/aws/archera.tfterraform/environments/aws/dev.tfvars.exampleterraform/environments/aws/variables.tfterraform/environments/azure/README.mdterraform/environments/azure/archera.tfterraform/environments/azure/dev.tfvars.exampleterraform/environments/azure/variables.tfterraform/environments/gcp/README.mdterraform/environments/gcp/archera.tfterraform/environments/gcp/dev.tfvars.exampleterraform/environments/gcp/variables.tf
…review Address 3 actionable findings from CodeRabbit's review of f3ba36a: 1. AWS README — sync with read/purchase split: add `archera_external_id` to enablement example, mention optional `enable_archera_purchase_actions` flag, replace stale `archera_integration` policy/attachment table entries with `archera_read` + `archera_purchase`. 2. AWS variables.tf — add validation block to `archera_aws_account_id` that fails fast if the value isn't a 12-digit account ID when `enable_archera = true` (avoids building an invalid trust principal ARN at apply time). 3. Azure README — clarify that reservation purchase write permission is gated on `enable_archera_purchase_actions = true`, not `enable_archera` alone; adjust the role-definition row to match. `terraform validate` passes for AWS and Azure with the new validation block.
|
@coderabbitai review CR-pass-2 fixes pushed in f8daec6:
|
|
Tip For best results, initiate chat on the files or code changes.
[review] |
|
@coderabbitai full review The previous |
|
Tip For best results, initiate chat on the files or code changes.
[full_review] |
CR loop complete — all 3 actionable items addressed
CI: all 4 checks green (sanity AWS, sanity Azure, frontend build, pre-commit). Per-thread fix confirmations posted above (replies to each CR comment with the specific resolution). |
Architectural pivot — shared module + thin callerAfter discussion with @cristim and a second agent, the consensus is to NOT keep this PR's Archera implementation as inline New shapeBoth Terraform call sites become thin module-wrapper files: # terraform/environments/aws/archera.tf (this PR — was inline)
module "archera" {
source = "../../iac/modules/archera/aws"
enable_archera = var.enable_archera
archera_aws_account_id = var.archera_aws_account_id
archera_external_id = var.archera_external_id
enable_archera_purchase_actions = var.enable_archera_purchase_actions
}
# iac/federation/aws-target/terraform/archera.tf (#314 — same module, same shape)
module "archera" { source = "../../../modules/archera/aws"; ... }Non-Terraform formats (CFN/Bicep/ARM, used by federation bundles) load the action list from What this means for this PRThis PR will be reshaped to land:
CFN/Bicep/ARM rendering, federation bundle plumbing, frontend checkbox, and the parity check are scoped to #314 — not this PR. CI gate
CoordinationA consensus sync has been posted to the multi-agent bus at |
Correction to my earlier commentRe-verified the bundle-flag worktree state with a parallel agent (
Coordination record: see |
|
Closing this one since we decided to implement this as part of #314 |
…cation pages (closes #314) Introduces the Archera Insurance CTA at the two high-intent moments where a user is about to commit money, plus two education pages that explain what Archera Insurance is and how the integration works. **New module — frontend/src/archera.ts** - `renderArcheraCTA()`: returns a small, muted <p> with an inline <button> that reads "Worried about committing? Archera Insurance underwrites commitment-overuse — learn how it works →". Placed below the approval note in the Purchase modal, and before the Save/Cancel row in Plan-creation modals. - `openArcheraPage('what-is-archera' | 'how-it-works')`: renders a full-viewport overlay panel using DOM methods only (no innerHTML). Doesn't touch SPA routing state or the URL. - `closeArcheraPage()`: hides + clears the overlay. - `ARCHERA_SIGNUP_URL = 'https://archera.ai/signup?mode=cudly'` for attribution-tagged referral links. **Page A — "What is Archera Insurance?"** Plain-language explainer: commitment-overuse insurance, how Archera earns (sharing-of-savings), when it makes sense, what CUDly's role is. Cross-links to Page B. Signup link at bottom (target=_blank, rel="noopener noreferrer"). **Page B — "How the CUDly ↔ Archera integration works"** Step-by-step: sign up → Archera generates pre-filled IaC for AWS/GCP (or OAuth consent for Azure) → Archera ingests cost data → purchase commitments normally through CUDly. Disclaimers: Archera is third-party, no credentials stored in CUDly. Cross-links to Page A. Signup link at bottom. TODO(@cristim) markers flag all copy that needs final review. **Modal integration** - `recommendations.ts / openPurchaseModal`: appends `renderArcheraCTA()` inside `#purchase-details`, below the approval note. - `plans.ts / openCreatePlanModal + openNewPlanModal`: calls `injectPlanModalCTA()` (guarded against duplication with an id check) to insert the CTA before `.modal-buttons` in `#plan-form`. **CSS (styles/modals.css)**: `.archera-cta`, `.archera-cta-link`, `#archera-page-container`, `.archera-page-inner`, `.archera-page-back`, `.archera-signup-block`, `.archera-signup-btn`, `.archera-signup-note`. **HTML (index.html)**: adds `<div id="archera-page-container" role="region" aria-label="Archera Insurance information">` (hidden by default) before the modal stack. **Tests (archera.test.ts)**: 26 assertions covering renderArcheraCTA structure, page A/B content + crosslinks + signup link attributes, closeArcheraPage, and CTA injection in both Purchase and Plan modals. Nothing in backend/, cmd/, internal/, iac/, terraform/, or scripts/ is touched. This is a frontend-only change. Supersedes PR #310 and PR #315 (closed without merging; earlier iterations bundled IAM/IaC which was rejected by Archera-side review — see issue #314 for history).
Summary
Adds
enable_archera = falsescaffolding to all three cloud environments (AWS, Azure, GCP) so non-Archera customers see no drift. When a customer setsenable_archera = true, the IaC creates the minimal identity grants needed by Archera's integration.What's in each cloud
AWS (
terraform/environments/aws/archera.tf)enable_archera(bool, defaultfalse),archera_aws_account_id(string, default"")aws_iam_role(cudly-archera-integration) trusted byarn:aws:iam::<archera_aws_account_id>:root, with anaws_iam_policycovering:ce:Get*,ce:List*), CUR (cur:DescribeReportDefinitions), Reserved Instances (ec2:Describe*), Savings Plans (savingsplans:Describe*)ec2:PurchaseReservedInstancesOffering,ec2:ModifyReservedInstances,savingsplans:CreateSavingsPlanAzure (
terraform/environments/azure/archera.tf)enable_archera,archera_azure_sp_object_idazurerm_role_definition(custom, subscription-scoped) withMicrosoft.CostManagement/*/read,Microsoft.Consumption/*/read,Microsoft.Billing/*/read,Microsoft.Capacity/reservations/read,Microsoft.Capacity/reservationOrders/read|writeazurerm_role_assignmentto Archera's service principal (principal_type = "ServicePrincipal")GCP (
terraform/environments/gcp/archera.tf)enable_archera,archera_gcp_service_accountgoogle_project_iam_custom_role(stage=BETA, project-scoped) with billing read, recommender CUD read + creategoogle_project_iam_memberbinding to Archera's service accountIAM split placement
Per the repo's bootstrap-vs-runtime split (CLAUDE.md §"CI/CD IAM"): Archera is a runtime integration — it reads cost telemetry and executes purchases during normal operation, not during Terraform deploys. All three
archera.tffiles therefore live in the main environment (alongsidecompute.tf,database.tf) rather than inci-cd-permissions/.Verification
terraform fmt -checkclean on all 3 environmentsterraform validatepasses on all 3 environments withenable_archera = false(default, count=0).tfvarsfiles modified — only.examplefiles updatedOut of scope (follow-up PRs)
Per the issue body's suggestion of three per-cloud sub-PRs: this single scaffolding PR lands the structural gating and provisional lists for all three clouds at once (lower review risk since nothing is enabled by default). Separate follow-up PRs per cloud can narrow the scope list once Archera's docs are consulted.
Test plan
@cristimconfirms the scope list against Archera's integration docs (or narrows it)enable_archera = truein the target environment's tfvars and runsterraform plan— no new resources should appear for other environmentsenable_archera = truecreates 3 resources: role, policy, attachmentSummary by CodeRabbit
New Features
Documentation