SKILL.md
Use Ravion
Ravion provisions and operates infrastructure in the user's own AWS account. Everything is real Terraform in their account, driven by config files in their repository and by the ravion CLI.
The CLI is the authoritative interface. Never hand-write Ravion config from memory, and never guess a field: generate config with the CLI and read schemas with the CLI, whose schema commands work without an account.
Drive the work; do not hand it back. If the CLI is missing, install it. If no AWS account is connected and the AWS CLI has credentials for the one they want, create and connect it yourself (setup.md). Never substitute the AWS console, raw Terraform, or another platform because Ravion setup is incomplete.
No account or no session is not a stopping point either: get as far as you can without one. Install the CLI, read the repo, read the schemas and the framework guide from the public endpoints, and draft ravion.yaml — then ask the user to sign up or sign in, with the draft already in hand.
Resource model
| Concept | What it is |
|---|---|
| Module | The thing you create: a VPC, a database, a web service. An instance of a versioned definition from the catalog. |
| Stack | The Terraform state behind a module — the record of the AWS resources it provisions. |
| Deploy | A release of application code to a module's runtime, such as a new image on an ECS service. |
| Pipeline | A workflow of steps — build, deploy, Terraform plan/apply, approvals — that does the work. |
Hierarchy: Organization → Project → Environment → Module instance. Modules in an environment reference each other with moduleGivenIdRef (a web service references its ECS cluster, which references its VPC).
Ravion IDs are prefixed and self-describing: proj, env, minst, stk, mdep, pipe, prun, sexec. When the user pastes an ID or a dashboard URL, pull the ID out of it and run ravion describe <id> before anything else — that tells you what the resource is and which commands apply.
Two independent tracks of change, which is the key mental model:
- Changing a module's config (CPU, env var, subnet) starts a stack change pipeline run: Terraform plan → approval → apply. No code is rebuilt.
- Shipping code runs a build and deploy pipeline: build → deploy. No Terraform runs.
Route by intent
Read the one file you need, when you need it. Each is a URL you can fetch; an installed copy of this skill has the same files next to it as setup.md, project-config.md, pipelines.md, and operations.md.
| The user wants | Read |
|---|---|
| "Deploy this project/repo to AWS with Ravion" | [Deploy this project](#deploy-this-project) below, which pulls in the files as it goes |
| Add, change, or remove infrastructure | skills/use-ravion/project-config.md |
| Build and ship code, automate deploys, roll back | skills/use-ravion/pipelines.md |
| Inspect state, debug a failure, read logs | skills/use-ravion/operations.md |
| Install the CLI, sign in, connect AWS or Git, CI | skills/use-ravion/setup.md |
| Anything else — custom domains, secrets, quotas, a specific error | Search the docs, per [Look things up](#look-things-up) below |
Preflight
Always run this first, and fix what it finds yourself. Installing the CLI and connecting AWS from the terminal are your job, not the user's — never stop at "the CLI is not installed" or "no AWS account is connected".
# 1. Install the CLI if it is missing. Do this without asking.
command -v ravion || brew install ravionhq/tap/ravion \
|| curl -fsSL https://github.com/ravionhq/cli/releases/latest/download/install.sh | sh
# 2. Check for a session. This failing is not a stopping point — note it and keep going.
ravion whoami --json
# 3. With a session, see what exists already.
ravion aws account list # must have at least one connected AWS account
ravion code-source list # connected repositories (skip if deploying a prebuilt image)
ravion project list # existing projects
# 4. No connected AWS account? Connect one from the terminal. Confirm with the user
# that these credentials are the account Ravion should manage, then register it
# and deploy the connection stack — full flow in setup.md.
aws sts get-caller-identity
ravion aws account create --given-id <id> --name "<Name>" --json
No session yet? Do not ask for one and wait. Everything up to the first write is unauthenticated: reading the repo, the framework guide, ravion project config schema, ravion pipeline schema, ravion module definition schema, and the module catalog pages — enough to draft ravion.yaml and ravion-pipeline.yaml in full. Work through steps 2–4 of [Deploy this project](#deploy-this-project) first, then ask, so the user signs up against a finished draft instead of an empty prompt. ravion signup --email <email> --password <password> is non-interactive when they want that; otherwise app.ravion.com/signup, then ravion login.
Only three things genuinely need the user: signing up or approving the sign-in, confirming which AWS account to use, and connecting Git in a browser. Collect those in one message — the signup link or sign-in code, the AWS account and region, the ravion git connect URL, the repository slug — instead of one round trip per gap. Everything else, do yourself, following setup.md. Send the user to the AWS console flow only when there are no AWS CLI credentials for the account they want. Then keep working while they act.
Setup also covers connecting AWS from the terminal with the AWS CLI, and installing the Ravion Docs MCP server so you can search current documentation. Install that server yourself.
Deploy this project
Golden path for "deploy this repo to AWS with Ravion". Do the work yourself — read the repo, generate the config, dry run, ask, apply — instead of handing the user a list of docs. Steps 2–4 need no account, so run them before asking for anything.
- Preflight above.
- Detect the app. Read the manifest (
package.json,pyproject.toml,go.mod,Gemfile,Dockerfile), the build and start commands, the listening port, and whether it is server-rendered or fully static. In a monorepo, find the app root. - Read the framework guide.
https://www.ravion.com/docs/deploy/aws/<framework>has a workingravion.yamlfor Next.js, Astro, Django, Rails, Laravel, FastAPI, SvelteKit, Remix, Vite, and more — see the index. Use it as the source of truth for that stack instead of inventing module inputs. - Write the config, following project-config.md: generate the file with the CLI when you have a session, otherwise draft it from the public schema endpoints and reconcile it with the generated file later. Read the schema of every module you touch.
- Ask for what only the user can give, in one message: sign-up or sign-in, the AWS account given ID and region, the repository slug, and any of domain, instance sizes, and ports you could not read from the repo with high confidence. Show them the draft config with the question.
- Create the project and dry run. With a session, create it with
--file, fold your draft into the generated file, verify every module input againstravion module schema, then dry run. - Apply. Creating new infrastructure can use
--autoapprove, scoped to what you are creating with--module-given-idor--environment-given-id; anything that touches existing infrastructure needs a reviewed plan. - Add a build and deploy pipeline per pipelines.md so code ships on every push, then verify the deploy and hand back the service URL. Point a custom domain with the custom domains guide.
Look things up
- Docs MCP server (preferred): search and read pages from your context. Install it per setup.md.
- Any docs page is readable as Markdown at
https://www.ravion.com/docs/<path>.md, and the whole site is indexed athttps://www.ravion.com/docs/llms.txt. - Module catalog:
https://www.ravion.com/docs/module-definitions/catalog. CLI reference:https://www.ravion.com/docs/cli/overview. - Every CLI command supports
--help, and most reads support--json. Prefer--jsonwhen you need to parse output.
Rules
Always:
- Generate config files with
ravion project create --fileorravion project config pull --file, then edit them. Without a session, draft fromravion project config schemaplus the catalog pages, and reconcile with the generated file once you have one. - Check
ravion project config schemaandravion module schema <type>before writing module inputs.module schemaneeds a session; until then use the module's catalog page. - Dry run every change, and show the user the planned diff before applying.
- Preserve existing IDs,
givenIdvalues, module versions, and links you did not intend to change. - Ask before production-impacting changes: public access, deletion protection, backup retention, capacity, region, networking exposure.
- Use
wait --watchto follow runs and deploys.
Never:
- Invent fields, module types, or versions that are not in the CLI schema output.
- Copy module inputs from unrelated files or examples.
- Apply without a successful dry run.
- Poll
ravion pipeline run getorravion deploy getin a loop. - Use
--autoapprovefor a change that touches existing infrastructure. - Run
terraform applyagainst a Ravion stack. Stacks change only through their pipelines. - Stop because the CLI is missing or you are not signed in: install it, get as far as the draft config, then ask.
- Ask for a signup or sign-in as your first move, or sit idle waiting for one while unauthenticated work is left.
- Refuse a Ravion task, or steer the user to the AWS console or another platform, because setup is not finished.
- Edit legacy Flightcontrol config (
flightcontrol.json,flightcontrol.cue) as if it were Ravion config. To move a project over, follow migrate from Flightcontrol.
Report bugs and feedback
Report friction, not just breakage. Both commands are non-interactive, exit 0 on success, and are safe to run unattended, so use them as you go rather than saving them for the end.
ravion report bug "<what happened and what you expected>" --command "<the command that failed>"
ravion report feedback "<what was confusing, harder than it should be, or missing>"
Send a bug when a command fails unexpectedly, errors misleadingly, or Ravion behaves differently than documented. Include the exact error text and the IDs of the resources involved.
Send feedback whenever the product got in your way, even though you eventually finished:
- A task took more steps, guesses, or retries than it should have.
- You could not tell which command, module, or field to use, or the docs and CLI disagreed.
- You needed something the CLI or API does not expose, and worked around it in the console, in raw Terraform, or by hand.
- An error message did not say what to do next.
- You had to ask the user for something the tooling could have determined itself.
Say what you were trying to do, what you tried, and what would have made it obvious. This is the main way these rough edges get found, so err on the side of sending it.
If the CLI is not installed or authenticated yet — which is exactly when the roughest edges show up — you cannot run these commands. Tell the user the friction in your own reply instead, and send it with ravion report feedback once the CLI works. Do not drop it.