late-balloon-24601
11/07/2025, 5:41 PMk8s.helm.v3.Release containing CRDs that I'd like to move to v4.Chart (why yes I do have CRDs that are almost a year out of date now, how did you know?). To avoid deleting the CRDs I want to add retainOnDelete: true to the v3 release, then replace it with a v4.Chart, but afaik this would require two deployments, so I'd have to ensure that all dependent projects are upgraded to the version that has retainOnDelete before I can actually do the v4.Chart replacement.
If not, I'm somewhat curious if a dynamic provider based on umzug could work...late-balloon-24601
11/07/2025, 6:00 PMlate-balloon-24601
11/07/2025, 6:13 PMconst oldV3Chart = new NullResource(name, {}, {
parent: this,
retainOnDelete: true,
aliases: [{
type: 'kubernetes:<http://helm.sh/v3:Release|helm.sh/v3:Release>',
}],
})
this.chart = this.helmV4Chart(name, {
name: props.releaseName ?? 'kube-prometheus-stack-crds',
chart: 'prometheus-operator-crds',
namespace: 'default',
version: props.chart?.version,
repositoryOpts: {
repo: '<https://prometheus-community.github.io/helm-charts>',
},
values: this.getOverriddenChartValues(props.chart, {
crds: {
annotations: {
'<http://pulumi.com/patchForce|pulumi.com/patchForce>': 'true'
}
}
}),
}, pulumi.mergeOptions(opts, {
aliases: [{
parent: opts?.parent,
}],
parent: this,
dependsOn: [oldV3Chart],
}))
But I think the desire for a multi-step 'migration' type thing that's a bit more advanced than aliases might still be a relevant discussionmodern-spring-15520
11/07/2025, 6:32 PMlate-balloon-24601
11/07/2025, 6:38 PMmigrateV3ToV4Chart(...args: ConstructorParameters<typeof k8s.helm.v4.Chart>): k8s.helm.v4.Chart {
const [name, props, opts] = args
const oldV3Chart = new NullResource(name, {}, pulumi.mergeOptions(opts ?? {}, {
retainOnDelete: true,
aliases: [{
type: 'kubernetes:helm.sh/v3:Release',
}],
}))
return this.helmV4Chart(name, props, pulumi.mergeOptions(opts ?? {}, {
dependsOn: [oldV3Chart],
transforms: [args => {
if (isTransformType<pulumi.Unwrap<k8s.apiextensions.v1.CustomResourceDefinitionArgs>>(args, 'kubernetes:apiextensions.k8s.io/v1:CustomResourceDefinition')) {
args.props.metadata ??= {}
args.props.metadata.annotations = {
...args.props.metadata.annotations,
'pulumi.com/patchForce': 'true'
}
}
return args
}]
}))
}
(some custom stuff going on in there but you get the gist)
I'm not sure what will happen if the inputs change though, I feel like that null resource replacement has to have some sort of ramification somewhere. I think patchForce might be needed on all resources too so maybe just a single deploy with the env var rather than transforming the annotations would be better, not sure yetmodern-spring-15520
11/07/2025, 6:45 PMlate-airplane-27955
11/10/2025, 2:09 PMv3.Release resource? I'm pretty sure pulumi just does "helm uninstall" under the hood, and Helm generally does not clean up its crdslate-balloon-24601
11/10/2025, 2:12 PM