Skip to main content
Ryvn can deploy into a Kubernetes cluster you already run instead of provisioning one for you. You install the Ryvn agent, the agent connects outbound to Ryvn, and from then on the environment behaves like any other — services, installations, release channels, and observability all work the same way. What changes is the boundary. Ryvn manages what runs inside the cluster and leaves everything around it — the network, the cluster itself, the node pools, ingress, and DNS — under your control.

Choosing this path

Pick an existing cluster when your platform team already owns cluster lifecycle, when the cluster predates Ryvn, or when it needs to live somewhere Ryvn does not provision. If you would rather Ryvn stand up the whole environment, see How provisioning works instead. There are two variants. If the cluster runs in AWS, Google Cloud, or Azure, select that provider and then Use an existing cluster — only this variant can give the agent a cloud identity, so it is the only one that can run Terraform against cloud APIs (see Infrastructure permissions). For a cluster anywhere else, select the Other provider. Everything else on this page applies to both.

What Ryvn installs

Connecting the cluster installs Ryvn’s base platform: KEDA is optional — turn it off in platform settings if your cluster already runs its own. Log and metric collection are likewise toggleable.

What Ryvn does not do

  • No network or cluster infrastructure. Ryvn creates no VPC, VNet, subnets, cluster, or node pools, and modifies none of the ones you have.
  • No ingress, DNS, or certificates. Ryvn’s managed gateway is deliberately not installed on these environments, so ingress controllers, TLS certificates, and DNS records stay yours to run.
  • No cloud API access by default. The agent starts with Kubernetes permissions only. Granting it cloud access is an explicit, separate opt-in — the rest of this page.

Requirements

  • A Kubernetes cluster, with kubectl and helm access to it. No minimum Kubernetes version is enforced.
  • Outbound HTTPS from the cluster. The agent is pull-based and egress-only: it opens connections to Ryvn and never accepts inbound ones, so it needs no ingress rules, port forwarding, or public endpoints.
  • Somewhere for the agent to schedule. It requests 250m CPU / 512Mi memory and runs unprivileged — non-root, read-only root filesystem, all capabilities dropped. It tolerates the CriticalAddonsOnly and kubernetes.io/arch=arm64 taints, but tolerations only permit scheduling, they never attract it: any other taint on your nodes will leave the agent Pending. It also ships no memory limit on purpose, since Terraform plans can spike to several GiB — a LimitRange that forces one back on may cut plans short.

Cluster permissions

By default the Ryvn agent assumes broad permissions in the cluster, so it can fully manage cluster-level resources — CRDs, cluster issuers, and whatever else the Helm charts you deploy need to create. If your deployments only ever target a specific set of namespaces, permissions can be scoped to those namespaces instead. Contact Ryvn to set that up for an environment.

Connect the cluster

1

Create the environment

In the Ryvn dashboard, create an environment and work through the wizard:
  1. Environment details — name and defaults
  2. Provider selection — AWS, Google Cloud, Azure, or Other
  3. Cluster setup — choose Use an existing cluster (skipped entirely for Other)
  4. Platform features — approval policy, observability, and infrastructure permissions
  5. Provisioning details — the agent bootstrap commands below
  6. Review environment — a summary of what Ryvn will and will not do
The networking and provisioning-method steps do not appear: there is no network for Ryvn to lay out and no infrastructure for it to stand up.
2

Download the agent manifest

On the Provisioning details step, click Download ryvn-agent-manifest.yaml. The manifest contains the ryvn-system namespace, the agent’s credentials secret for this environment, and the role definitions behind user access to the cluster — so you do not have to create the namespace yourself. The agent’s own cluster permissions come from the chart in the next step, covered in Cluster permissions.Downloading again mints a fresh key, so treat the file as a credential and re-run the install if you regenerate it.
3

Apply it

4

Install the agent

The dashboard shows the exact command with your environment name filled in, then waits for the agent’s first heartbeat. Once it reports in, the environment is connected and you can deploy to it.

Platform features

The Platform features step configures behavior you can change at any time afterwards under Settings → Infrastructure → Platform Settings:
  • Approval policy — whether installation and infrastructure tasks wait for manual approval. See Deployment approvals.
  • Observability — metric collection, log collection, and log redaction patterns applied before logs leave the cluster.
  • Infrastructure permissions — covered next.

Infrastructure permissions

Out of the box the agent can deploy anything that lives inside the cluster — containers, Helm charts, jobs — using its Kubernetes RBAC. It cannot touch your cloud account, because nothing in your cloud account has granted it permission to. Allow infrastructure changes is how you grant that permission. You create a role in your cloud account, trust the agent’s Kubernetes service account to assume it, and paste the role’s identifier into Ryvn. From then on, Terraform services and installations in that environment run as that role.
On clusters Ryvn provisions, Ryvn creates this role for you during provisioning. This section is for existing clusters, where Ryvn never had access to your cloud account and cannot create anything in it.

What the role is for

Terraform services let you manage cloud resources — a database, a bucket, a queue — alongside the application that uses them. The agent is what actually runs terraform plan and terraform apply, from inside your cluster. To do that against a cloud provider API, the Terraform process needs cloud credentials. Ryvn does not store cloud keys for this. Instead the agent uses the cluster’s built-in workload identity — IRSA on EKS, Workload Identity on GKE, Azure Workload Identity on AKS — to exchange its Kubernetes service account token for short-lived cloud credentials. You tell Ryvn which cloud identity to use; the cloud provider decides whether to hand over credentials, based on a trust policy you control. Leaving the setting off is a perfectly normal way to run an environment. The agent keeps full ability to deploy and manage workloads. What it loses is the ability to authenticate to your cloud provider — a Terraform service that talks to a cloud API will fail at the provider authentication step.

How the trust relationship works

Every cloud provider needs the same thing from you: a statement that one specific Kubernetes service account, in one specific cluster, is allowed to act as your role. That service account is always:
The agent’s service account is named ryvn-agent and cannot be renamed — not through Helm values, not through the release name. ryvn-system is the namespace you installed the agent into; if you installed it elsewhere, substitute your namespace everywhere below. Ryvn holds up the other half. When you save the setting, Ryvn annotates that service account with the identity you supplied and rolls the agent pods so they pick up the new credentials.
Ryvn never asks for and never stores a cloud key, secret, or certificate for this. The only values you provide are identifiers — a role ARN, a service account email, or client/tenant/subscription IDs. All of them are safe to treat as non-secret.

Step 1 — Create the role

You can do this before or after creating the environment. Doing it first means you can paste the identifier straight into the wizard; doing it later means one extra visit to the environment’s settings.
EKS uses IAM Roles for Service Accounts (IRSA). The role trusts your cluster’s OIDC provider, scoped to the agent’s service account.
1

Confirm the cluster has an IAM OIDC provider

This prints an issuer URL like https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE. If IAM has no provider registered for it yet, create one:
2

Write the trust policy

Save this as trust-policy.json, replacing the account ID and the OIDC host/path from the previous step.
The condition keys use the issuer URL without the https:// prefix. Both conditions matter: sub pins the role to the agent, and aud prevents tokens minted for another audience from being replayed.
3

Create the role

4

Attach a permissions policy

Write the permissions your modules need into permissions-policy.json — see Scoping the permissions — then create and attach it:
5

Copy the role ARN

The result looks like arn:aws:iam::123456789012:role/RyvnAgentTerraform. This is the value Ryvn needs.
The agent uses IRSA, not EKS Pod Identity. A Pod Identity association targeting ryvn-agent will not be picked up — the trust must be federated through the cluster’s OIDC provider as shown above.

Step 2 — Turn on Allow infrastructure changes

On the Platform features step, find the Infrastructure Permissions section and turn on Allow infrastructure changes. The fields for your provider appear below the toggle:
  • AWS — Agent IAM role ARN
  • Google Cloud — Agent service account email
  • Azure — Agent client ID, Agent tenant ID, Subscription ID
Ryvn checks the format of each value before letting you move on, so a typo is caught here rather than at the first Terraform run. The check is silent: if a value is malformed, Continue simply stays disabled rather than showing an error next to the field. If the button will not activate, re-check the value against the placeholder format.The Review environment step restates which identity the agent will use.
Saving re-renders the agent’s installation. Ryvn writes the identity annotation onto the ryvn-agent service account and restarts the agent pods, because cloud identity annotations are only read when a pod starts. Expect a brief gap while the pods roll.

Step 3 — Verify

Check that the annotation landed on the service account:
You should see the annotation for your provider: On Azure, Ryvn also adds the azure.workload.identity/use: "true" pod label, which is what triggers the Azure webhook to project a token into the agent’s pod. Annotations alone are not enough there, so confirm the label is present:
Confirm the pods restarted after the change:
Then run a real check: create a Terraform installation in the environment and trigger a plan. A plan that reaches “Refreshing state” has authenticated successfully.

Scoping the permissions

Ryvn cannot tell you what the role should be allowed to do — that depends entirely on which resources your Terraform modules manage. Two approaches work: Start narrow. Grant only what your current modules need, and widen when a plan fails with an authorization error. This is the safer default and the one worth the extra iterations for production environments. Start broad, then deny. On its own provisioned clusters, Ryvn takes this shape: allow most actions, then explicitly deny the operations that read or destroy customer data — Secrets Manager and SSM parameter reads, DynamoDB item operations, KMS decrypt, database failover and restore, IAM user and group management, and organization-level changes. Terraform needs to create a database; it never needs to read rows out of one. Whichever you pick, remember that this role is the blast radius for every Terraform module deployed into the environment. Scope it to a single resource group, project, or account boundary wherever your cloud provider lets you.

What Ryvn stores

Only the identifiers you typed: a role ARN, a service account email, or client/tenant/subscription IDs. They are stored as ordinary environment settings, not secrets, and are visible to anyone who can view the environment. Terraform state for installations stays in your cluster — the agent uses the Kubernetes backend and writes state to a Secret. It is never shipped to Ryvn.

Troubleshooting

If a plan fails and the error does not point at authentication, the role is probably working and the problem is in the module. Check the task logs on the installation.