Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/components/ProductHome.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
// Styles use Starlight's tokens only, so the block takes each site's palette.
import { PRODUCTS, STARTS } from '../data/products.mjs';

// A mention of another Intentius project is a link.
const PROJECT = /\b(behold|chant|choudoufu|plunge|plywood|terragucci)\b/;
const PROJECTS = new Set(['behold', 'chant', 'choudoufu', 'plunge', 'plywood', 'terragucci']);
const linked = (text: string, self: string) => text.split(PROJECT).map((part) =>
PROJECTS.has(part) && part !== self ? { name: part, href: `https://intentius.io/${part}/` } : part);

interface Props {
id: string;
version?: string;
Expand All @@ -23,7 +29,7 @@ const starts = Object.entries(product.starts).map(([key, href]) => {
return { key, label: STARTS[key], href };
});

const lines = product.first.cmd.map((line) => {
const lines = (product.first?.cmd ?? []).map((line) => {
if (!line.includes('{version}')) return line;
if (!version) throw new Error(`ProductHome: ${id} has {version} in its first command, so the site must pass version`);
return line.replaceAll('{version}', version);
Expand All @@ -35,10 +41,10 @@ const hid = `ph-${product.id}`;
<div class="art"><slot name="art" /></div>
<h1 id={`${hid}-name`} class="name">{product.name}</h1>
<p class="one">{product.oneLiner}</p>
<div class="text">
<p>{product.changes}</p>
<p>{product.fits}</p>
</div>
{(product.changes || product.fits) && <div class="text">
{product.changes && <p>{linked(product.changes, id).map((b) => typeof b === 'string' ? b : <a href={b.href}>{b.name}</a>)}</p>}
{product.fits && <p>{linked(product.fits, id).map((b) => typeof b === 'string' ? b : <a href={b.href}>{b.name}</a>)}</p>}
</div>}
{starts.length > 0 && (
<nav class="starts" aria-labelledby={`${hid}-starts`}>
<h2 id={`${hid}-starts`}>Where to start</h2>
Expand All @@ -47,12 +53,14 @@ const hid = `ph-${product.id}`;
</ul>
</nav>
)}
{product.first && (
<div class="first">
<h2 id={`${hid}-first`}>First command</h2>
<p class="needs">Needs: {product.first.needs}.</p>
<pre aria-labelledby={`${hid}-first`}><code>{lines.join('\n')}</code></pre>
<p><a href={product.first.href}>The full steps</a></p>
</div>
)}
<p class="links">
<a href={docs}>Docs</a>
<a href={source}>Source</a>
Expand All @@ -74,6 +82,7 @@ const hid = `ph-${product.id}`;
.one { margin: 0; font-size: var(--sl-text-lg); color: var(--sl-color-gray-2); }
.text p { margin: 0 0 0.75rem; color: var(--sl-color-gray-2); line-height: 1.6; }
h2 { margin: 0 0 0.5rem; font-size: var(--sl-text-base); color: var(--sl-color-white); }
.text p:last-child { margin-bottom: 0; }
.starts ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.starts li { margin: 0; }
.starts a {
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/compare/terraform-platforms.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ plywood and plunge against Pulumi Cloud, and against Spacelift where it runs Pul
- choudoufu is a build of OpenTofu that records each resource's owner on the resource itself.
- plywood runs Pulumi previews and updates from pull requests, as jobs in your own CI.
- plunge is a fork of Pulumi that keeps one record per resource, so two updates to one stack need not wait for each other.
- behold draws the whole estate as one picture coloured by drift. It only reads.
- behold draws the whole estate as one picture coloured by drift.
- chant writes infrastructure as typed code and checks it before anything runs.
4 changes: 2 additions & 2 deletions src/content/docs/tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import OneLiner from '../../components/OneLiner.astro';

## behold

<OneLiner id="behold" /> It reads what chant records for terragucci and plywood, and only reads. Every change leaves through an approval.
<OneLiner id="behold" /> It reads what chant records for terragucci, and Pulumi from stack exports. On a chant project you can act from the graph, through Ops and their approvals.

[Docs](https://intentius.io/behold/) · [Source](https://github.com/INTENTIUS/behold)

Expand All @@ -32,7 +32,7 @@ Declares an agent's sandbox, its secrets and its schedule as ordinary infrastruc

## choudoufu

<OneLiner id="choudoufu" bare />, and the engine terragucci can run with `binary: choudoufu`. Every resource records who owns it on the resource itself, as two tags on AWS or a label on Kubernetes. The state file becomes a copy you are allowed to lose.
<OneLiner id="choudoufu" bare />, and the engine terragucci can run with `binary: choudoufu`. Every resource records who owns it on the resource itself, as tags or labels on the three big clouds and Kubernetes. The state file becomes a copy you are allowed to lose.

[Docs](https://intentius.io/choudoufu/) · [Source](https://github.com/INTENTIUS/choudoufu) · [Compare](/compare/choudoufu-and-terraform-state/)

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/work.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Everything I build runs in your CI, under your accounts, and stays yours.

## Estate migration and carving

A large estate gets [choudoufu](https://intentius.io/choudoufu/) as its binary. Each resource gets its own lock and an owner tag, so splitting a team off becomes a tag rewrite and a permissions policy. It runs on AWS and Kubernetes, with more on the way.
A large estate gets [choudoufu](https://intentius.io/choudoufu/) as its binary. Each resource gets its own lock and an owner tag, so splitting a team off becomes a tag rewrite and a permissions policy. It runs on the three big clouds and Kubernetes.

## Moving from another runner

Expand Down
2 changes: 1 addition & 1 deletion src/data/arenas.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ export const ARENAS = [
hcp: ['good', 'Standard, US only', 'https://www.hashicorp.com/en/blog/hcp-terraform-powered-by-infragraph-limited-availability-launch'],
sl: ['bad', 'list only', `${S}/concepts/resources`] },
{ q: 'Finding cloud resources nothing manages',
tg: ['good', 'with choudoufu, each shown as unowned, with the command to adopt it', `${B}/using/choudoufu/`],
tg: ['good', 'chant search --ambient reports those of a kind you manage', 'https://intentius.io/chant/cli/search/'],
hcp: ['good', 'tier not published', `${H}/workspaces/import`],
sl: ['good', 'tier not published', `${S}/concepts/intelligence`] },
{ q: 'Drift, shown on the graph',
Expand Down
2 changes: 1 addition & 1 deletion src/data/compare-choudoufu-state.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const ARENAS = [
id: 'reach', title: 'Where it runs',
rows: [
{ q: 'Platforms',
cdf: ['warn', 'AWS and Kubernetes, more on the way', `${C}/docs/progress/`],
cdf: ['warn', 'AWS, Kubernetes, GCP and Azure', `${C}/docs/progress/`],
tf: ['good', 'every provider', `${H}/language/backend`] },
{ q: 'A backend block or a non-default workspace',
cdf: ['warn', 'refused; choudoufu live-check reports it before you start', `${C}/docs/progress/`],
Expand Down
8 changes: 4 additions & 4 deletions src/data/compare-platforms.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ const rest = [
// The control plane: the behold rows that match what HCP Terraform's and
// Pulumi Cloud's consoles show (the estate graph, drift on it, resources
// nothing manages, and which run deployed each resource). It sits second on
// the page, so its words link down the page like LEAD's. behold only reads,
// so no row here runs or approves a plan; those stay in BEHOLD.
// the page, so its words link down the page like LEAD's. No row here runs or
// approves a plan; those stay in BEHOLD.
export const CONTROL = {
PREFIX: 'plane-',
LEVEL: 3,
Expand All @@ -191,15 +191,15 @@ export const CONTROL = {
ARENAS: [
{
id: 'behold', title: 'One graph, every engine',
blurb: 'behold is free, and it only reads. It reads Terraform through choudoufu and Pulumi through plunge.',
blurb: 'behold is free. It reads Terraform through choudoufu and Pulumi through plunge.',
lead: tfB.lead,
rows: [
{ q: GRAPH, in: tfGraph.tg, hcp: tfGraph.hcp, pc: puGraph.pc, sl: tfGraph.sl },
{ q: 'Drift, shown on the graph from each engine\'s own read', def: 'Drift: a change made outside your code.',
in: ['good', "live, from each engine's own read: plunge drift for Pulumi, choudoufu's plan for Terraform, chant's live read for chant", srcs(tfDrift.tg, puDrift.pw)],
hcp: tfDrift.hcp, pc: puDrift.pc, sl: tfDrift.sl },
{ q: 'Finds cloud resources no code manages',
in: ['good', 'with choudoufu, each shown as unowned; one Adopt click opens a pull request', srcs(tfFind.tg, puFind.pw)],
in: ['good', 'chant search --ambient reports those of a kind you manage', srcs(tfFind.tg, puFind.pw)],
hcp: tfFind.hcp, pc: puFind.pc,
sl: { parts: [named('Terraform', tfFind.sl), named('Pulumi', puFind.sl)] } },
{ q: RUN, in: puRun.pw, pc: puRun.pc, sl: puRun.sl },
Expand Down
2 changes: 1 addition & 1 deletion src/data/compare-pulumi-platforms.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ export const ARENAS = [
pc: ['good', '', `${P}/iac/concepts/state-and-backends/`],
sl: ['good', '', `${S}/concepts/run`] },
{ q: 'Finds cloud resources no code manages',
pw: ['good', 'one Adopt click opens a pull request', `${B}/using/acting/`],
pw: ['good', 'chant search --ambient reports those of a kind you manage', 'https://intentius.io/chant/cli/search/'],
pc: ['good', 'Essentials', `${P}/discovery-governance/concepts/discovery/`],
sl: ['bad', 'not for Pulumi', `${S}/vendors/pulumi`] },
],
Expand Down
40 changes: 16 additions & 24 deletions src/data/products.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,17 @@ export const PRODUCTS = [
{
id: 'chant',
name: 'chant',
oneLiner: 'Spec-native typed ops with per-resource locking.',
changes: 'You describe infrastructure in TypeScript, and chant builds the files each platform reads, such as CloudFormation templates, Kubernetes YAML and CI pipelines. Changes run as typed Ops that are checked before they apply. Each resource carries its own ownership marker, so two changes to different resources do not wait for each other.',
fits: 'terragucci and plywood are built on it. Use chant directly when you want to write the infrastructure itself in TypeScript.',
starts: {
tofu: `${IO}/chant/for/terraform-pulumi/`,
pulumiDiy: `${IO}/chant/for/terraform-pulumi/`,
fresh: `${IO}/chant/getting-started/quick-start/`,
},
first: {
needs: 'Node.js 24 or later',
cmd: ['npm install --save-dev @intentius/chant-lexicon-aws', 'npx chant init my-infra --lexicon aws'],
href: `${IO}/chant/getting-started/quick-start/`,
},
links: { docs: `${IO}/chant/`, source: `${GH}/chant`, evidence: null },
oneLiner: 'Cloud native ops and governance.',
changes: '',
fits: '',
starts: {},
first: null,
links: { docs: `${IO}/chant/getting-started/introduction/`, source: `${GH}/chant`, evidence: null },
},
{
id: 'terragucci',
name: 'terragucci',
oneLiner: 'Sophisticated automation for Terraform.',
oneLiner: 'Terraform ops and governance.',
changes: 'terragucci generates the plan and apply pipeline for your Terraform, OpenTofu and Terragrunt repos and runs it as jobs in your own CI, on GitHub, GitLab or Forgejo. A pull request gets one plan note for every root it touches, and an apply runs only the plan someone approved. There is no server to host.',
fits: 'Built on chant. It can run choudoufu as its engine.',
starts: {
Expand All @@ -63,7 +55,7 @@ export const PRODUCTS = [
{
id: 'plywood',
name: 'plywood',
oneLiner: 'Sophisticated automation for Pulumi.',
oneLiner: 'Pulumi ops and governance.',
changes: 'Pulumi previews and updates move into your pull requests and run as jobs in the CI you already have. Each stack a change reaches gets its own preview note, and an approval holds only for the exact preview it was shown. Your programs stay as they are, on the backend they use today.',
fits: 'Built on chant. It can run plunge as its engine.',
starts: {
Expand All @@ -81,9 +73,9 @@ export const PRODUCTS = [
{
id: 'choudoufu',
name: 'choudoufu',
oneLiner: 'OpenTofu with per-resource locking.',
changes: 'choudoufu is a build of OpenTofu that runs your configurations as they are. In place of one lock on the whole state, it keeps one record per resource and writes an ownership marker on each cloud object, so two applies of saved plans that change different resources run at the same time. The state file becomes a copy you can rebuild.',
fits: 'The engine terragucci can run, with binary: choudoufu. Built on chant.',
oneLiner: 'Per-resource locking for OpenTofu.',
changes: 'choudoufu is a build of OpenTofu. `choudoufu live-check` tells you offline whether your configuration runs as it is. In place of one lock on the whole state, it keeps one record per resource and writes an ownership marker on each cloud object, so two applies of saved plans that change different resources run at the same time. The state file becomes a copy you can rebuild.',
fits: "The engine terragucci can run, with binary: choudoufu. It uses chant's ownership markers, and chant can run it.",
starts: {
tofu: `${IO}/choudoufu/docs/use/migrate/`,
fresh: `${IO}/choudoufu/docs/use/start/`,
Expand All @@ -103,9 +95,9 @@ export const PRODUCTS = [
{
id: 'plunge',
name: 'plunge',
oneLiner: 'Pulumi with per-resource locking.',
oneLiner: 'Per-resource locking for Pulumi.',
changes: 'plunge is a fork of Pulumi with a drop-in CLI that runs your programs as they are. It keeps one record per resource in place of one state file per stack, and writes two ownership tags, its markers, on each cloud object. So two runs that change different resources of one stack do not wait for each other.',
fits: 'The engine plywood can run, with engine: plunge. Built on chant.',
fits: "The engine plywood can run, with engine: plunge. It uses chant's ownership markers, and chant can run it.",
starts: {
pulumiCloud: `${IO}/plunge/use/migrate/`,
pulumiDiy: `${IO}/plunge/use/migrate/`,
Expand All @@ -122,9 +114,9 @@ export const PRODUCTS = [
{
id: 'behold',
name: 'behold',
oneLiner: 'A spec-native control plane for cloud infrastructure.',
changes: 'behold draws an estate as one graph and colours whatever has drifted from what you declared. It only reads. A change goes out through an Op you already committed, behind the approval that Op carries.',
fits: 'Reads what chant records for terragucci and plywood.',
oneLiner: 'Visualize and control.',
changes: 'behold draws an estate as one graph and colours whatever has drifted from what you declared. On a chant project you can act from the graph, through Ops and their approvals.',
fits: 'Reads what chant records for terragucci, and Pulumi from stack exports.',
starts: {
tofu: `${IO}/behold/for/terraform/`,
fresh: `${IO}/behold/start/run-it/`,
Expand Down
2 changes: 1 addition & 1 deletion src/data/rooms.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const ROOMS = [
does: [
'Same HCL, same providers, same plan. choudoufu is a build of OpenTofu.',
'Ownership moves out of the state file and onto each resource, where your IAM policies can read it.',
'Runs on AWS and Kubernetes, with more on the way. A read-only check reports anything it would refuse before you commit.',
'Runs on the three big clouds and Kubernetes. A read-only check reports anything it would refuse before you commit.',
],
check: [
{ label: 'The docs', href: 'https://intentius.io/choudoufu/' },
Expand Down
Loading