Skip to content

docs: add cpflow vs. Terraform guidance for Control Plane#751

Open
justin808 wants to merge 1 commit into
masterfrom
jg-conductor/control-plane-terraform-migration
Open

docs: add cpflow vs. Terraform guidance for Control Plane#751
justin808 wants to merge 1 commit into
masterfrom
jg-conductor/control-plane-terraform-migration

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented May 30, 2026

Summary

Readers see Control Plane's official cpln Terraform provider and ask whether the .controlplane/templates/*.yml files should be Terraform instead. This adds a focused doc that answers it.

The key insight: the YAML in .controlplane/ covers two concerns, and Terraform only addresses one of them.

  1. controlplane.yml — cpflow's own orchestration config (app/org aliases, app_workloads, release_script, upstream promotion, review-app prefix matching). No Terraform equivalent.
  2. templates/*.yml — native cpln apply resource manifests. These could be cpln_* Terraform resources.

Terraform does not replace the cpflow app lifecycle (build-image/deploy-image, release-phase migrations, ephemeral per-PR review apps, staging→production promotion), so for this tutorial app the recommendation is to stay on cpflow.

What's in the doc

  • A decision-rule table (when cpflow vs. when Terraform).
  • A concrete HCL appendix mapping templates/app.yml + templates/rails.yml to cpln_gvc / cpln_identity / cpln_workload, with inline comments calling out exactly where the two models diverge (per-PR {{APP_NAME}} interpolation, deploy-time {{APP_IMAGE_LINK}} injection, and the provision-vs-deploy separation).

Changes

  • New .controlplane/docs/cpflow-vs-terraform.md.
  • One pointer link added to .controlplane/readme.md's Project Configuration section.

Docs-only; no code or deploy behavior changes.

🤖 Generated with Claude Code


Note

Low Risk
Documentation-only changes with no runtime, deploy, or infrastructure behavior impact.

Overview
Adds .controlplane/docs/cpflow-vs-terraform.md to explain why this tutorial app keeps cpflow instead of moving .controlplane YAML to the official cpln Terraform provider. The doc splits controlplane.yml (orchestration with no TF equivalent) from templates/*.yml (could be cpln_* resources), lists what Terraform does not cover (build/deploy, release migrations, review apps, promotion), and gives a cpflow vs Terraform decision table.

An HCL appendix maps templates/app.yml and templates/rails.yml to cpln_gvc, cpln_identity, and cpln_workload, with comments on divergences like {{APP_NAME}}, deploy-time {{APP_IMAGE_LINK}}, and provision vs deploy.

.controlplane/readme.md gains a short link under Project Configuration pointing readers to that doc.

Reviewed by Cursor Bugbot for commit 8bf6e3a. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Documentation
    • Added documentation explaining cpflow configuration management versus Terraform approaches, including field-by-field mapping examples
    • Updated configuration guide with reference to new comparison documentation

Review Change Stack

Readers see the official cpln Terraform provider and ask whether the
.controlplane/templates/*.yml files should be Terraform instead. Add a
focused doc that answers it: the YAML covers two concerns (cpflow's own
controlplane.yml orchestration config vs. cpln apply resource manifests),
and Terraform only addresses the latter. Includes a decision rule and a
concrete HCL mapping of app.yml + rails.yml to cpln_gvc/cpln_workload so
the trade-offs (per-PR interpolation, deploy-time image injection,
provision-vs-deploy separation) are visible.

Linked from .controlplane/readme.md's Project Configuration section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions
Copy link
Copy Markdown

🚀 Quick Review App Commands

Welcome! Here are the commands you can use in this PR:
They require the repository to have cpflow review apps configured, including the CPLN_TOKEN_STAGING secret.

+review-app-deploy

Deploy your PR branch for testing.

+review-app-delete

Remove the review app when done.

+review-app-help

Show detailed instructions, environment setup, and configuration options.

Comment +review-app-help for full setup details.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d6d6a7b-98a0-4a98-bbfd-1f6faff567f3

📥 Commits

Reviewing files that changed from the base of the PR and between 6378189 and 8bf6e3a.

📒 Files selected for processing (2)
  • .controlplane/docs/cpflow-vs-terraform.md
  • .controlplane/readme.md

Walkthrough

This PR adds documentation that clarifies the division between cpflow and Terraform. A new document explains why cpflow-managed YAML is not a Terraform substitute, then provides a conceptual Terraform HCL mapping for key templates and notes feature gaps. The readme links to this resource for trade-offs context.

Changes

cpflow vs Terraform Documentation

Layer / File(s) Summary
Documentation contrast and HCL mapping
​.controlplane/docs/cpflow-vs-terraform.md, ​.controlplane/readme.md
New documentation contrasts cpflow's app lifecycle scope (deploy loops, release migrations, review apps) against Terraform's durable infrastructure role, includes an appendix mapping cpflow templates to Terraform HCL for GVC, workload, and identity, and identifies features like controlplane.yml release scripts and upstream promotion that lack Terraform representation. The readme adds a navigation link to this resource.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

🐰 A map for the confused, a chart for the wise,
cpflow flows through the app, from build to sunrise,
While Terraform's bedrock holds infrastructure dear—
Now both paths are clear!

🚥 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 clearly and concisely summarizes the main change: adding documentation that compares cpflow and Terraform for Control Plane management, which aligns with 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 jg-conductor/control-plane-terraform-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 30, 2026

Greptile Summary

This PR adds a new docs/cpflow-vs-terraform.md document that explains when to use cpflow versus the official cpln Terraform provider for Control Plane deployments, and adds a single pointer line to the existing readme.md. The doc is accurate and well-reasoned; two small HCL syntax issues in the appendix code block would cause terraform validate failures for readers who copy the snippets directly.

  • New doc (cpflow-vs-terraform.md): decision table, rationale for staying on cpflow in this tutorial, and an HCL appendix mapping app.yml + rails.yml to cpln_gvc / cpln_identity / cpln_workload resources.
  • readme.md update: three-line pointer added to the Project Configuration section; relative path resolves correctly to the new file.

Confidence Score: 4/5

Docs-only change with no impact on deployed code or infrastructure; safe to merge after fixing the two HCL snippet issues.

All changes are documentation. The new file is well-reasoned and the readme.md pointer is correct. Two HCL syntax mistakes in the appendix code block — an invalid inline multi-attribute variable declaration and a port number expressed as a string — would cause copy-paste failures for any reader who tries to apply the snippets directly.

.controlplane/docs/cpflow-vs-terraform.md — the HCL appendix block has the two syntax issues; everything else in both files is fine.

Important Files Changed

Filename Overview
.controlplane/docs/cpflow-vs-terraform.md New doc explaining cpflow vs. Terraform trade-offs; HCL appendix has two minor syntax issues: invalid inline multi-attribute variable block and a port number passed as a string instead of an integer.
.controlplane/readme.md Three-line addition pointing readers at the new docs file; relative path resolves correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Developer question:\nShould I use Terraform\nfor .controlplane/templates?] --> B{What concern?}

    B --> C[App build / deploy /\nrelease-phase migrations]
    B --> D[Ephemeral per-PR\nreview apps]
    B --> E[Staging → production\npromotion]
    B --> F[Durable shared infra:\norgs, domains, IAM,\nexternal RDS/ElastiCache]

    C --> G[Use cpflow]
    D --> G
    E --> G
    F --> H[Use Terraform\ncpln provider]

    G --> I[controlplane.yml\ndrives workflow]
    H --> J[cpln_gvc / cpln_workload /\ncpln_identity resources]

    I --> K[build-image → deploy-image\nrelease script → promote]
    J --> L[terraform apply\nstate-managed infra]
Loading

Reviews (1): Last reviewed commit: "docs: add cpflow vs. Terraform guidance ..." | Re-trigger Greptile

# variables.tf
variable "app_name" { type = string } # cpflow injects {{APP_NAME}} per review app;
# in TF this is a -var or a workspace name.
variable "location" { type = string default = "aws-us-east-2" }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 HCL2 requires multiple attributes inside a block body to be separated by newlines (or semicolons); placing type and default on the same line without either separator is a parse error that terraform validate will reject. A reader who copies this snippet verbatim will get an immediate failure.

Suggested change
variable "location" { type = string default = "aws-us-east-2" }
variable "location" {
type = string
default = "aws-us-east-2"
}


ports {
protocol = "http" # keep http — Thruster does HTTP/2 on the TLS frontend
number = "3000"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 The cpln_workload provider schema defines the ports.number attribute as a number type, not a string. Passing "3000" (string) instead of 3000 (integer) will produce a type-mismatch error at terraform plan time if the provider enforces strict typing, and at minimum creates misleading documentation for readers.

Suggested change
number = "3000"
number = 3000

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@claude
Copy link
Copy Markdown

claude Bot commented May 30, 2026

Code Review: docs: add cpflow vs. Terraform guidance for Control Plane

Overall: Clear, well-structured docs-only addition. The decision table and HCL appendix are genuinely useful for readers coming from a Terraform background. Two minor HCL correctness issues in the appendix worth fixing before merge.

Issues

HCL type error — port number is a string
Line 110 of the new file: number = "3000" — in HCL, port numbers are integers. The Terraform cpln provider will either coerce this or raise a type error depending on the schema. Should be number = 3000 (no quotes).

Hardcoded SECRET_KEY_BASE in Terraform example
Line 76: SECRET_KEY_BASE = "placeholder_secret_key_base_for_test_apps_only" is passed as a plain env string in the GVC resource. In actual Terraform usage this would need to be a sensitive variable (or a cpln://secret/... reference like the two lines below it). Even in tutorial docs, example Terraform that puts secrets in env maps as literal strings teaches a pattern readers will cargo-cult into production. A short inline comment noting "real usage: var.secret_key_base marked sensitive, or use a cpln:// secret ref" would close the gap.

Minor observations

  • The firewall_spec block opens 0.0.0.0/0 inbound/outbound without a note that this mirrors the tutorial template and should be tightened in production.
  • The closing paragraph ("templates/postgres.yml, redis.yml, daily-task.yml follow the same pattern") mentions cpln_secret + cpln_policy + cpln_volumeset without any snippet. A note like "see the provider docs — the field mapping is mechanical" would be more satisfying, though not blocking.

Summary

Conceptual content is solid. The two HCL issues (port type, secret handling) are the only changes worth making; the rest is polish.


ports {
protocol = "http" # keep http — Thruster does HTTP/2 on the TLS frontend
number = "3000"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

HCL port numbers are integers, not strings — the cpln provider schema expects a number type here. This should be:

Suggested change
number = "3000"
number = 3000

Passing a string may cause a type-mismatch error on terraform apply depending on how strictly the provider validates the attribute.

RAILS_ENV = "production"
NODE_ENV = "production"
RAILS_SERVE_STATIC_FILES = "true"
SECRET_KEY_BASE = "placeholder_secret_key_base_for_test_apps_only"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is the one spot in the appendix that could teach a bad pattern. Hardcoding a secret value in a GVC env map is exactly what readers should not do when they adapt this to a real app — but the example doesn't signal that.

Two lines below, RENDERER_PASSWORD and REACT_ON_RAILS_PRO_LICENSE correctly use cpln://secret/... references. Suggest matching that style, or at minimum adding an inline comment:

Suggested change
SECRET_KEY_BASE = "placeholder_secret_key_base_for_test_apps_only"
SECRET_KEY_BASE = "cpln://secret/${var.app_name}-secrets.SECRET_KEY_BASE" # use a secret ref or var.secret_key_base (sensitive = true)

Even for a tutorial placeholder, showing the cpln://secret/ pattern is consistent with the two lines below and avoids the "copy the example into prod" failure mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant