Skip to content

feat(iac): scaffolding for Archera integration perms across AWS/Azure/GCP (closes #305)#310

Closed
cristim wants to merge 3 commits into
feat/multicloud-web-frontendfrom
feat/issue-305-archera-iac-perms
Closed

feat(iac): scaffolding for Archera integration perms across AWS/Azure/GCP (closes #305)#310
cristim wants to merge 3 commits into
feat/multicloud-web-frontendfrom
feat/issue-305-archera-iac-perms

Conversation

@cristim
Copy link
Copy Markdown
Member

@cristim cristim commented May 5, 2026

Summary

Adds enable_archera = false scaffolding to all three cloud environments (AWS, Azure, GCP) so non-Archera customers see no drift. When a customer sets enable_archera = true, the IaC creates the minimal identity grants needed by Archera's integration.

SCOPE LIST IS PROVISIONAL — the exact IAM permissions/RBAC actions required by Archera have not yet been confirmed against Archera's integration docs. The lists in each archera.tf are best-effort read-only cost data + commitment purchase scopes. Do NOT merge with enable_archera = true in any environment until @cristim has confirmed the scope list against Archera's actual onboarding guide.

What's in each cloud

AWS (terraform/environments/aws/archera.tf)

  • New variables: enable_archera (bool, default false), archera_aws_account_id (string, default "")
  • When enabled: cross-account aws_iam_role (cudly-archera-integration) trusted by arn:aws:iam::<archera_aws_account_id>:root, with an aws_iam_policy covering:
    • Read-only: Cost Explorer (ce:Get*, ce:List*), CUR (cur:DescribeReportDefinitions), Reserved Instances (ec2:Describe*), Savings Plans (savingsplans:Describe*)
    • Purchase-execution (provisional): ec2:PurchaseReservedInstancesOffering, ec2:ModifyReservedInstances, savingsplans:CreateSavingsPlan
  • ExternalId condition stub is commented in for easy activation once Archera provides it

Azure (terraform/environments/azure/archera.tf)

  • New variables: enable_archera, archera_azure_sp_object_id
  • When enabled: azurerm_role_definition (custom, subscription-scoped) with Microsoft.CostManagement/*/read, Microsoft.Consumption/*/read, Microsoft.Billing/*/read, Microsoft.Capacity/reservations/read, Microsoft.Capacity/reservationOrders/read|write
  • azurerm_role_assignment to Archera's service principal (principal_type = "ServicePrincipal")

GCP (terraform/environments/gcp/archera.tf)

  • New variables: enable_archera, archera_gcp_service_account
  • When enabled: google_project_iam_custom_role (stage=BETA, project-scoped) with billing read, recommender CUD read + create
  • google_project_iam_member binding to Archera's service account

IAM 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.tf files therefore live in the main environment (alongside compute.tf, database.tf) rather than in ci-cd-permissions/.

Verification

  • terraform fmt -check clean on all 3 environments
  • terraform validate passes on all 3 environments with enable_archera = false (default, count=0)
  • No existing .tfvars files modified — only .example files updated

Out 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

  • @cristim confirms the scope list against Archera's integration docs (or narrows it)
  • Once confirmed, a follow-up PR flips enable_archera = true in the target environment's tfvars and runs terraform plan — no new resources should appear for other environments
  • AWS: plan with enable_archera = true creates 3 resources: role, policy, attachment
  • Azure: plan creates 2 resources: role definition, role assignment
  • GCP: plan creates 2 resources: custom role, IAM member

Summary by CodeRabbit

  • New Features

    • Added optional Archera integration for AWS, Azure, and GCP environments (disabled by default). Can be enabled via environment variables and includes an optional "purchase actions" flag to permit buy-side operations.
  • Documentation

    • Added provider-specific README guidance covering enablement steps, required identifiers, and a summary of resources that will be created when the integration is enabled.

…/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.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e6bc1db5-7e75-4ac4-a5ff-02489df85a4c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds 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/*.

Changes

Archera Integration Across Cloud Environments

Layer / File(s) Summary
Variables / Public Inputs
terraform/environments/*/variables.tf
Adds enable_archera (bool, default false) in AWS/Azure/GCP and cloud-specific identifiers: archera_aws_account_id, archera_external_id (AWS), archera_azure_sp_object_id (Azure), archera_gcp_service_account (GCP). Includes validations (ExternalId non-empty when enabled; UUID/email format checks where applicable).
Local Constants
terraform/environments/aws/archera.tf, .../gcp/archera.tf, .../azure/archera.tf
Defines local role/name constants (local.archera_role_name, local.archera_custom_role_id, local.archera_role_name_azure) used by role/definition resources.
Core Cloud Implementation
terraform/environments/aws/archera.tf, terraform/environments/azure/archera.tf, terraform/environments/gcp/archera.tf
Implements conditional Archera integration resources: AWS cross-account aws_iam_role with trust policy and aws_iam_policy(read) plus optional purchase policy; Azure azurerm_role_definition and azurerm_role_assignment with optional reservation write; GCP google_project_iam_custom_role and google_project_iam_member with optional purchase action. All resources use count = var.enable_archera ? 1 : 0 (and additional gating for purchase actions).
Examples / Wiring
terraform/environments/*/dev.tfvars.example
Adds Archera sections and example settings: enable_archera = false, enable_archera_purchase_actions = false, and commented placeholders for cloud-specific identifiers and external ID examples.
Documentation
terraform/environments/*/README.md
Adds "Archera Integration" sections per-cloud describing gating (default disabled), how to enable (which tfvars to set), prerequisites (service principal/account id/external id), and lists the Terraform resources created when enabled.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

"I hopped through clouds with careful paws,
Flags held low to avoid surprise,
Roles and scopes in tidy laws,
A rabbit cheers with eager eyes,
Archera now may claim the prize."

🚥 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 accurately and specifically describes the main change: scaffolding for Archera integration permissions across three cloud platforms (AWS/Azure/GCP). It is concise, clear, and directly summarizes the primary objective of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-305-archera-iac-perms

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

@cristim cristim added priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-quarter Within the quarter impact/many Affects most users effort/m Days type/feat New capability triaged Item has been triaged labels May 5, 2026
@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 5, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
terraform/environments/azure/archera.tf (1)

55-59: ⚡ Quick win

Separate purchase capability behind a second explicit flag.

enable_archera currently enables both telemetry read and purchase write. A dedicated enable_archera_purchase_actions (default false) 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

📥 Commits

Reviewing files that changed from the base of the PR and between f83c914 and e869eba.

📒 Files selected for processing (12)
  • terraform/environments/aws/README.md
  • terraform/environments/aws/archera.tf
  • terraform/environments/aws/dev.tfvars.example
  • terraform/environments/aws/variables.tf
  • terraform/environments/azure/README.md
  • terraform/environments/azure/archera.tf
  • terraform/environments/azure/dev.tfvars.example
  • terraform/environments/azure/variables.tf
  • terraform/environments/gcp/README.md
  • terraform/environments/gcp/archera.tf
  • terraform/environments/gcp/dev.tfvars.example
  • terraform/environments/gcp/variables.tf

Comment thread terraform/environments/aws/archera.tf
Comment thread terraform/environments/aws/archera.tf
Comment thread terraform/environments/azure/variables.tf
Comment thread terraform/environments/gcp/archera.tf Outdated
Comment thread terraform/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.
@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 5, 2026

CodeRabbit review — round 1 fixes (commit f3ba36a)

All 5 Actionable items addressed, plus the Nitpick:

Addressed

AWS

  • ✅ ExternalId enforcement: added archera_external_id variable (sensitive = true, validation requires non-empty when enable_archera = true); trust policy now unconditionally requires StringEquals { sts:ExternalId } (confused-deputy protection)
  • ✅ Purchase/read split: aws_iam_policy.archera_read (attached when enable_archera = true) and aws_iam_policy.archera_purchase (attached only when both enable_archera and enable_archera_purchase_actions are true) — financial writes are never included at read-only rollout
  • ✅ Added enable_archera_purchase_actions variable (bool, default false)

Azure

  • ✅ UUID validation on archera_azure_sp_object_id when enable_archera = true (regex ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-...{12}$)
  • ✅ Added enable_archera_purchase_actions variable; Microsoft.Capacity/reservationOrders/write gated via concat() behind the flag

GCP

  • ✅ Removed recommender.commitmentUtilizationInsights.update (write action incorrectly placed in the read-only block)
  • ✅ Email format validation on archera_gcp_service_account when enable_archera = true (regex ^[^@]+@[^.]+\.iam\.gserviceaccount\.com$)
  • ✅ Added enable_archera_purchase_actions variable; recommender.commitments.create gated via concat() behind the flag

All clouds: dev.tfvars.example updated with enable_archera_purchase_actions = false

terraform fmt -check + terraform validate pass for all three clouds.

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Tip

For best results, initiate chat on the files or code changes.

@cristim: Excellent work on the round 1 fixes! The changes look well-structured:

  • AWS: The ExternalId enforcement is a critical security improvement for confused-deputy protection, and the read/purchase policy split is a great least-privilege approach.
  • Azure: UUID validation and the concat()-gated write permission are solid guards.
  • GCP: Removing the misplaced write action and adding email format validation clean things up nicely.

Triggering a fresh review of commit f3ba36a now.

[review]

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 5, 2026

@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).

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Tip

For best results, initiate chat on the files or code changes.

@cristim: Understood! Triggering a full review of PR #310 now, covering commit f3ba36a and all the changes addressed in round 1:

  • AWS: ExternalId enforcement in the trust policy (confused-deputy protection), read/purchase IAM policy split (archera_read vs archera_purchase), and new enable_archera_purchase_actions variable.
  • Azure: UUID validation on archera_azure_sp_object_id, Microsoft.Capacity/reservationOrders/write gated behind enable_archera_purchase_actions.
  • GCP: Removed recommender.commitmentUtilizationInsights.update from the read block, email format validation on archera_gcp_service_account, recommender.commitments.create gated behind enable_archera_purchase_actions.
  • All clouds: dev.tfvars.example updated with enable_archera_purchase_actions = false.

[full_review]

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 5, 2026

@coderabbitai resolve

The previous [full_review] acknowledgment 25 min ago has not produced a posted review. Please re-attempt the full review now of commit f3ba36a. If you've already verified all round-1 actionables are addressed and have no new findings, please acknowledge with an explicit comment so this PR can be marked review-complete.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between f83c914 and f3ba36a.

📒 Files selected for processing (12)
  • terraform/environments/aws/README.md
  • terraform/environments/aws/archera.tf
  • terraform/environments/aws/dev.tfvars.example
  • terraform/environments/aws/variables.tf
  • terraform/environments/azure/README.md
  • terraform/environments/azure/archera.tf
  • terraform/environments/azure/dev.tfvars.example
  • terraform/environments/azure/variables.tf
  • terraform/environments/gcp/README.md
  • terraform/environments/gcp/archera.tf
  • terraform/environments/gcp/dev.tfvars.example
  • terraform/environments/gcp/variables.tf

Comment thread terraform/environments/aws/README.md Outdated
Comment thread terraform/environments/aws/variables.tf
Comment thread terraform/environments/azure/README.md
…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.
@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 5, 2026

@coderabbitai review

CR-pass-2 fixes pushed in f8daec6:

  • AWS README — sync with read/purchase split (added archera_external_id + noted optional enable_archera_purchase_actions; replaced stale archera_integration table entries with archera_read + archera_purchase)
  • AWS variables.tf — added 12-digit archera_aws_account_id validation gated on enable_archera = true
  • Azure README — clarified purchase-write permission is conditional on enable_archera_purchase_actions

terraform validate clean for AWS and Azure.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Tip

For best results, initiate chat on the files or code changes.

@cristim: Thanks for the CR-pass-2 summary! Triggering a review of commit f8daec6 now, covering:

  • AWS README: Synced with the read/purchase policy split, archera_external_id added, optional enable_archera_purchase_actions noted, and stale archera_integration table entries replaced with archera_read + archera_purchase.
  • AWS variables.tf: 12-digit numeric validation for archera_aws_account_id gated on enable_archera = true.
  • Azure README: Clarified that the reservationOrders/write permission is conditional on enable_archera_purchase_actions.

[review]

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 5, 2026

@coderabbitai full review

The previous @coderabbitai review ack at 21:34 has not produced a posted review in 30+ minutes. Please run a full review on the latest commit (f8daec6) — the changes are docs (AWS README + Azure README) plus a 12-digit validation block on archera_aws_account_id, addressing the 3 actionable items from your 21:22 review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Tip

For best results, initiate chat on the files or code changes.

@cristim: Apologies for the delays — triggering a full review of commit f8daec6 now. The scope I'll cover:

  • AWS README: Sync with read/purchase policy split — archera_external_id documented, optional enable_archera_purchase_actions noted, stale archera_integration table entries replaced with archera_read + archera_purchase.
  • AWS variables.tf: 12-digit numeric validation on archera_aws_account_id gated on enable_archera = true.
  • Azure README: Clarification that reservationOrders/write is conditional on enable_archera_purchase_actions.

[full_review]

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 5, 2026

CR loop complete — all 3 actionable items addressed

# File CR finding Fix in f8daec6
1 terraform/environments/aws/README.md docs stale post read/purchase split Added archera_external_id + optional enable_archera_purchase_actions to the enablement example; replaced archera_integration table entries with archera_read + archera_purchase (purchase conditional on the flag)
2 terraform/environments/aws/variables.tf missing 12-digit validation on archera_aws_account_id Added validation block: ^\d{12}$ regex with trimspace, gated on !var.enable_archera || .... terraform validate clean.
3 terraform/environments/azure/README.md docs imply purchase writes always granted Clarified that Microsoft.Capacity/reservationOrders/write is conditional on enable_archera_purchase_actions = true; added the optional flag to the tfvars snippet; updated the azurerm_role_definition row

CI: all 4 checks green (sanity AWS, sanity Azure, frontend build, pre-commit).
Mergeable: CLEAN.

Per-thread fix confirmations posted above (replies to each CR comment with the specific resolution).

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 6, 2026

Architectural pivot — shared module + thin caller

After discussion with @cristim and a second agent, the consensus is to NOT keep this PR's Archera implementation as inline terraform/environments/<cloud>/archera.tf files. Both the CUDly self-deploy (this PR) AND the customer-facing federation bundles (#314) need Archera permissions, so we want a single source of truth rather than two parallel implementations + a parity-script.

New shape

iac/modules/archera/
├── aws/
│   ├── main.tf          # role + read policy + optional purchase policy
│   ├── variables.tf     # enable_archera, archera_aws_account_id,
│   │                    # archera_external_id, enable_archera_purchase_actions
│   └── outputs.tf
├── azure/                # custom RBAC role + assignment
├── gcp/                  # service account + IAM bindings
└── scope.{aws,azure,gcp}.yaml   # canonical permission list (the source of truth)

Both 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 scope.<cloud>.yaml at bundle-render time on our side (deploy-time Fn::Transform / Bicep loadJsonContent isn't viable for customer-distributed bundles — must be pre-baked).

What this means for this PR

This PR will be reshaped to land:

  • New iac/modules/archera/{aws,azure,gcp}/ module trees
  • New iac/modules/archera/scope.{aws,azure,gcp}.yaml source-of-truth files
  • terraform/environments/<cloud>/archera.tf rewritten as thin module callers (replaces the current inline implementation)

CFN/Bicep/ARM rendering, federation bundle plumbing, frontend checkbox, and the parity check are scoped to #314 — not this PR.

CI gate

scripts/check-archera-scope.sh (lands with #314) diffs the rendered CFN/Bicep/ARM action lists against scope.<cloud>.yaml. Terraform parity is automatic — both call sites consume the same module — so no Terraform-vs-Terraform diff is needed. This replaces the earlier check-archera-parity.sh proposal in #314's body.

Coordination

A consensus sync has been posted to the multi-agent bus at ~/.claude/agent-comms/messages/sync-2026-05-06T010500Z-archera-architecture-agreed.md so any agent picking up follow-up Archera work has the same context.

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 6, 2026

Correction to my earlier comment

Re-verified the bundle-flag worktree state with a parallel agent (pr-314-resume):

Coordination record: see ~/.claude/agent-comms/messages/sync-2026-05-06T232500Z-archera-agreement-confirmed.md.

@cristim cristim closed this May 6, 2026
@cristim cristim deleted the feat/issue-305-archera-iac-perms branch May 6, 2026 12:14
@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 6, 2026

Closing this one since we decided to implement this as part of #314

cristim added a commit that referenced this pull request May 11, 2026
…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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/m Days impact/many Affects most users priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/feat New capability urgency/this-quarter Within the quarter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant