Skip to content

Commit

Permalink
feat: Install Helm Charts using the Chart resource tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
dirien committed Dec 16, 2024
1 parent 7e52ddd commit 5ee7ae5
Show file tree
Hide file tree
Showing 20 changed files with 629 additions and 7 deletions.
10 changes: 5 additions & 5 deletions content/tutorials/kubernetes-helm-part-one/index.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
title_tag: How to Install Helm Charts on Kubernetes with Pulumi - Part 1
title_tag: Install Helm Charts using the Release resource
allow_long_title: true
title: How to Install Helm Charts on Kubernetes with Pulumi - Part 1
title: Install Helm Charts using the Release resource
layout: single
description: |
Using Pulumi to install Helm Charts on Kubernetes is a great way to manage to install third-party applications on your Kubernetes cluster.
Learn how to use the `Release` resource from the Pulumi Kubernetes provider to install Helm charts on Kubernetes.
meta_desc: Using Pulumi to install Helm Charts on Kubernetes is a great way to manage to install third-party applications on your Kubernetes cluster.
meta_image: meta.png
weight: 999
summary: |
If you worked with Pulumi and [Kubernetes](https://kubernetes.io/), you probably know that Pulumi has a [Kubernetes provider](/docs/iac/get-started/kubernetes/) that allows you to deploy Kubernetes resources.
In this tutorial, we will learn how to install Helm on Kubernetes using Pulumi. [Helm](https://helm.sh/) is a package manager for Kubernetes that allows you to install and manage applications on your Kubernetes cluster.
In this tutorial, we will learn how to install Helm chart on Kubernetes using Pulumi. [Helm](https://helm.sh/) is a package manager for Kubernetes that allows you to install and manage applications on your Kubernetes cluster.
Most of the third-party applications that you want to install on your Kubernetes cluster, like whole monitoring stacks, databases, and other applications, are most likely available as Helm charts.
Expand Down Expand Up @@ -167,7 +167,7 @@ NAME DESIRED
replicaset.apps/ingresscontroller-b5455c41-nginx-ingress-5987c7bd56 1 1 1 104s
```

## Deploying a OCI Helm chart with Pulumi
## Deploying an OCI Helm chart with Pulumi

In the previous example, we deployed a Helm chart from a Helm repository. Helm supports also [OCI registries](https://helm.sh/blog/storing-charts-in-oci/) as a way to share Helm charts. The changes in the Pulumi program are minimal.

Expand Down
Binary file modified content/tutorials/kubernetes-helm-part-one/meta.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
265 changes: 265 additions & 0 deletions content/tutorials/kubernetes-helm-part-two/index.md

Large diffs are not rendered by default.

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 layouts/taxonomy/collection.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h3 class="no-anchor font-normal text-xl flex items-center">
</h3>
</div>
<p class="text-base text-gray-700 mb-6">
{{ $item.Description }}
{{ $item.Description | markdownify }}
</p>
<div class="inline-flex flex-wrap gap-2 text-sm">
{{ $estimated_time := 0 }}
Expand Down
51 changes: 51 additions & 0 deletions static/programs/helm-kubernetes-part-two-csharp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Pulumi;
using Pulumi.Experimental.Provider;
using Pulumi.Kubernetes.Helm.V4;
using Pulumi.Kubernetes.Types.Inputs;
using Pulumi.Kubernetes.Types.Inputs.Helm.V4;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Immutable;

await Deployment.RunAsync<MyStack>();


class MyStack : Stack
{
public MyStack()
{
var certman = new Chart("cert-manager", new ChartArgs
{
Namespace = "cert-manager",
Chart = "oci://registry-1.docker.io/bitnamicharts/cert-manager",
Version = "1.3.1",
},
new ComponentResourceOptions
{
ResourceTransforms =
{
async (args, _) =>
{
Console.WriteLine("Transforming resource");
if (args.Type != "kubernetes:helm.sh/v4:Chart")
{
var myTags = ImmutableDictionary.Create<string, object>().Add("cost-center", "12345");

InputMap<object> tags =
args.Args.TryGetValue("metadata", out var tagsValue) && tagsValue is not null ?
tagsValue is Output<ImmutableDictionary<string, object>> tagsOutput ? tagsOutput :
tagsValue is ImmutableDictionary<string, object> tagsDictionary ? tagsDictionary :
throw new InvalidOperationException($"Unexpected tags type: {tagsValue.GetType()}") :
ImmutableDictionary<string, object>.Empty;

tags = tags.Apply(t => t.SetItems(myTags));
return new( args.Args.SetItem("metadata", tags), args.Options);
}
return null;
},
},
});
}
}
7 changes: 7 additions & 0 deletions static/programs/helm-kubernetes-part-two-csharp/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: helm-kubernetes-part-two-csharp
description: Demo Code Part 2 of the Tutorial around Helm in Kubernetes
runtime: dotnet
config:
pulumi:tags:
value:
pulumi:template: kubernetes-csharp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Pulumi" Version="3.*" />
<PackageReference Include="Pulumi.Kubernetes" Version="4.*" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions static/programs/helm-kubernetes-part-two-go/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: helm-kubernetes-part-two-go
description: Demo Code Part 2 of the Tutorial around Helm in Kubernetes
runtime: go
config:
pulumi:tags:
value:
pulumi:template: kubernetes-go
107 changes: 107 additions & 0 deletions static/programs/helm-kubernetes-part-two-go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
module helm-kubernetes-part-two-go

go 1.23.0

toolchain go1.23.4

require (
github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.12.0
github.com/pulumi/pulumi/sdk/v3 v3.117.0
k8s.io/apimachinery v0.32.0
)

require (
dario.cat/mergo v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/charmbracelet/bubbles v0.16.1 // indirect
github.com/charmbracelet/bubbletea v0.24.2 // indirect
github.com/charmbracelet/lipgloss v0.7.1 // indirect
github.com/cheggaaa/pb v1.0.29 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/djherbis/times v1.5.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-git/go-git/v5 v5.12.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/hcl/v2 v2.17.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/opentracing/basictracer-go v1.1.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pgavlin/fx v0.1.6 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/term v1.1.0 // indirect
github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect
github.com/pulumi/esc v0.6.2 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/texttheater/golang-levenshtein v1.0.1 // indirect
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 // indirect
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/zclconf/go-cty v1.13.2 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
lukechampine.com/frand v1.4.2 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
54 changes: 54 additions & 0 deletions static/programs/helm-kubernetes-part-two-go/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"context"

helmv4 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/helm/v4"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/internals"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

func main() {

applyPatchForceAnnotation := func(ctx context.Context, rta *pulumi.XResourceTransformArgs) *pulumi.XResourceTransformResult {
transform := func(applier interface{}) {
o := rta.Props.ToMapOutputWithContext(ctx).ApplyT(applier)
r, err := internals.UnsafeAwaitOutput(ctx, o)
if err != nil {
panic(err)
}
rta.Props = r.Value.(pulumi.Map)
}

switch rta.Type {
case "kubernetes:helm.sh/v4:Chart":
// Do nothing for Helm charts
default:
transform(func(obj map[string]any) pulumi.Map {
// note: obj is an ordinary Unstructured object at this point.
err := unstructured.SetNestedField(obj, "12345", "metadata", "annotations", "cost-center")
if err != nil {
return nil
}
return pulumi.ToMap(obj)
})
}
return &pulumi.XResourceTransformResult{
Props: rta.Props,
Opts: rta.Opts,
}
}

pulumi.Run(func(ctx *pulumi.Context) error {
_, err := helmv4.NewChart(ctx, "cert-manager", &helmv4.ChartArgs{
Namespace: pulumi.String("cert-manager"),
Chart: pulumi.String("oci://registry-1.docker.io/bitnamicharts/cert-manager"),
Version: pulumi.String("1.3.1"),
}, pulumi.Transforms([]pulumi.XResourceTransform{applyPatchForceAnnotation}))
if err != nil {
return err
}
return nil
})
}
11 changes: 11 additions & 0 deletions static/programs/helm-kubernetes-part-two-python/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: helm-kubernetes-part-two-python
description: Demo Code Part 2 of the Tutorial around Helm in Kubernetes
runtime:
name: python
options:
toolchain: pip
virtualenv: venv
config:
pulumi:tags:
value:
pulumi:template: kubernetes-python
21 changes: 21 additions & 0 deletions static/programs/helm-kubernetes-part-two-python/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pulumi
import pulumi_kubernetes as kubernetes

def apply_patchforce_annotation(args: pulumi.ResourceTransformArgs):
if not args.type_ == "kubernetes:helm.sh/v4:Chart":
if not "metadata" in args.props:
args.props["metadata"] = {}
if not "annotations" in args.props["metadata"]:
args.props["metadata"]["annotations"] = {}
args.props["metadata"]["annotations"]["cost-center"] = "12345"

return pulumi.ResourceTransformResult(props=args.props, opts=args.opts)


certman = kubernetes.helm.v4.Chart(
"cert-manager",
namespace="cert-manager",
chart="oci://registry-1.docker.io/bitnamicharts/cert-manager",
version="1.3.1",
opts=pulumi.ResourceOptions(transforms=[apply_patchforce_annotation])
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pulumi>=3.0.0,<4.0.0
pulumi-kubernetes>=4.0.0,<5.0.0
10 changes: 10 additions & 0 deletions static/programs/helm-kubernetes-part-two-typescript/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: helm-kubernetes-part-two-typescript
description: Demo Code Part 2 of the Tutorial around Helm in Kubernetes
runtime:
name: nodejs
options:
packagemanager: npm
config:
pulumi:tags:
value:
pulumi:template: kubernetes-typescript
34 changes: 34 additions & 0 deletions static/programs/helm-kubernetes-part-two-typescript/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as pulumi from "@pulumi/pulumi";
import * as kubernetes from "@pulumi/kubernetes";

const applyPatchForceAnnotation = async (args: pulumi.ResourceTransformArgs) => {
switch (args.type) {
case "kubernetes:helm.sh/v4:Chart":
break;
default:
args.props.metadata.annotations = {
"cost-center": "12345",
...args.props.metadata.annotations,
};
}
return {
props: args.props,
opts: args.opts,
};
};

const ns = new kubernetes.core.v1.Namespace("cert-manager", {
metadata: {
name: "cert-manager",
},
});

const certman = new kubernetes.helm.v4.Chart(
"cert-manager",
{
namespace: "cert-manager",
chart: "oci://registry-1.docker.io/bitnamicharts/cert-manager",
version: "1.3.1",
},
{ transforms: [applyPatchForceAnnotation] },
);
12 changes: 12 additions & 0 deletions static/programs/helm-kubernetes-part-two-typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "helm-kubernetes-part-two-typescript",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0"
},
"dependencies": {
"@pulumi/kubernetes": "^4.0.0",
"@pulumi/pulumi": "^3.113.0"
}
}
16 changes: 16 additions & 0 deletions static/programs/helm-kubernetes-part-two-typescript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2020",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": ["index.ts"]
}
Loading

0 comments on commit 5ee7ae5

Please sign in to comment.