diff --git a/src/pages/docs/features/native-helm-deployment.mdx b/src/pages/docs/features/native-helm-deployment.mdx index bcd5383f..889538a4 100644 --- a/src/pages/docs/features/native-helm-deployment.mdx +++ b/src/pages/docs/features/native-helm-deployment.mdx @@ -8,12 +8,7 @@ tags: - native --- -import { Callout, Steps } from "nextra/components"; -import { Image } from "@lifecycle-docs/components"; - - - This feature is still in alpha and might change with breaking changes. - +import { Callout } from "nextra/components"; **Native Helm** is an alternative deployment method that runs Helm deployments directly within Kubernetes jobs, eliminating the need for external CI/CD systems. This provides a more self-contained and portable deployment solution. @@ -117,16 +112,26 @@ Stored in database with key `helmDefaults`: "nativeHelm": { "enabled": true, "defaultArgs": "--wait --timeout 30m", - "defaultHelmVersion": "3.12.0" + "defaultHelmVersion": "3.12.0", + "image": "registry.example.com/helm-runner:1.0.0", + "postRenderer": { + "enabled": true, + "command": "/opt/bin/post-renderer", + "args": ["--mode=preview"] + } } } ``` **Field Descriptions**: -- `enabled`: When `true`, enables native Helm deployment for all services unless they explicitly set `deploymentMethod: "ci"` +- `enabled`: Enables default native Helm behavior in global config. Services still typically opt in with `deploymentMethod: "native"` or service-level native Helm settings. - `defaultArgs`: Arguments automatically appended to every Helm command (appears before service-specific args) - `defaultHelmVersion`: The Helm version to use when not specified at the service or chart level +- `image`: Custom runner image for the native Helm job +- `postRenderer.enabled`: Enables or disables the configured Helm post-renderer +- `postRenderer.command`: Executable passed to Helm with `--post-renderer` +- `postRenderer.args`: Arguments passed to Helm as repeated `--post-renderer-args` flags #### Chart-specific Configuration @@ -151,6 +156,104 @@ Example: PostgreSQL configuration stored with key `postgresql`: overridden at the service level. +### Custom Runner Images and Post-Renderers + +Native Helm supports two related customization points: + +- `nativeHelm.image` changes the container image used for the Helm job +- `nativeHelm.postRenderer` configures Helm's `--post-renderer` integration + +This keeps the model aligned with Helm itself: Lifecycle configures the runner +image and optionally tells Helm which post-renderer executable to invoke. + +#### Global Defaults Only + +```json +{ + "nativeHelm": { + "enabled": true, + "defaultArgs": "--wait --timeout 30m", + "image": "registry.example.com/helm-runner:1.0.0" + } +} +``` + +Services can then opt into native Helm without repeating the runner image: + +```yaml filename="lifecycle.yaml" +services: + - name: api + helm: + deploymentMethod: "native" + chart: + name: "./charts/api" +``` + +#### Global Custom Image with Post-Renderer + +```json +{ + "nativeHelm": { + "enabled": true, + "image": "registry.example.com/helm-runner:1.0.0", + "postRenderer": { + "enabled": true, + "command": "/opt/bin/post-renderer", + "args": ["--mode=preview"] + } + } +} +``` + +#### Service-Level Override + +Service config can override either the image or the post-renderer settings: + +```yaml filename="lifecycle.yaml" +services: + - name: api + helm: + deploymentMethod: "native" + nativeHelm: + image: "registry.example.com/custom-runner:2.0.0" + postRenderer: + enabled: true + command: "/custom/bin/render" + args: + - "--tenant=preview" + chart: + name: "./charts/api" +``` + +#### Disable an Inherited Post-Renderer + +If a post-renderer is defined globally, a service can explicitly disable it: + +```yaml filename="lifecycle.yaml" +services: + - name: api + helm: + deploymentMethod: "native" + nativeHelm: + postRenderer: + enabled: false + chart: + name: "./charts/api" +``` + + + Custom runner images should include Helm and any post-renderer binary + referenced by `nativeHelm.postRenderer.command`. A common pattern is to start + from an existing Helm image and add your post-renderer binary on top. + + + + Repo-local post-renderer commands for public charts are not supported today + unless the deployment already clones the repository for another reason. For + public charts, prefer a post-renderer binary that already exists in the runner + image. + + ## Usage Examples ### Quick Experiment: Deploy Jenkins! @@ -392,7 +495,7 @@ services: dockerfilePath: "frontend/Dockerfile" env: REACT_APP_API_URL: "https://api.example.com" - REACT_APP_VERSION: "{{build.uuid}}" + REACT_APP_VERSION: "{{{buildUUID}}}" # Service using map format (common for custom charts) - name: backend @@ -431,151 +534,11 @@ services: - "deploy/helm/mysql-values.yaml" ``` -## Templated Variables - -Lifecycle supports template variables in Helm values that are resolved at deployment time. These variables allow you to reference dynamic values like build UUIDs, docker tags, and internal hostnames. - -### Available Variables - -Template variables use the format `{{{variableName}}}` and are replaced with actual values during deployment: - -| Variable | Description | Example Value | -| ------------------------------------ | ------------------------- | ---------------------------------------- | -| `{{{serviceName_dockerTag}}}` | Docker tag for a service | `main-abc123` | -| `{{{serviceName_dockerImage}}}` | Full docker image path | `registry.com/org/repo:main-abc123` | -| `{{{serviceName_internalHostname}}}` | Internal service hostname | `api-service.env-uuid.svc.cluster.local` | -| `{{{build.uuid}}}` | Build UUID | `env-12345` | -| `{{{build.namespace}}}` | Kubernetes namespace | `env-12345` | - -### Usage in Values - -```yaml filename="lifecycle.yaml" -services: - - name: web-api - helm: - deploymentMethod: "native" - chart: - name: "./charts/app" - values: - - "image.tag={{{web-api_dockerTag}}}" - - "backend.url=http://{{{backend-service_internalHostname}}}:8080" - - "env.BUILD_ID={{{build.uuid}}}" -``` - -**Docker Image Mapping**: When using custom charts, you'll need to map `{{{serviceName_dockerImage}}}` or `{{{serviceName_dockerTag}}}` to your chart's expected value path. Common patterns include: -- `image.repository` and `image.tag` (most common) -- `deployment.image` (single image string) -- `app.image` or `application.image` -- Custom paths specific to your chart - -Check your chart's `values.yaml` to determine the correct path. - + For supported template variables, see the [Template Variables + guide](/docs/features/template-variables). -#### Image Mapping Examples - -```yaml filename="lifecycle.yaml" -# Example 1: Separate repository and tag (most common) -services: - - name: web-api - helm: - chart: - name: "./charts/standard" - values: - - "image.repository=registry.com/org/web-api" # Static repository - - "image.tag={{{web-api_dockerTag}}}" # Dynamic tag only - -# Example 2: Combined image string -services: - - name: worker - helm: - chart: - name: "./charts/custom" - values: - - "deployment.image={{{worker_dockerImage}}}" # Full image with tag - -# Example 3: Nested structure -services: - - name: backend - helm: - chart: - name: "./charts/microservice" - values: - - "app.container.image={{{backend_dockerImage}}}" # Full image with tag -``` - - -**Important**: Always use triple braces `{{{variable}}}` instead of double braces `{{variable}}` for Lifecycle template variables. This prevents Helm from trying to process them as Helm template functions and ensures they are passed through correctly for Lifecycle to resolve. - - -### Template Resolution Order - -1. Lifecycle resolves `{{{variables}}}` before passing values to Helm -2. The resolved values are then passed to Helm using `--set` flags -3. Helm processes its own template functions (if any) after receiving the resolved values - -### Example with Service Dependencies - -```yaml filename="lifecycle.yaml" -services: - - name: api-gateway - helm: - chart: - name: "./charts/gateway" - values: - - "config.authServiceUrl=http://{{{auth-service_internalHostname}}}:3000" - - "config.userServiceUrl=http://{{{user-service_internalHostname}}}:3000" - - "image.tag={{{api-gateway_dockerTag}}}" - - - name: auth-service - helm: - chart: - name: "./charts/microservice" - values: - - "image.tag={{{auth-service_dockerTag}}}" - - "database.host={{{postgres-db_internalHostname}}}" -``` - -## Deployment Process - - - 1. **Job Creation**: A Kubernetes job is created in the ephemeral namespace 2. - **RBAC Setup**: Service account with namespace-scoped permissions is created - 3. **Git Clone**: Init container clones the repository 4. **Helm Deploy**: - Main container executes the Helm deployment 5. **Monitoring**: Logs are - streamed in real-time via WebSocket - - -### Concurrent Deployment Handling - -Native Helm automatically handles concurrent deployments by: - -- Detecting existing deployment jobs -- Force-deleting the old job -- Starting the new deployment - -This ensures the newest deployment always takes precedence. - -## Monitoring Deployments - -### Deploy Logs Access - -For services using native Helm deployment, you can access deployment logs through the Lifecycle PR comment: - -1. Add the `lifecycle-status-comments!` label to your PR -2. In the status comment that appears, you'll see a **Deploy Logs** link for each service using native Helm -3. Click the link to view real-time deployment logs - -### Log Contents - -The deployment logs show: - -- Git repository cloning progress (`clone-repo` container) -- Helm deployment execution (`helm-deploy` container) -- Real-time streaming of all deployment output -- Success or failure status - ## Chart Types Lifecycle automatically detects and handles three chart types: @@ -739,7 +702,6 @@ services: chart: name: "./charts/microservices" values: - - 'image.tag="{{{api-gateway_dockerTag}}}"' - "service.type=LoadBalancer" - "ingress.enabled=true" valueFiles: @@ -752,7 +714,7 @@ services: app: dockerfilePath: "docker/api.dockerfile" env: - BACKEND_URL: "{{backend-service_internalHostname}}:3000" + BACKEND_URL: "{{{backend-service_internalHostname}}}:3000" LOG_LEVEL: "info" ENV_NAME: "production" ports: @@ -771,7 +733,6 @@ services: chart: name: "./charts/microservices" values: - - 'image.tag="{{{backend-service_dockerTag}}}"' - "replicaCount=2" valueFiles: - "deploy/helm/base-values.yaml" diff --git a/src/pages/docs/features/template-variables.mdx b/src/pages/docs/features/template-variables.mdx index a018bb70..4754da13 100644 --- a/src/pages/docs/features/template-variables.mdx +++ b/src/pages/docs/features/template-variables.mdx @@ -35,6 +35,9 @@ The following template variables are available for use within your configuration For service-specific variables, replace `` with the actual service name. +- **`{{{_branchName}}}`** - The branch name associated with that service's deployment. +- **`{{{_dockerImage}}}`** - The fully qualified Docker image reference for the service. +- **`{{{_initDockerImage}}}`** - The fully qualified Docker image reference for the service's init container image. - **`{{{_internalHostname}}}`** - The internal hostname of the deployed service. If the service is optional and not deployed, it falls back to `defaultInternalHostname`. @@ -43,9 +46,10 @@ For service-specific variables, replace `` with the actual service with deployments across namespaces. +- **`{{{_ipAddress}}}`** - The service IP address. +- **`{{{_namespace}}}`** - The Kubernetes namespace used by the service. - **`{{{_publicUrl}}}`** - The public URL of the deployed service. If optional and not deployed, it defaults to `defaultPublicUrl` under the `services` table. - **`{{{_sha}}}`** - The GitHub SHA that triggered the Lifecycle build. -- **`{{{_branchName}}}`** - The branch name of the pull request that deployed the environment. - **`{{{_UUID}}}`** - The build UUID of the service. If listed under `optionalServices` or `defaultServices`, its value depends on whether the service is selected: - If selected, it is equal to `buildUUID`. - If not selected (or if service not part of deploys created), it defaults to **`dev-0`**. @@ -59,6 +63,8 @@ services: env: API_URL: "{{{backend_publicUrl}}}" UUID: "{{{buildUUID}}}" + BACKEND_IMAGE: "{{{backend_dockerImage}}}" + BACKEND_NAMESPACE: "{{{backend_namespace}}}" ``` This ensures the `PUBLIC_URL` and `INTERNAL_HOST` variables are dynamically assigned based on the ephemeral environment deployment. diff --git a/src/pages/docs/schema/helm.mdx b/src/pages/docs/schema/helm.mdx index 80ded569..46a2e11b 100644 --- a/src/pages/docs/schema/helm.mdx +++ b/src/pages/docs/schema/helm.mdx @@ -270,6 +270,32 @@ Configuration for an init container that runs before the main application. Uses | `deploymentMethod` | string | No | `"native"` or `"ci"` | | `envLens` | boolean | No | Enable environment lens ingress banner. Overrides the global `features.envLens` default. | +## Native Helm Configuration + +When `deploymentMethod: "native"` is enabled, you can further customize the +native Helm job with the `nativeHelm` block. + +```yaml filename="lifecycle.yaml" +services: + - name: "api" + helm: + deploymentMethod: "native" + nativeHelm: + postRenderer: + enabled: true + command: "/opt/bin/post-renderer" + args: + - "--mode=preview" + chart: + name: "./charts/api" +``` + +| Field | Type | Required | Description | +| --------------------------------- | ------- | -------- | ----------------------------------------------------------------- | +| `nativeHelm.postRenderer.enabled` | boolean | No | Enables or disables an inherited post-renderer | +| `nativeHelm.postRenderer.command` | string | No | Executable passed to Helm with `--post-renderer` | +| `nativeHelm.postRenderer.args` | array | No | Arguments passed to Helm as repeated `--post-renderer-args` flags | + ## Templated Variables Use templated variables in chart values to reference dynamic deployment values. See the [Template Variables](/docs/features/template-variables) guide for the complete list.