Skip to content
Open
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
2 changes: 1 addition & 1 deletion content/docs/en/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Here **project** and **environment** are the required arguments. User might add

### Injecting values on deploy

You can inject Helm values into a single deployment, on top of everything configured in the platform (see [Values](/docs/project/values) for the override levels):
You can inject Helm values into a single deployment, on top of everything configured in the platform (see [Values](/docs/project/workload/values) for the override levels):

```plain
sleakops deploy -p myapp -e prod -f values.prod.yaml
Expand Down
55 changes: 55 additions & 0 deletions content/docs/en/cluster/addons/essential-addons.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: Essential addons
sidebar_label: Essential addons
sidebar_position: 9
---

import Zoom from "react-medium-image-zoom";
import "react-medium-image-zoom/dist/styles.css";
import { FiExternalLink } from "react-icons/fi";

:::info
This page covers importing an existing resource. If you haven't connected your AWS infrastructure to SleakOps yet, start with [Install SleakOps on your infra](/docs/install-on-your-infra).
:::

Essential addons are the infrastructure glue every cluster needs to function under SleakOps: networking, autoscaling, and access control. Unlike the optional addons you pick from the Addons list, these five are always present — SleakOps installs them automatically on every managed cluster instead of waiting for you to add them.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./essential-addons/essential-addons-list.png").default}
alt="Addons list showing the five essential addons (all Installed) alongside a mix of installed, deprecated, and not-yet-installed optional addons"
/>
</Zoom>

They show in the Addons list like any other addon card, with no special badge or visual marker — you recognize them by name and description, not by a distinct treatment.

## The five essential addons

| Name | What it does |
|---|---|
| Metrics Server | Collects resource metrics from kubelets and exposes them through the Kubernetes Metrics API, enabling Horizontal Pod Autoscaling and `kubectl top`. |
| ExternalDNS | Synchronizes exposed Kubernetes Services and Ingresses with DNS providers (Route53), keeping cluster DNS records up to date automatically. |
| Karpenter | A Kubernetes node autoscaler that provisions right-sized compute capacity in response to unschedulable pods, improving efficiency and reducing cost. |
| AWS Auth | Wires SleakOps IAM roles into the cluster's `aws-auth` ConfigMap and the SleakOps RBAC ClusterRoles, enabling SleakOps integration and role-based access. |
| Load Balancer | The AWS Load Balancer Controller manages Application Load Balancers for Kubernetes Ingresses, plus the public and private IngressClasses used to route external traffic. |

## Behavior on imported clusters

On a managed cluster, SleakOps provisions and owns all five essential addons from day one. On an imported cluster, there's nothing to provision — the client's infrastructure already runs its own version of each piece — so instead of installing them, SleakOps adopts them from what's already there, one at a time, as you bring resources under management.

The Load Balancer addon is one concrete example: when a cluster is imported, its Addon row is created directly from the public and private IngressClass names discovered in the import payload, without running any Pulumi provisioning — the client already runs their own ALB controller, so SleakOps only needs to record what exists.

AWS Auth has the most involved import-time behavior. On a managed cluster, SleakOps owns the entire `aws-auth` ConfigMap's `mapRoles`. On an imported cluster, the module instead runs in merge mode: it reads the client's live `aws-auth` ConfigMap and merges in only the SleakOps-required role entries, deduplicated by role ARN with the SleakOps entries winning on conflict — every pre-existing client entry is preserved. This merge is idempotent: reading back an already-merged ConfigMap and running it again doesn't duplicate entries.

## Restrictions

**Configuration** — an essential addon's configuration form is read-only on a managed cluster, since SleakOps owns that configuration; it becomes editable on an imported cluster, since there the configuration reflects what the client already had running, which is theirs to change. Note that most essential addons (Metrics Server, ExternalDNS, Karpenter, AWS Auth) have no configurable fields at all — Load Balancer is the one with an actual schema (its public and private IngressClass names), so it's also the one where the read-only lock is visible:

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./essential-addons/essential-addon-lb-detail.png").default}
alt="Load Balancer addon detail view on a managed cluster, with its IngressClass name fields locked"
/>
</Zoom>

**Deletion** — essential addons cannot be deleted at all on a managed cluster: they're permanent for the cluster's lifetime and are only torn down automatically when the cluster itself is destroyed. On an imported cluster, they can be deleted individually like any other adopted resource, subject to the same dependency guard as any addon (you can't delete one that another addon depends on). This restriction is gated by the cluster's type, not by the requesting user's role.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions content/docs/en/cluster/addons/import-addons.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: Import and export addons
sidebar_label: Import and export addons
sidebar_position: 8
---

import Zoom from "react-medium-image-zoom";
import "react-medium-image-zoom/dist/styles.css";
import { FiExternalLink } from "react-icons/fi";

:::info
This page covers importing an existing resource. If you haven't connected your AWS infrastructure to SleakOps yet, start with [Install SleakOps on your infra](/docs/install-on-your-infra).
:::

Addons can move in and out of SleakOps in two ways: importing a JSON definition exported from another cluster, or discovering and adopting a Helm release already running in the cluster. Both buttons sit on the Addons list next to **Add custom addon**, and both only appear when your company has the generic (custom Helm chart) addon type registered. From there the two flows differ in scope: **Import from JSON** and **Export JSON** work with any addon type registered in the cluster — SleakOps Managed (Grafana, KEDA, …) or custom — while **Import from cluster** always adopts the release as a custom addon, since discovery has no way to know which managed type (if any) a live Helm release corresponds to.

Both flows require your company to have the import feature enabled (`infra_import.addon`) and require an **admin** user — creating, updating, or exporting an addon is admin-only on the backend.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./import-addons/import-addons-buttons.png").default}
alt="Addons list showing Import from cluster and Import from JSON next to Add custom addon"
/>
</Zoom>

## Import from JSON

Click **Import from JSON** to paste a definition exported from another cluster:

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./import-addons/import-addon-json.png").default}
alt="Import addon from JSON dialog with a textarea for pasting the exported definition"
/>
</Zoom>

Paste the JSON and click **Import**. SleakOps validates it before opening the form:

- Invalid JSON: **"Invalid JSON. Paste a valid addon export."**
- Missing shape: **'The JSON must include a string "addon_type" and an object "values".'**
- A type the cluster doesn't have registered: **`Addon type "<type>" is not available in this cluster.`**

Once it validates, the matching addon's create form opens pre-filled from the pasted `values` (and `name`, if present) — nothing is locked, so you can change anything before installing. The submit button reads **Import** instead of **Install** as a reminder that these are starting values, not a fresh default configuration.

This pairs with **Export JSON**, available on any installed addon's detail view — SleakOps Managed or custom — once it's in `created` state (same access requirement). It copies the addon's portable JSON to the clipboard and downloads it as `<addon-name>.addon.json` — that file is what you paste into **Import from JSON** on the destination cluster.

## Import from cluster

Click **Import from cluster** to discover the Helm releases already running in this cluster:

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./import-addons/import-addon-from-cluster.png").default}
alt="Import from cluster dialog listing discovered Helm releases with a Use button each"
/>
</Zoom>

Each release shows its name, namespace, chart, and version. While discovery runs: **"Loading releases…"**; if it can't reach the cluster: **"Could not load Helm releases from the cluster."**; if none are found: **"No Helm releases found in this cluster."**

Click **Use** on a release to pre-fill the generic addon form with its release name, namespace, chart, version, and current Helm values. Unlike the JSON flow — which can target any addon type — this always creates a custom (generic) addon, and it adopts a live resource rather than just starting from a set of values: the release name, namespace, chart, and version are locked (read-only) because they feed the underlying Pulumi import and must match what's actually running. **Repository URL** is the one field left blank and editable — the chart's repository URL can't be recovered from a live release, so you type it in yourself.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./import-addons/import-addon-from-cluster-form.png").default}
alt="Generic addon form pre-filled from a discovered release, with release name, chart, version and namespace locked and Repository URL left blank"
/>
</Zoom>

Click **Import** to adopt the release under SleakOps management.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion content/docs/en/cluster/index.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 5
sidebar_position: 6
title: Cluster
pagination_next: environment/index
---
Expand Down
59 changes: 59 additions & 0 deletions content/docs/en/cluster/nodepools/importing-a-nodepool.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: Importing a Node Pool
sidebar_label: Importing a Node Pool
sidebar_position: 4
---

import Zoom from "react-medium-image-zoom";
import "react-medium-image-zoom/dist/styles.css";
import { FiExternalLink } from "react-icons/fi";

:::info
This page covers importing an existing resource. If you haven't connected your AWS infrastructure to SleakOps yet, start with [Install SleakOps on your infra](/docs/install-on-your-infra).
:::

SleakOps can bring an existing Karpenter node pool under management instead of creating one from scratch. Import discovers the live node pools running in your cluster and lets you adopt one as-is.

## Prerequisites

- An admin user in SleakOps.
- The import feature enabled for your company (`infra_import.nodepool`).
- The cluster must **not** be in import mode. **Import Node Pool** is only available on clusters SleakOps provisioned itself — it doesn't appear on imported clusters.

## Discover and import

From the Cluster Listing, select a cluster and access its Settings, then click on Node Pools. If the prerequisites above are met, an **Import Node Pool** button sits next to **Create**.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./importing-a-nodepool/import-nodepool-button.png").default}
alt="Node Pools section of a cluster, with the Import Node Pool button next to Create"
/>
</Zoom>

### Discover

Clicking it opens a dialog that lists the live Karpenter node pools running in the cluster that SleakOps doesn't manage yet:

- While the search runs: **"Discovering Karpenter node pools…"**
- No unmanaged node pools found: **"No unmanaged Karpenter node pools were found in this cluster."**
- The cluster isn't reachable: an error asking you to check connectivity and try again.

A node pool whose name doesn't match SleakOps' naming rules (lowercase alphanumerics with single hyphens, up to 50 characters) can't be adopted and appears disabled — the pool's name becomes the NodePool's name in SleakOps and can't be edited afterward, so names outside that pattern are filtered out of selection.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./importing-a-nodepool/import-nodepool-dialog.png").default}
alt="Import Node Pool dialog showing the discovered, unmanaged Karpenter node pools of the cluster"
/>
</Zoom>

### Review

Select a node pool and move to the next step: "Review the configuration mapped from the live pool. It is adopted exactly as it runs today, even where its values fall outside the SleakOps ranges."

SleakOps pre-fills the same form used to create or edit a node pool with the values discovered on the live pool — architecture, node types, instance types, CPU and memory limits, node storage, and its dedicated taint if the pool has one.

## After importing

Once you confirm the import: "`<name>` is being adopted by SleakOps. SleakOps is taking the live node pool under management. Its EC2NodeClass is cloned under the pool's name and existing nodes rotate gradually, respecting PodDisruptionBudgets and disruption budgets. You can follow the progress in the node pools list."
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions content/docs/en/domain/import-domain.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Import a domain
sidebar_label: Import a domain
sidebar_position: 3
---

import Zoom from "react-medium-image-zoom";
import "react-medium-image-zoom/dist/styles.css";
import { FiExternalLink } from "react-icons/fi";

:::info
This page covers importing an existing resource. If you haven't connected your AWS infrastructure to SleakOps yet, start with [Install SleakOps on your infra](/docs/install-on-your-infra).
:::

Domain import isn't a separate flow — it's a section inside the Environment creation form. Creating an Environment normally provisions a brand-new Route53 hosted zone; the import option lets you reuse one that already exists in the target AWS account instead.

## Reuse an existing hosted zone

On the Environment creation form, an admin-only **Use Existing Hosted Zone** toggle sits below the base fields (Name, Cluster, Domain):

> Adopt a Route53 hosted zone that already exists in the target AWS account instead of creating a new one. The ACM certificate for the domain is adopted automatically when the account has one issued.

Before you can search, three fields need to be filled in first — the Cluster determines which AWS account SleakOps searches:

- No Cluster selected: **"Select a Cluster to search its account for existing hosted zones."**
- Cluster selected but Name or Domain still missing/invalid: **"Enter a Name and a valid Domain to search for existing hosted zones."**

Once all three are filled in, turning the toggle on searches Route53 in that account:

- A zone whose name matches the Domain field exactly is marked **Exact Match** (plus **Private** if it's a private zone) and listed first.
- Any other zones found in the account are listed below it, each with a **Private** badge if applicable.
- No zones at all: **"No hosted zones found in the account."**
- Zones exist but none match exactly: **"No hosted zone matches `<domain>` exactly. Pick one manually or create a new one."**

Pick one with the radio cards — **Create a New Hosted Zone** (the default, SleakOps provisions a new zone) or one of the discovered zones. Changing the Cluster switches the target AWS account, so it discards any zone you'd already picked — a hosted zone ID only makes sense within the account it belongs to.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./import-domain/domain-import-section.png").default}
alt="Environment creation form with the Use Existing Hosted Zone toggle on, showing an exact-match zone and another discovered zone"
/>
</Zoom>

Once the Environment is created, the usual domain setup applies — see [Setup your Domains](/docs/domain/setup) and the [Domain Delegation Guide](/docs/domain/delegation) for what comes next.

## FAQs

<details>
<summary>
### What happens to the ACM certificate?
</summary>
It's adopted automatically, along with the hosted zone, when the target AWS account already has one issued for the domain.
</details>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion content/docs/en/domain/index.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
sidebar_label: Domain
sidebar_position: 8
sidebar_position: 9
---

# Domain Levels & Strategies
Expand Down Expand Up @@ -134,6 +134,8 @@ If `anything.com` is completely external:
- You need multiple domains for the same service
- Connecting external domains to your Sleakops services

Each domain or alias you add gets its own manifest — see [Manifests](/docs/project/workload/manifests#ingress-per-domain).

---

## Delegation Strategies
Expand Down
2 changes: 1 addition & 1 deletion content/docs/en/environment/index.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
sidebar_label: Environment
sidebar_position: 6
sidebar_position: 7
pagination_next: project/index
---

Expand Down
48 changes: 48 additions & 0 deletions content/docs/en/install-on-your-infra/import-accounts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: Import an account
sidebar_label: Import an account
sidebar_position: 3
---

import Zoom from "react-medium-image-zoom";
import "react-medium-image-zoom/dist/styles.css";
import { FiExternalLink } from "react-icons/fi";

# Import an account

Once a provider is running in import mode, connect each existing AWS account you want SleakOps to manage from its **Accounts & Networking** section.

## Declare an existing AWS account

1. In **Accounts & Networking**, click the **Install SleakOps in account** card.
2. Fill in the three fields:

- **Account color** — pick one of the 8 preset swatches, or use the custom color picker to choose any other color.
- **Account name** — up to 20 characters (e.g. `payments-prod`).
- **AWS account ID** — the account's 12-digit numeric ID.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./import-accounts/import-account-form.png").default}
alt="Import account form with color, name, and AWS account ID filled in"
/>
</Zoom>

3. Click **Create account**. The account appears in the list on the left.

## Run the CloudFormation stack

1. Select the new account in the list. Its detail panel shows **CloudFormation not applied yet**.

<Zoom overlayBgColorEnd="rgba(255, 255, 255, 0.8)">
<img
src={require("./import-accounts/account-awaiting-cfn.png").default}
alt="Account detail panel showing the CloudFormation not applied yet state with the Open CloudFormation link"
/>
</Zoom>

2. Click **Open CloudFormation** to launch the SleakOps CloudFormation stack. It opens in a new tab — run it signed in to this AWS account.

## What happens next

Once SleakOps receives the stack's callback, the account is ready for network configuration.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading