Skip to content

Latest commit

 

History

History
653 lines (579 loc) · 18.4 KB

File metadata and controls

653 lines (579 loc) · 18.4 KB

Chart is a component representing a collection of resources described by a Helm Chart. Helm charts are a popular packaging format for Kubernetes applications, and published to registries such as Artifact Hub.

Chart does not use Tiller or create a Helm Release; the semantics are equivalent to running helm template --dry-run=server and then using Pulumi to deploy the resulting YAML manifests. This allows you to apply Pulumi Transformations and Pulumi Policies to the Kubernetes resources.

You may also want to consider the Release resource as an alternative method for managing helm charts. For more information about the trade-offs between these options, see: Choosing the right Helm resource for your use case.

Chart Resolution

The Helm Chart can be fetched from any source that is accessible to the helm command line. The following variations are supported:

  1. By chart reference with repo prefix: chart: "example/mariadb"
  2. By path to a packaged chart: chart: "./nginx-1.2.3.tgz"
  3. By path to an unpacked chart directory: chart: "./nginx"
  4. By absolute URL: chart: "https://example.com/charts/nginx-1.2.3.tgz"
  5. By chart reference with repo URL: chart: "nginx", repositoryOpts: { repo: "https://example.com/charts/" }
  6. By OCI registries: chart: "oci://example.com/charts/nginx", version: "1.2.3"

A chart reference is a convenient way of referencing a chart in a chart repository.

When you use a chart reference with a repo prefix (example/mariadb), Pulumi will look in Helm's local configuration for a chart repository named example, and will then look for a chart in that repository whose name is mariadb. It will install the latest stable version of that chart, unless you specify devel to also include development versions (alpha, beta, and release candidate releases), or supply a version number with version.

Use the verify and optional keyring inputs to enable Chart verification. By default, Pulumi uses the keyring at $HOME/.gnupg/pubring.gpg. See: Helm Provenance and Integrity.

Chart Values

Values files (values.yaml) may be supplied with the valueYamlFiles input, accepting Pulumi Assets.

A map of chart values may also be supplied with the values input, with highest precedence. You're able to use literals, nested maps, Pulumi outputs, and Pulumi assets as values. Assets are automatically opened and converted to a string.

Note that the use of expressions (e.g. service.type) is not supported.

Chart Dependency Resolution

For unpacked chart directories, Pulumi automatically rebuilds the dependencies if dependencies are missing and a Chart.lock file is present (see: Helm Dependency Build). Use the dependencyUpdate input to have Pulumi update the dependencies (see: Helm Dependency Update).

Templating

The Chart resource renders the templates from your chart and then manages the resources directly with the Pulumi Kubernetes provider. A default namespace is applied based on the namespace input, the provider's configured namespace, and the active Kubernetes context. Use the skipCrds option to skip installing the Custom Resource Definition (CRD) objects located in the chart's crds/ special directory.

Use the postRenderer input to pipe the rendered manifest through a post-rendering command.

Resource Ordering

Sometimes resources must be applied in a specific order. For example, a namespace resource must be created before any namespaced resources, or a Custom Resource Definition (CRD) must be pre-installed.

Pulumi uses heuristics to determine which order to apply and delete objects within the Chart. Pulumi also waits for each object to be fully reconciled, unless skipAwait is enabled.

Pulumi supports the config.kubernetes.io/depends-on annotation to declare an explicit dependency on a given resource. The annotation accepts a list of resource references, delimited by commas.

Note that references to resources outside the Chart aren't supported.

Resource reference

A resource reference is a string that uniquely identifies a resource.

It consists of the group, kind, name, and optionally the namespace, delimited by forward slashes.

Resource Scope Format
namespace-scoped <group>/namespaces/<namespace>/<kind>/<name>
cluster-scoped <group>/<kind>/<name>

For resources in the “core” group, the empty string is used instead (for example: /namespaces/test/Pod/pod-a).

{{% examples %}}

Example Usage

{{% example %}}

Local Chart Directory

import * as k8s from "@pulumi/kubernetes";

const nginx = new k8s.helm.v4.Chart("nginx", {
    chart: "./nginx",
});
import pulumi
from pulumi_kubernetes.helm.v4 import Chart

nginx = Chart("nginx",
    chart="./nginx"
)
package main

import (
	helmv4 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/helm/v4"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := helmv4.NewChart(ctx, "nginx", &helmv4.ChartArgs{
			Chart: pulumi.String("./nginx"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using Pulumi;
using Pulumi.Kubernetes.Types.Inputs.Helm.V4;
using System.Collections.Generic;

return await Deployment.RunAsync(() =>
{
    new Pulumi.Kubernetes.Helm.V4.Chart("nginx", new ChartArgs
    {
        Chart = "./nginx"
    });
    return new Dictionary<string, object?>{};
});
package generated_program;

import com.pulumi.Pulumi;
import com.pulumi.kubernetes.helm.v4.Chart;
import com.pulumi.kubernetes.helm.v4.ChartArgs;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var nginx = new Chart("nginx", ChartArgs.builder()
                    .chart("./nginx")
                    .build());
        });
    }
}
name: example
runtime: yaml
resources:
  nginx:
    type: kubernetes:helm.sh/v4:Chart
    properties:
      chart: ./nginx

{{% /example %}} {{% example %}}

Repository Chart

import * as k8s from "@pulumi/kubernetes";

const nginx = new k8s.helm.v4.Chart("nginx", {
    chart: "nginx",
    repositoryOpts: {
        repo: "https://charts.bitnami.com/bitnami",
    },
});
import pulumi
from pulumi_kubernetes.helm.v4 import Chart,RepositoryOptsArgs

nginx = Chart("nginx",
    chart="nginx",
    repository_opts=RepositoryOptsArgs(
        repo="https://charts.bitnami.com/bitnami",
    )
)
package main

import (
	helmv4 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/helm/v4"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := helmv4.NewChart(ctx, "nginx", &helmv4.ChartArgs{
			Chart: pulumi.String("nginx"),
			RepositoryOpts: &helmv4.RepositoryOptsArgs{
				Repo: pulumi.String("https://charts.bitnami.com/bitnami"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using Pulumi;
using Pulumi.Kubernetes.Types.Inputs.Helm.V4;
using System.Collections.Generic;

return await Deployment.RunAsync(() =>
{
    new Pulumi.Kubernetes.Helm.V4.Chart("nginx", new ChartArgs
    {
        Chart = "nginx",
        RepositoryOpts = new RepositoryOptsArgs
        {
            Repo = "https://charts.bitnami.com/bitnami"
        },
    });
    
    return new Dictionary<string, object?>{};
});
package generated_program;

import com.pulumi.Pulumi;
import com.pulumi.kubernetes.helm.v4.Chart;
import com.pulumi.kubernetes.helm.v4.ChartArgs;
import com.pulumi.kubernetes.helm.v4.inputs.RepositoryOptsArgs;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var nginx = new Chart("nginx", ChartArgs.builder()
                    .chart("nginx")
                    .repositoryOpts(RepositoryOptsArgs.builder()
                            .repo("https://charts.bitnami.com/bitnami")
                            .build())
                    .build());
        });
    }
}
name: example
runtime: yaml
resources:
  nginx:
    type: kubernetes:helm.sh/v4:Chart
    properties:
      chart: nginx
      repositoryOpts:
        repo: https://charts.bitnami.com/bitnami

{{% /example %}} {{% example %}}

OCI Chart

import * as k8s from "@pulumi/kubernetes";

const nginx = new k8s.helm.v4.Chart("nginx", {
    chart: "oci://registry-1.docker.io/bitnamicharts/nginx",
    version: "16.0.7",
});
import pulumi
from pulumi_kubernetes.helm.v4 import Chart

nginx = Chart("nginx",
    chart="oci://registry-1.docker.io/bitnamicharts/nginx",
    version="16.0.7",
)
package main

import (
	helmv4 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/helm/v4"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := helmv4.NewChart(ctx, "nginx", &helmv4.ChartArgs{
			Chart:   pulumi.String("oci://registry-1.docker.io/bitnamicharts/nginx"),
			Version: pulumi.String("16.0.7"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using Pulumi;
using Pulumi.Kubernetes.Types.Inputs.Helm.V4;
using System.Collections.Generic;

return await Deployment.RunAsync(() =>
{
    new Pulumi.Kubernetes.Helm.V4.Chart("nginx", new ChartArgs
    {
        Chart = "oci://registry-1.docker.io/bitnamicharts/nginx",
        Version = "16.0.7",
    });
    
    return new Dictionary<string, object?>{};
});
package generated_program;

import com.pulumi.Pulumi;
import com.pulumi.kubernetes.helm.v4.Chart;
import com.pulumi.kubernetes.helm.v4.ChartArgs;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var nginx = new Chart("nginx", ChartArgs.builder()
                    .chart("oci://registry-1.docker.io/bitnamicharts/nginx")
                    .version("16.0.7")
                    .build());
        });
    }
}
name: example
runtime: yaml
resources:
  nginx:
    type: kubernetes:helm.sh/v4:Chart
    properties:
      chart: oci://registry-1.docker.io/bitnamicharts/nginx
      version: "16.0.7"

{{% /example %}} {{% example %}}

Chart Values

import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";

const nginx = new k8s.helm.v4.Chart("nginx", {
    chart: "nginx",
    repositoryOpts: {
        repo: "https://charts.bitnami.com/bitnami",
    },
    valueYamlFiles: [
        new pulumi.asset.FileAsset("./values.yaml")
    ],
    values: {
        service: {
            type: "ClusterIP",
        },
        notes: new pulumi.asset.FileAsset("./notes.txt"),
    },
});
"""A Kubernetes Python Pulumi program"""

import pulumi
from pulumi_kubernetes.helm.v4 import Chart,RepositoryOptsArgs

nginx = Chart("nginx",
    chart="nginx",
    repository_opts=RepositoryOptsArgs(
        repo="https://charts.bitnami.com/bitnami"
    ),
    value_yaml_files=[
        pulumi.FileAsset("./values.yaml")
    ],
    values={
        "service": {
            "type": "ClusterIP"
        },
        "notes": pulumi.FileAsset("./notes.txt")
    }
)
package main

import (
	helmv4 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/helm/v4"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := helmv4.NewChart(ctx, "nginx", &helmv4.ChartArgs{
			Chart: pulumi.String("nginx"),
			RepositoryOpts: &helmv4.RepositoryOptsArgs{
				Repo: pulumi.String("https://charts.bitnami.com/bitnami"),
			},
			ValueYamlFiles: pulumi.AssetOrArchiveArray{
				pulumi.NewFileAsset("./values.yaml"),
			},
			Values: pulumi.Map{
				"service": pulumi.Map{
					"type": pulumi.String("ClusterIP"),
				},
				"notes": pulumi.NewFileAsset("./notes.txt"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using Pulumi;
using Pulumi.Kubernetes.Types.Inputs.Helm.V4;
using System.Collections.Generic;

return await Deployment.RunAsync(() =>
{
    new Pulumi.Kubernetes.Helm.V4.Chart("nginx", new ChartArgs
    {
        Chart = "nginx",
        RepositoryOpts = new RepositoryOptsArgs
        {
            Repo = "https://charts.bitnami.com/bitnami"
        },
        ValueYamlFiles = 
        {
            new FileAsset("./values.yaml") 
        },
        Values = new InputMap<object>
        {
            ["service"] = new InputMap<object>
            {
                ["type"] = "ClusterIP",
            },
            ["notes"] = new FileAsset("./notes.txt")
        },
    });
    
    return new Dictionary<string, object?>{};
});
package generated_program;

import java.util.Map;

import com.pulumi.Pulumi;
import com.pulumi.kubernetes.helm.v4.Chart;
import com.pulumi.kubernetes.helm.v4.ChartArgs;
import com.pulumi.kubernetes.helm.v4.inputs.RepositoryOptsArgs;
import com.pulumi.asset.FileAsset;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var nginx = new Chart("nginx", ChartArgs.builder()
                    .chart("nginx")
                    .repositoryOpts(RepositoryOptsArgs.builder()
                            .repo("https://charts.bitnami.com/bitnami")
                            .build())
                    .valueYamlFiles(new FileAsset("./values.yaml"))
                    .values(Map.of(
                            "service", Map.of(
                                    "type", "ClusterIP"),
                            "notes", new FileAsset("./notes.txt")))
                    .build());
        });
    }
}
name: example
runtime: yaml
resources:
  nginx:
    type: kubernetes:helm.sh/v4:Chart
    properties:
      chart: nginx
      repositoryOpts:
        repo: https://charts.bitnami.com/bitnami
      valueYamlFiles:
      - fn::fileAsset: values.yaml
      values:
        service:
          type: ClusterIP
        notes:
          fn::fileAsset: notes.txt

{{% /example %}} {{% example %}}

Chart Namespace

import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";

const ns = new k8s.core.v1.Namespace("nginx", {
    metadata: { name: "nginx" },
});
const nginx = new k8s.helm.v4.Chart("nginx", {
    namespace: ns.metadata.name,
    chart: "nginx",
    repositoryOpts: {
        repo: "https://charts.bitnami.com/bitnami",
    }
});
import pulumi
from pulumi_kubernetes.meta.v1 import ObjectMetaArgs
from pulumi_kubernetes.core.v1 import Namespace
from pulumi_kubernetes.helm.v4 import Chart,RepositoryOptsArgs

ns = Namespace("nginx",
    metadata=ObjectMetaArgs(
        name="nginx",
    )
)
nginx = Chart("nginx",
    namespace=ns.metadata.name,
    chart="nginx",
    repository_opts=RepositoryOptsArgs(
        repo="https://charts.bitnami.com/bitnami",
    )
)
package main

import (
	corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1"
	helmv4 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/helm/v4"
	metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/meta/v1"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		ns, err := corev1.NewNamespace(ctx, "nginx", &corev1.NamespaceArgs{
			Metadata: &metav1.ObjectMetaArgs{Name: pulumi.String("nginx")},
		})
		if err != nil {
			return err
		}
		_, err = helmv4.NewChart(ctx, "nginx", &helmv4.ChartArgs{
            Namespace: ns.Metadata.Name(),
			Chart:     pulumi.String("nginx"),
			RepositoryOpts: &helmv4.RepositoryOptsArgs{
				Repo: pulumi.String("https://charts.bitnami.com/bitnami"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using Pulumi;
using Pulumi.Kubernetes.Types.Inputs.Core.V1;
using Pulumi.Kubernetes.Types.Inputs.Meta.V1;
using Pulumi.Kubernetes.Types.Inputs.Helm.V4;
using System.Collections.Generic;

return await Deployment.RunAsync(() =>
{
    var ns = new Pulumi.Kubernetes.Core.V1.Namespace("nginx", new NamespaceArgs
    {
        Metadata = new ObjectMetaArgs{Name = "nginx"}
    });
    new Pulumi.Kubernetes.Helm.V4.Chart("nginx", new ChartArgs
    {
        Namespace = ns.Metadata.Apply(m => m.Name),
        Chart = "nginx",
        RepositoryOpts = new RepositoryOptsArgs
        {
            Repo = "https://charts.bitnami.com/bitnami"
        },
    });
    
    return new Dictionary<string, object?>{};
});
package generated_program;

import com.pulumi.Pulumi;
import com.pulumi.kubernetes.core.v1.Namespace;
import com.pulumi.kubernetes.core.v1.NamespaceArgs;
import com.pulumi.kubernetes.helm.v4.Chart;
import com.pulumi.kubernetes.helm.v4.ChartArgs;
import com.pulumi.kubernetes.helm.v4.inputs.RepositoryOptsArgs;
import com.pulumi.kubernetes.meta.v1.inputs.ObjectMetaArgs;
import com.pulumi.core.Output;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var ns = new Namespace("nginx", NamespaceArgs.builder()
                    .metadata(ObjectMetaArgs.builder()
                            .name("nginx")
                            .build())
                    .build());
            var nginx = new Chart("nginx", ChartArgs.builder()
                    .namespace(ns.metadata().apply(m -> Output.of(m.name().get())))
                    .chart("nginx")
                    .repositoryOpts(RepositoryOptsArgs.builder()
                            .repo("https://charts.bitnami.com/bitnami")
                            .build())
                    .build());
        });
    }
}
name: example
runtime: yaml
resources:
  ns:
    type: kubernetes:core/v1:Namespace
    properties:
      metadata:
        name: nginx
  nginx:
    type: kubernetes:helm.sh/v4:Chart
    properties:
      namespace: ${ns.metadata.name}
      chart: nginx
      repositoryOpts:
        repo: https://charts.bitnami.com/bitnami

{{% /example %}} {{% /examples %}}