Skip to content

Instantly share code, notes, and snippets.

@EronWright
Last active July 20, 2024 22:42
Show Gist options
  • Save EronWright/2dc38b79c744605ce77dcd3d282b8604 to your computer and use it in GitHub Desktop.
Save EronWright/2dc38b79c744605ce77dcd3d282b8604 to your computer and use it in GitHub Desktop.
Pulumi Go SDK using transforms
package main
import (
"context"
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"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/internals"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
cfg := config.New(ctx, "")
k8sNamespace, err := cfg.Try("k8sNamespace")
if err != nil {
k8sNamespace = "default"
}
appLabels := pulumi.StringMap{
"app": pulumi.String("nginx-ingress"),
}
// Create a new namespace (user supplies the name of the namespace)
ingressNs, err := corev1.NewNamespace(ctx, "ingressns", &corev1.NamespaceArgs{
Metadata: &metav1.ObjectMetaArgs{
Labels: pulumi.StringMap(appLabels),
Name: pulumi.String(k8sNamespace),
},
})
if err != nil {
return err
}
applyPatchForceAnnotation := func(ctx context.Context, rta *pulumi.ResourceTransformArgs) *pulumi.ResourceTransformResult {
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.
unstructured.SetNestedField(obj, "true", "metadata", "annotations", "pulumi.com/patchForce")
return pulumi.ToMap(obj)
})
}
return &pulumi.ResourceTransformResult{
Props: rta.Props,
Opts: rta.Opts,
}
}
transformImage := func(ctx context.Context, rta *pulumi.ResourceTransformArgs) *pulumi.ResourceTransformResult {
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:apps/v1:Deployment":
transform(func(obj map[string]any) pulumi.Map {
// note: obj is an ordinary Unstructured object at this point.
// get the name of the deployment
name, _, _ := unstructured.NestedString(obj, "metadata", "name")
if name == "ingresscontroller-nginx-ingress" {
// change the image field for demonstration purposes
containers, _, _ := unstructured.NestedFieldNoCopy(obj, "spec", "template", "spec", "containers")
container := containers.([]any)[0].(map[string]any)
unstructured.SetNestedField(container, "nginx/nginx-ingress:2.3.1-patched", "image")
}
return pulumi.ToMap(obj)
})
}
return &pulumi.ResourceTransformResult{
Props: rta.Props,
Opts: rta.Opts,
}
}
// Use Helm to install the Nginx ingress controller
_, err = helmv4.NewChart(ctx, "ingresscontroller", &helmv4.ChartArgs{
Chart: pulumi.String("nginx-ingress"),
Namespace: ingressNs.Metadata.Name(),
RepositoryOpts: &helmv4.RepositoryOptsArgs{
Repo: pulumi.String("https://helm.nginx.com/stable"),
},
SkipCrds: pulumi.Bool(true),
Values: pulumi.Map{
"controller": pulumi.Map{
"enableCustomResources": pulumi.Bool(false),
"appprotect": pulumi.Map{
"enable": pulumi.Bool(false),
},
"appprotectdos": pulumi.Map{
"enable": pulumi.Bool(false),
},
"service": pulumi.Map{
"extraLabels": appLabels,
},
},
},
Version: pulumi.String("0.14.1"),
}, pulumi.Transforms([]pulumi.ResourceTransform{applyPatchForceAnnotation, transformImage}))
if err != nil {
return err
}
return nil
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment