From a24e405a9b28b4f5289ab3f8e33c2ff7ef720e0f Mon Sep 17 00:00:00 2001 From: Dominik Lekse Date: Fri, 30 Apr 2021 18:53:42 +0200 Subject: [PATCH] New data source `helm_template` to render chart templates locally (v3) (#483) --- helm/data_template.go | 576 ++++++++++++++++++++++++++ helm/data_template_test.go | 103 +++++ helm/provider.go | 3 + website/docs/d/template.html.markdown | 165 ++++++++ website/docs/index.html.markdown | 4 + website/docs/r/release.html.markdown | 2 +- website/helm.erb | 3 + 7 files changed, 855 insertions(+), 1 deletion(-) create mode 100644 helm/data_template.go create mode 100644 helm/data_template_test.go create mode 100644 website/docs/d/template.html.markdown diff --git a/helm/data_template.go b/helm/data_template.go new file mode 100644 index 0000000000..5d0056f8d8 --- /dev/null +++ b/helm/data_template.go @@ -0,0 +1,576 @@ +package helm + +import ( + "bytes" + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/chartutil" + "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v3/pkg/releaseutil" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + "time" +) + +// defaultTemplateAttributes template attribute values +var defaultTemplateAttributes = map[string]interface{}{ + "validate": false, + "include_crds": false, + "is_upgrade": false, + "skip_tests": false, +} + +func dataTemplate() *schema.Resource { + return &schema.Resource{ + ReadContext: dataTemplateRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Release name.", + }, + "repository": { + Type: schema.TypeString, + Optional: true, + Description: "Repository where to locate the requested chart. If is a URL the chart is installed without installing the repository.", + }, + "repository_key_file": { + Type: schema.TypeString, + Optional: true, + Description: "The repositories cert key file", + }, + "repository_cert_file": { + Type: schema.TypeString, + Optional: true, + Description: "The repositories cert file", + }, + "repository_ca_file": { + Type: schema.TypeString, + Optional: true, + Description: "The Repositories CA File", + }, + "repository_username": { + Type: schema.TypeString, + Optional: true, + Description: "Username for HTTP basic authentication", + }, + "repository_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + Description: "Password for HTTP basic authentication", + }, + "chart": { + Type: schema.TypeString, + Required: true, + Description: "Chart name to be installed. A path may be used.", + }, + "version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Specify the exact chart version to install. If this is not specified, the latest version is installed.", + }, + "devel": { + Type: schema.TypeBool, + Optional: true, + Description: "Use chart development versions, too. Equivalent to version '>0.0.0-0'. If `version` is set, this is ignored", + // Suppress changes of this attribute if `version` is set + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Get("version").(string) != "" + }, + }, + "values": { + Type: schema.TypeList, + Optional: true, + Description: "List of values in raw yaml format to pass to helm.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "set": { + Type: schema.TypeSet, + Optional: true, + Description: "Custom values to be merged with the values.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + // TODO: use ValidateDiagFunc once an SDK v2 version of StringInSlice exists. + // https://github.com/hashicorp/terraform-plugin-sdk/issues/534 + ValidateFunc: validation.StringInSlice([]string{ + "auto", "string", + }, false), + }, + }, + }, + }, + "set_sensitive": { + Type: schema.TypeSet, + Optional: true, + Description: "Custom sensitive values to be merged with the values.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "auto", "string", + }, false), + }, + }, + }, + }, + "set_string": { + Type: schema.TypeSet, + Optional: true, + Description: "Custom string values to be merged with the values.", + Deprecated: "This argument is deprecated and will be removed in the next major" + + " version. Use `set` argument with `type` equals to `string`", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "namespace": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Namespace to install the release into.", + DefaultFunc: schema.EnvDefaultFunc("HELM_NAMESPACE", "default"), + }, + "verify": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["verify"], + Description: "Verify the package before installing it.", + }, + "keyring": { + Type: schema.TypeString, + Optional: true, + Default: os.ExpandEnv("$HOME/.gnupg/pubring.gpg"), + Description: "Location of public keys used for verification. Used only if `verify` is true", + // Suppress changes of this attribute if `verify` is false + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return !d.Get("verify").(bool) + }, + }, + "timeout": { + Type: schema.TypeInt, + Optional: true, + Default: defaultAttributes["timeout"], + Description: "Time in seconds to wait for any individual kubernetes operation.", + }, + "disable_webhooks": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["disable_webhooks"], + Description: "Prevent hooks from running.", + }, + "reuse_values": { + Type: schema.TypeBool, + Optional: true, + Description: "When upgrading, reuse the last release's values and merge in any overrides. If 'reset_values' is specified, this is ignored", + Default: defaultAttributes["reuse_values"], + }, + "reset_values": { + Type: schema.TypeBool, + Optional: true, + Description: "When upgrading, reset the values to the ones built into the chart", + Default: defaultAttributes["reset_values"], + }, + "atomic": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["atomic"], + Description: "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used", + }, + "skip_crds": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["skip_crds"], + Description: "If set, no CRDs will be installed. By default, CRDs are installed if not already present", + }, + "skip_tests": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["skip_tests"], + Description: "If set, tests will not be rendered. By default, tests are rendered", + }, + "render_subchart_notes": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["render_subchart_notes"], + Description: "If set, render subchart notes along with the parent", + }, + "disable_openapi_validation": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["disable_openapi_validation"], + Description: "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema", + }, + "wait": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["wait"], + Description: "Will wait until all resources are in a ready state before marking the release as successful.", + }, + "dependency_update": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["dependency_update"], + Description: "Run helm dependency update before installing the chart", + }, + "replace": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["replace"], + Description: "Re-use the given name, even if that name is already used. This is unsafe in production", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Add a custom description", + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return new == "" + }, + }, + "create_namespace": { + Type: schema.TypeBool, + Optional: true, + Default: defaultAttributes["create_namespace"], + Description: "Create the namespace if it does not exist", + }, + "postrender": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Description: "Postrender command configuration.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "binary_path": { + Type: schema.TypeString, + Required: true, + Description: "The command binary path.", + }, + }, + }, + }, + "api_versions": { + Type: schema.TypeList, + Optional: true, + Description: "Kubernetes api versions used for Capabilities.APIVersions", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "include_crds": { + Type: schema.TypeBool, + Optional: true, + Default: defaultTemplateAttributes["include_crds"], + Description: "Include CRDs in the templated output", + }, + "is_upgrade": { + Type: schema.TypeBool, + Optional: true, + Default: defaultTemplateAttributes["is_upgrade"], + Description: "Set .Release.IsUpgrade instead of .Release.IsInstall", + }, + "show_only": { + Type: schema.TypeList, + Optional: true, + Description: "Only show manifests rendered from the given templates", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "validate": { + Type: schema.TypeBool, + Optional: true, + Default: defaultTemplateAttributes["validate"], + Description: "Validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install", + }, + "manifests": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Description: "Map of rendered chart templates indexed by the template name.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "manifest": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Concatenated rendered chart templates. This corresponds to the output of the `helm template` command.", + }, + "notes": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Rendered notes if the chart contains a `NOTES.txt`.", + }, + }, + } +} + +func dataTemplateRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + logID := fmt.Sprintf("[dataTemplateRead: %s]", d.Get("name").(string)) + debug("%s Started", logID) + + m := meta.(*Meta) + + name := d.Get("name").(string) + n := d.Get("namespace").(string) + + var apiVersions []string + + if apiVersionsAttr, ok := d.GetOk("api_versions"); ok { + apiVersionsValues := apiVersionsAttr.([]interface{}) + + for _, apiVersion := range apiVersionsValues { + apiVersions = append(apiVersions, apiVersion.(string)) + } + } + + var showFiles []string + + if showOnlyAttr, ok := d.GetOk("show_only"); ok { + showOnlyAttrValue := showOnlyAttr.([]interface{}) + + for _, showFile := range showOnlyAttrValue { + showFiles = append(showFiles, showFile.(string)) + } + } + + debug("%s Getting Config", logID) + + actionConfig, err := m.GetHelmConfiguration(n) + if err != nil { + return diag.FromErr(err) + } + + cpo, chartName, err := chartPathOptions(d, m) + if err != nil { + return diag.FromErr(err) + } + + debug("%s Getting chart", logID) + c, path, err := getChart(d, m, chartName, cpo) + if err != nil { + return diag.FromErr(err) + } + + // check and update the chart's dependencies if needed + updated, err := checkChartDependencies(d, c, path, m) + if err != nil { + return diag.FromErr(err) + } else if updated { + // load the chart again if its dependencies have been updated + c, err = loader.Load(path) + if err != nil { + return diag.FromErr(err) + } + } + + debug("%s Preparing for installation", logID) + + values, err := getValues(d) + if err != nil { + return diag.FromErr(err) + } + + err = isChartInstallable(c) + if err != nil { + return diag.FromErr(err) + } + + client := action.NewInstall(actionConfig) + client.ChartPathOptions = *cpo + client.ClientOnly = false + client.DryRun = true + client.DisableHooks = d.Get("disable_webhooks").(bool) + client.Wait = d.Get("wait").(bool) + client.Devel = d.Get("devel").(bool) + client.DependencyUpdate = d.Get("dependency_update").(bool) + client.Timeout = time.Duration(d.Get("timeout").(int)) * time.Second + client.Namespace = d.Get("namespace").(string) + client.ReleaseName = d.Get("name").(string) + client.GenerateName = false + client.NameTemplate = "" + client.OutputDir = "" + client.Atomic = d.Get("atomic").(bool) + client.SkipCRDs = d.Get("skip_crds").(bool) + client.SubNotes = d.Get("render_subchart_notes").(bool) + client.DisableOpenAPIValidation = d.Get("disable_openapi_validation").(bool) + client.Replace = d.Get("replace").(bool) + client.Description = d.Get("description").(string) + client.CreateNamespace = d.Get("create_namespace").(bool) + + // The following source has been adapted from the source of the helm template command + // https://github.com/helm/helm/blob/v3.5.3/cmd/helm/template.go#L67 + client.DryRun = true + // NOTE Do not set fixed release name as client.ReleaseName like in helm template command + client.Replace = true // Skip the name check + client.ClientOnly = !d.Get("validate").(bool) + client.APIVersions = chartutil.VersionSet(apiVersions) + client.IncludeCRDs = d.Get("include_crds").(bool) + + skipTests := d.Get("skip_tests").(bool) + + debug("%s Rendering Chart", logID) + + rel, err := client.Run(c, values) + + if err != nil { + return diag.FromErr(err) + } + + var manifests bytes.Buffer + + fmt.Fprintln(&manifests, strings.TrimSpace(rel.Manifest)) + + if !client.DisableHooks { + for _, m := range rel.Hooks { + if skipTests && isTestHook(m) { + continue + } + + fmt.Fprintf(&manifests, "---\n# Source: %s\n%s\n", m.Path, m.Manifest) + } + } + + // Difference to the implementation of helm template in newTemplateCmd: + // Independent of templates, names of the charts templates are always resolved from the manifests + // to be able to populate the keys in the manifests computed attribute. + var manifestsToRender []string + + splitManifests := releaseutil.SplitManifests(manifests.String()) + manifestsKeys := make([]string, 0, len(splitManifests)) + for k := range splitManifests { + manifestsKeys = append(manifestsKeys, k) + } + sort.Sort(releaseutil.BySplitManifestsOrder(manifestsKeys)) + + // Mapping of manifest key to manifest template name + manifestNamesByKey := make(map[string]string, len(manifestsKeys)) + + manifestNameRegex := regexp.MustCompile("# Source: [^/]+/(.+)") + + for _, manifestKey := range manifestsKeys { + manifest := splitManifests[manifestKey] + submatch := manifestNameRegex.FindStringSubmatch(manifest) + if len(submatch) == 0 { + continue + } + manifestName := submatch[1] + manifestNamesByKey[manifestKey] = manifestName + } + + // if we have a list of files to render, then check that each of the + // provided files exists in the chart. + if len(showFiles) > 0 { + for _, f := range showFiles { + missing := true + // Use linux-style filepath separators to unify user's input path + f = filepath.ToSlash(f) + for manifestKey, manifestName := range manifestNamesByKey { + // manifest.Name is rendered using linux-style filepath separators on Windows as + // well as macOS/linux. + manifestPathSplit := strings.Split(manifestName, "/") + // manifest.Path is connected using linux-style filepath separators on Windows as + // well as macOS/linux + manifestPath := strings.Join(manifestPathSplit, "/") + + // if the filepath provided matches a manifest path in the + // chart, render that manifest + if matched, _ := filepath.Match(f, manifestPath); !matched { + continue + } + manifestsToRender = append(manifestsToRender, manifestKey) + missing = false + } + + if missing { + return diag.Errorf("could not find template %q in chart", f) + } + } + } else { + manifestsToRender = manifestsKeys + } + + // Map from rendered manifests to data source output + computedManifests := make(map[string]string, 0) + computedManifest := &strings.Builder{} + + for _, manifestKey := range manifestsToRender { + manifest := splitManifests[manifestKey] + manifestName := manifestNamesByKey[manifestKey] + + // Manifests + computedManifests[manifestName] = manifest + + // Manifest bundle + fmt.Fprintf(computedManifest, "---\n%s\n", manifest) + } + + computedNotes := rel.Info.Notes + + d.SetId(name) + + err = d.Set("manifests", computedManifests) + if err != nil { + return diag.FromErr(err) + } + + err = d.Set("manifest", computedManifest.String()) + if err != nil { + return diag.FromErr(err) + } + + err = d.Set("notes", computedNotes) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func isTestHook(h *release.Hook) bool { + for _, e := range h.Events { + if e == release.HookTest { + return true + } + } + return false +} diff --git a/helm/data_template_test.go b/helm/data_template_test.go new file mode 100644 index 0000000000..48b0c462cc --- /dev/null +++ b/helm/data_template_test.go @@ -0,0 +1,103 @@ +package helm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataTemplate_basic(t *testing.T) { + name := randName("basic") + namespace := randName(testNamespacePrefix) + + datasourceAddress := fmt.Sprintf("data.helm_template.%s", testResourceName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{{ + Config: testAccDataHelmTemplateConfigBasic(testResourceName, namespace, name, "1.2.3"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(datasourceAddress, "manifests.%", "4"), + resource.TestCheckResourceAttrSet(datasourceAddress, "manifests.templates/deployment.yaml"), + resource.TestCheckResourceAttrSet(datasourceAddress, "manifests.templates/service.yaml"), + resource.TestCheckResourceAttrSet(datasourceAddress, "manifests.templates/serviceaccount.yaml"), + resource.TestCheckResourceAttrSet(datasourceAddress, "manifests.templates/tests/test-connection.yaml"), + resource.TestCheckResourceAttrSet(datasourceAddress, "manifest"), + resource.TestCheckResourceAttrSet(datasourceAddress, "notes"), + ), + }}, + }) +} + +func TestAccDataTemplate_templates(t *testing.T) { + name := randName("basic") + namespace := randName(testNamespacePrefix) + + datasourceAddress := fmt.Sprintf("data.helm_template.%s", testResourceName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{{ + Config: testAccDataHelmTemplateConfigTemplates(testResourceName, namespace, name, "1.2.3"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(datasourceAddress, "manifests.%", "1"), + resource.TestCheckResourceAttrSet(datasourceAddress, "manifests.templates/deployment.yaml"), + resource.TestCheckResourceAttrSet(datasourceAddress, "manifest"), + resource.TestCheckResourceAttrSet(datasourceAddress, "notes"), + ), + }}, + }) +} + +func testAccDataHelmTemplateConfigBasic(resource, ns, name, version string) string { + return fmt.Sprintf(` + data "helm_template" "%s" { + name = %q + namespace = %q + description = "Test" + repository = %q + chart = "test-chart" + version = %q + + set { + name = "foo" + value = "bar" + } + + set { + name = "fizz" + value = 1337 + } + } + `, resource, name, ns, testRepositoryURL, version) +} + +func testAccDataHelmTemplateConfigTemplates(resource, ns, name, version string) string { + return fmt.Sprintf(` + data "helm_template" "%s" { + name = %q + namespace = %q + description = "Test" + repository = %q + chart = "test-chart" + version = %q + + set { + name = "foo" + value = "bar" + } + + set { + name = "fizz" + value = 1337 + } + + show_only = [ + "templates/deployment.yaml", + ] + } + `, resource, name, ns, testRepositoryURL, version) +} diff --git a/helm/provider.go b/helm/provider.go index eb8c8fa3fb..73fcd78d43 100644 --- a/helm/provider.go +++ b/helm/provider.go @@ -134,6 +134,9 @@ func Provider() *schema.Provider { ResourcesMap: map[string]*schema.Resource{ "helm_release": resourceRelease(), }, + DataSourcesMap: map[string]*schema.Resource{ + "helm_template": dataTemplate(), + }, } p.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { return providerConfigure(d, p.TerraformVersion) diff --git a/website/docs/d/template.html.markdown b/website/docs/d/template.html.markdown new file mode 100644 index 0000000000..634a971b26 --- /dev/null +++ b/website/docs/d/template.html.markdown @@ -0,0 +1,165 @@ +--- +layout: "helm" +page_title: "helm: helm_template" +sidebar_current: "docs-helm-template" +description: |- + +--- + +# Data Source: helm_template + +Render chart templates locally. + +`helm_template` renders chart templates locally and exposes the rendered manifests in the data source attributes. `helm_template` mimics the functionality of the `helm template` command. + +The arguments aim to be identical to the `helm_release` resource. + +For further details on the `helm template` command, refer to the [Helm documentation](https://helm.sh/docs/helm/helm_template/). + +## Example Usage + +### Render all chart templates + +The following example renders all templates of the `mariadb` chart of the official Helm stable repository. Concatenated manifests are exposed as output variable `mariadb_instance_manifest_bundle`. + +```hcl +data "helm_template" "mariadb_instance" { + name = "mariadb-instance" + namespace = "default" + repository = "https://kubernetes-charts.storage.googleapis.com" + + chart = "mariadb" + version = "7.1.0" + + set { + name = "service.port" + value = "13306" + } + + set_sensitive { + name = "rootUser.password" + value = "s3cr3t!" + } +} + +resource "local_file" "mariadb_manifests" { + for_each = data.helm_template.mariadb_instance.manifests + + filename = "./${each.key}" + content = each.value +} + +output "mariadb_instance_manifest_bundle" { + value = data.helm_template.mariadb_instance.manifest_bundle +} + +output "mariadb_instance_manifests" { + value = data.helm_template.mariadb_instance.manifests +} + +output "mariadb_instance_notes" { + value = data.helm_template.mariadb_instance.notes +} +``` + +### Render selected chart templates + +The following example renders only the templates `master-statefulset.yaml` and `master-svc.yaml` of the `mariadb` chart of the official Helm stable repository. + +```hcl +data "helm_template" "mariadb_instance" { + name = "mariadb-instance" + namespace = "default" + repository = "https://kubernetes-charts.storage.googleapis.com" + + chart = "mariadb" + version = "7.1.0" + + templates = [ + "templates/master-statefulset.yaml", + "templates/master-svc.yaml", + ] + + set { + name = "service.port" + value = "13306" + } + + set_sensitive { + name = "rootUser.password" + value = "s3cr3t!" + } +} + +resource "local_file" "mariadb_manifests" { + for_each = data.helm_template.mariadb_instance.manifests + + filename = "./${each.key}" + content = each.value +} + +output "mariadb_instance_manifest_bundle" { + value = data.helm_template.mariadb_instance.manifest_bundle +} + +output "mariadb_instance_manifests" { + value = data.helm_template.mariadb_instance.manifests +} + +output "mariadb_instance_notes" { + value = data.helm_template.mariadb_instance.notes +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Release name. +* `chart` - (Required) Chart name to be rendered. The chart name can be local path, a URL to a chart, or the name of the chart if `repository` is specified. It is also possible to use the `/` format here if you are running Terraform on a system that the repository has been added to with `helm repo add` but this is not recommended. +* `repository` - (Optional) Repository URL where to locate the requested chart. +* `repository_key_file` - (Optional) The repositories cert key file +* `repository_cert_file` - (Optional) The repositories cert file +* `repository_ca_file` - (Optional) The Repositories CA File. +* `repository_username` - (Optional) Username for HTTP basic authentication against the repository. +* `repository_password` - (Optional) Password for HTTP basic authentication against the repository. +* `devel` - (Optional) Use chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored. +* `version` - (Optional) Specify the exact chart version to install. If this is not specified, the latest version is installed. +* `namespace` - (Optional) The namespace to install the release into. Defaults to `default`. +* `verify` - (Optional) Verify the package before installing it. Helm uses a provenance file to verify the integrity of the chart; this must be hosted alongside the chart. For more information see the [Helm Documentation](https://helm.sh/docs/topics/provenance/). Defaults to `false`. +* `keyring` - (Optional) Location of public keys used for verification. Used only if `verify` is true. Defaults to `/.gnupg/pubring.gpg` in the location set by `home` +* `timeout` - (Optional) Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks). Defaults to `300` seconds. +* `disable_webhooks` - (Optional) Prevent hooks from running. Defaults to `false`. +* `reuse_values` - (Optional) When upgrading, reuse the last release's values and merge in any overrides. If 'reset_values' is specified, this is ignored. Defaults to `false`. +* `reset_values` - (Optional) When upgrading, reset the values to the ones built into the chart. Defaults to `false`. +* `atomic` - (Optional) If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`. +* `skip_crds` - (Optional) If set, no CRDs will be installed. By default, CRDs are installed if not already present. Defaults to `false`. +* `skip_tests` - (Optional) If set, tests will not be rendered. By default, tests are rendered. Defaults to `false`. +* `render_subchart_notes` - (Optional) If set, render subchart notes along with the parent. Defaults to `true`. +* `disable_openapi_validation` - (Optional) If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema. Defaults to `false`. +* `wait` - (Optional) Will wait until all resources are in a ready state before marking the release as successful. It will wait for as long as `timeout`. Defaults to `true`. +* `values` - (Optional) List of values in raw yaml to pass to helm. Values will be merged, in order, as Helm does with multiple `-f` options. +* `set` - (Optional) Value block with custom values to be merged with the values yaml. +* `set_sensitive` - (Optional) Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff. +* `set_string` - (Optional) Value block with custom STRING values to be merged with the values yaml. +* `dependency_update` - (Optional) Runs helm dependency update before installing the chart. Defaults to `false`. +* `replace` - (Optional) Re-use the given name, even if that name is already used. This is unsafe in production. Defaults to `false`. +* `description` - (Optional) Set release description attribute (visible in the history). +* `postrender` - (Optional) Configure a command to run after helm renders the manifest which can alter the manifest contents. +* `create_namespace` - (Optional) Create the namespace if it does not yet exist. Defaults to `false`. + +The following attributes are specific to the `helm_template` data source and not available in the `helm_release` resource: + +* `api_versions` - (Optional) List of Kubernetes api versions used for Capabilities.APIVersions. +* `include_crds` - (Optional) Include CRDs in the templated output. Defaults to `false`. +* `is_upgrade` - (Optional) Set .Release.IsUpgrade instead of .Release.IsInstall. Defaults to `false`. +* `show_only` - (Optional) Explicit list of chart templates to render, as Helm does with the `-s` or `--show-only` option. Paths to chart templates are relative to the root folder of the chart, e.g. `templates/deployment.yaml`. If not provided, all templates of the chart are rendered. +* `validate` - (Optional) Validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install. Defaults to `false`. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `manifests` - Map of rendered chart templates indexed by the template name. +* `manifest` - Concatenated rendered chart templates. This corresponds to the output of the `helm template` command. +* `notes` - Rendered notes if the chart contains a `NOTES.txt`. diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index fb41218469..58d09a9fb9 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -16,6 +16,10 @@ Try the [hands-on tutorial](https://learn.hashicorp.com/tutorials/terraform/helm * [Resource: helm_release](r/release.html) +## Data Sources + +* [Data Source: helm_template](d/template.html) + ## Example Usage ```hcl diff --git a/website/docs/r/release.html.markdown b/website/docs/r/release.html.markdown index de6098b138..ecbd19d1a8 100644 --- a/website/docs/r/release.html.markdown +++ b/website/docs/r/release.html.markdown @@ -99,7 +99,7 @@ The following arguments are supported: * `verify` - (Optional) Verify the package before installing it. Helm uses a provenance file to verify the integrity of the chart; this must be hosted alongside the chart. For more information see the [Helm Documentation](https://helm.sh/docs/topics/provenance/). Defaults to `false`. * `keyring` - (Optional) Location of public keys used for verification. Used only if `verify` is true. Defaults to `/.gnupg/pubring.gpg` in the location set by `home` * `timeout` - (Optional) Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks). Defaults to `300` seconds. -* `disable_webhooks` - (Optional) Prevent hooks from running. Defauts to `false` +* `disable_webhooks` - (Optional) Prevent hooks from running. Defaults to `false`. * `reuse_values` - (Optional) When upgrading, reuse the last release's values and merge in any overrides. If 'reset_values' is specified, this is ignored. Defaults to `false`. * `reset_values` - (Optional) When upgrading, reset the values to the ones built into the chart. Defaults to `false`. * `force_update` - (Optional) Force resource update through delete/recreate if needed. Defaults to `false`. diff --git a/website/helm.erb b/website/helm.erb index d65532ebc2..3ce9b2ac04 100644 --- a/website/helm.erb +++ b/website/helm.erb @@ -22,6 +22,9 @@ > helm_release + > + helm_template +