terraform-provider-terrahelm

command module
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2024 License: MIT Imports: 2 Imported by: 0

README

TerraHelm Provider

TerraHelm is a third-party Terraform provider that simplifies managing Helm releases using Helm CLI.

This provider is designed for teams looking to integrate Helm deployments seamlessly into their Terraform infrastructure, particularly those considering a transition to GitOps in the future. The HashiCorp Helm provider, though robust in managing basic Helm releases, will encounter limitations with complex Helm orchestration tasks due to several key reasons:

  • Limited Customization and Configuration Flexibility: The HashiCorp Helm provider primarily focuses on deploying Helm charts from repositories and configuring them using Terraform-defined variables. However, in complex deployments, users often need more nuanced control over the deployment process, such as conditional deployments, complex dependencies between charts, or advanced error handling strategies which can be better handled through direct interaction with the Helm CLI.
  • Restricted Access to Helm CLI Features: The HashiCorp provider encapsulates Helm functionality, exposing only a subset of the Helm CLI’s capabilities through Terraform.
  • Debugging and Troubleshooting: Helm deployments can sometimes fail due to issues such as template rendering errors, chart dependencies, or configuration mismatches. While the HashiCorp Helm provider does provide error logs, troubleshooting complex issues might require deeper insights into the Helm operations, such as step-by-step execution logs or interactive debugging sessions, which are more directly accessible through the Helm CLI itself.
  • Version Management: Complex environments might require specific versions of Helm for different applications or different parts of the same application due to already established GitOps integrations, legacy code, or security requirements.
  • Performance Challenges with Large Deployments: The Helm provider can slow down when deploying large charts or multiple Helm charts due to slow Terraform’s state management logic. TerraHelm mitigates this by using the Helm CLI directly, reducing Terraform state bloat and enhancing performance.
  • Integration with External Systems: In complex orchestration tasks, Helm charts might need to interact more extensively with external systems for fetching configuration data or managing secrets, for example. The direct use of Helm CLI allows for custom scripts and hooks that can dynamically interact with these systems during the deployment process, offering a level of customization that the HashiCorp provider might not support natively (see example below).

TerraHelm fills this gap by directly integrating the Helm CLI into the Terraform environment, boosting both the efficiency and simplicity of managing Helm-related tasks and providing powerful capabilties, like downloads of both charts and values independently from various sources like Git, Mercurial, HTTP, Amazon S3, Google GCP, etc.

Features

  • Helm CLI Integration: Seamlessly integrates Helm CLI into Terraform, enabling full access to Helm CLI functionalities for improved debugging and operational flexibility.
  • Binary Management: Automatically handles the downloading and installation of the specified Helm binary into a cache_dir directory (.terraform/terrahelm_cache/ by default). This feature supports effortless version management and switching between different Helm versions.
  • Flexible Sources: Supports fetching Helm charts and value files from a variety of sources including Git, Mercurial, HTTP, Amazon S3, and Google Cloud Storage. This flexibility ensures easy integration of custom and third-party Helm charts into your Terraform configuration.
  • Enhanced Debugging: Provides the capability to execute Helm CLI commands directly, mirroring the operations performed by the provider. This aids in debugging by allowing users to replicate and diagnose issues within the deployment process.

Documentation

Installation

To install the TerraHelm Provider, include a provider requirements section in your Terraform code for automatic installation and management:

terraform {
  required_providers {
    terrahelm = {
      source  = "mikhae1/terrahelm"
    }
  }
}
Manual binary installation
  1. Download the appropriate binary for your platform from the Releases page.
  2. Unzip the downloaded binary and move it to the Terraform plugins directory (e.g., ~/.terraform.d/plugins/github.com/mikhae1/terrahelm/1.0.0/linux_amd64/).
Build binary from Source

To build and install the terraform-provider-terrahelm provider from source, ensure you have Go binary installed and run the following command:

$ make install

Usage

TerraHelm manages Helm releases through the terrahelm_release resource and data source, representing a Helm release installed on a Kubernetes cluster.

Provider configuration
provider "terrahelm" {
  helm_version = "v3.9.4"
  kube_context = "kind"
}
Chart Repository release
resource "terrahelm_release" "mysql" {
  name             = "mysql"
  chart_repository = "bitnami"
  chart_path       = "mysql"

  values = data.template_file.values.rendered
}

data "template_file" "values" {
  template = file("values.yaml")
  vars = {
    username = var.username
    password = var.password
  }
}
Local chart
resource "terrahelm_release" "local_chart" {
  name             = "local-chart"
  chart_repository = "/path/to/charts"
  chart_path       = "my-chart"
}
Git Repository release
resource "terrahelm_release" "nginx" {
  name             = "nginx"
  git_repository   = "https://github.com/bitnami/charts.git"
  git_reference    = "main"
  chart_path       = "bitnami/nginx"
  namespace        = "nginx"
  create_namespace = true

  values = <<EOF
  replicaCount: 1
  EOF
}
Chart Url release

The chart_url parameter allows fetching charts from various sources, providing much more flexibility compared to git_repository.

resource "terrahelm_release" "nginx" {
  name       = "nginx"
  namespace  = "nginx"

  # fetch chart from variety of protocols: http::, file::, s3::, gcs::, hg::
  chart_url  = "github.com/mikhae1/terraform-provider-terrahelm//tests/charts/?ref=master&depth=1"
  chart_path = "./nginx"

  values_files = [
    "./values/nginx/common.yaml", # relative to chart directory
    "https://raw.githubusercontent.com/mikhae1/terraform-provider-terrahelm/master/tests/charts/values/nginx/dev-values.yaml",
  ]
}
General parameters
  • archive - The archive format to use to unarchive this file, or "" (empty string) to disable unarchiving
  • checksum - Checksum to verify the downloaded file or archive (./chart.tgz?checksum=md5:12345678, ./chart.tgz?checksum=file:./chart.tgz.sha256sum)
  • filename - When in file download mode, allows specifying the name of the downloaded file on disk. Has no effect in directory mode.

Here are examples covering different protocols and key features:

Local files
resource "terrahelm_release" "local_chart" {
  name      = "local-chart"
  chart_url = "file::path/to/local/chart.tgz"
}
Git
resource "terrahelm_release" "git_chart" {
  name      = "git-chart"
  chart_url = "github.com/kubernetes/ingress-nginx//charts/ingress-nginx?ref=helm-chart-4.8.3&depth=1"
}
resource "terrahelm_release" "git_chart" {
  name      = "git-chart"
  chart_url = "git::git@github.com:bitnami/charts.git//bitnami/nginx?depth=1"
}
Supported parameters
  • ref - The Git ref to checkout. This is a ref, so it can point to a commit SHA, a branch name, etc.
  • sshkey - An SSH private key to use during clones. The provided key must be a base64-encoded string. For example, to generate a suitable sshkey from a private key file on disk, you would run base64 -w0 .
  • depth - The Git clone depth. The provided number specifies the last n revisions to clone from the repository.
Mercurial
resource "terrahelm_release" "hg_chart" {
  name      = "hg-chart"
  chart_url = "hg::https://example.com/hg/repo//chart?rev=123"
}
HTTP
resource "terrahelm_release" "http_chart" {
  name      = "http-chart"
  chart_url = "https://charts.bitnami.com/bitnami/nginx-15.12.2.tgz//nginx"
}

To use HTTP basic authentication, prepend username:password@ to the hostname.

Amazon S3
resource "terrahelm_release" "s3_chart" {
  name      = "s3-chart"
  chart_url = "s3::https://s3.amazonaws.com/bucket/chart.tgz"
}
resource "terrahelm_release" "s3_chart" {
  name      = "s3-chart"
  chart_url = "bucket.s3-eu-west-1.amazonaws.com/bucket/chart"
}
Supported parameters
  • aws_access_key_id - AWS access key.
  • aws_access_key_secret - AWS access key secret.
  • aws_access_token - AWS access token if this is being used.
  • aws_profile - Use this profile from local ~/.aws/ config. Takes priority over key and token.
  • region - AWS regions to use.

Note: it will also read these from standard AWS environment variables if they're set.

Google GCP
resource "terrahelm_release" "gcp_chart" {
  name      = "gcp-chart"
  chart_url = "www.googleapis.com/storage/v1/bucket/chart"
}
resource "terrahelm_release" "gcp_chart" {
  name      = "gcp-chart"
  chart_url = "gcs::https://www.googleapis.com/storage/v1/bucket/chart.zip"
}
Data Source
data "terrahelm_release" "nginx" {
  name      = "nginx"
  namespace = "nginx"
}

Using Values and Values Files

Overview

When deploying Helm charts with this Terraform provider, you have the flexibility to customize the values passed to the Helm chart using either a values string (values) or values files (values_files). When both values and values_files are provided, the values from values take precedence over the values from the files. This means that you can override specific values from files by providing them directly in the values parameter.

This section provides examples and explanations of how to use these parameters effectively.

Values (string)

The values parameter allows you to directly specify the values for the Helm chart in a YAML format as a string. This is useful when the values are relatively simple and can be easily represented inline:

resource "helm_release" "example" {
  name           = "my-chart"
  chart_version  = "1.2.3"
  values         = <<EOF
  replicaCount: 3
  image:
    repository: nginx
    tag: "1.19.7"
  ingress:
    enabled: true
    hosts:
      - host: example.com
        paths: ["/"]
  EOF
}
Values Files

The values_files parameter allows you to specify one or more YAML files containing values for the Helm chart, whether they are local files, URLs, or files relative to the chart repository. This approach offers a powerful way to store values files outside Terraform in a GitOps compatible manner, enabling the use of separate repositories for the chart and value files. Notably, values_files supports most of the parameters from chart_url, allowing leverage diverse storage solutions for each individual file.

resource "helm_release" "example" {
  name           = "my-chart"
  chart_url      = "github.com/bitnami/charts//bitnami/nginx?depth=1"
  values_files   = [
    "https://example.com/values/common-values.yaml", // Http URL to values file
    "git::https://github.com/org/gitops//values/prod-values.yaml", // Git repository URL to values file
    "s3::https://s3.amazonaws.com/bucket/prod/ingress-values.yaml" // S3 bucket URI to values file
  ]
}

Values files will be added to Helm CLI in the order of appearance, and the values from the latest files will override the values from the first ones.

Files starting with . are treated as relative to the chart repository itself:

resource "terrahelm_release" "chart_values_files" {
  name             = "nginx-values"
  chart_url        = "github.com/mikhae1/terraform-provider-terrahelm//tests/charts/?ref=master&depth=1"
  chart_path       = "./nginx"

  values_files = [
    "./values/nginx/common.yaml",
    "./values/nginx/dev-values.yaml",
  ]
}

So the charts directory will be downloaded first and charts/values/nginx/common.yaml, charts/values/nginx/dev-values.yaml will be passed to the Helm CLI.

Post-Renderer Configuration

Helm provides support for post-renderers, which allow you to modify the Kubernetes manifests generated by Helm before they are deployed to your cluster. This can be useful for tasks such as:

  • Injecting additional configuration or secrets.
  • Integrating with kustomize or any external systems or tools.
  • Performing custom validation or transformation of the manifests.
Using Post-Renderers

To configure a post-renderer for a Helm release, you can use the post_renderer and post_renderer_url arguments in the terrahelm_release resource:

resource "terrahelm_release" "example" {
  # ... other configuration ...

  # Use existing my-post-renderer binary
  post_renderer = "/path/to/my-post-renderer arg1 arg2"

  # Alternatively, you can specify a URL to download the script
  post_renderer_url = "https://example.com/path/to/my-post-renderer.sh"
}
post_renderer
  • This argument specifies the command to run as the post-renderer. The command should accept the rendered Kubernetes manifests on standard input and output the modified manifests on standard output.
  • You can also provide additional arguments to the post-renderer command by separating them with spaces.
post_renderer_url
  • This argument allows you to specify a URL from where the post-renderer script will be downloaded, same features supported chat.
  • TerraHelm will automatically download the script and make it executable.
  • If you only specify post_renderer_url without post_renderer, the downloaded script will be used as the post-renderer command.
Safely using secrets with TerraHelm

secfetch allows replace secrets in Helm charts and values using the following placeholder syntax: {prefix}//{secret-path}//{target-key}. It supports AWS SSM, AWS Secrets Manager, Environment variables and others.

Here is how you can use it to replace secrets from values:

resource "terrahelm_release" "postrender" {
  name              = "nginx"
  chart_url         = "github.com/mikhae1/terraform-provider-terrahelm//tests/charts/?ref=master&depth=1"
  post_renderer_url = "https://github.com/mikhae1/secfetch/releases/latest/download/secfetch-darwin-amd64.zip"
  chart_path        = "nginx"
  namespace         = "postrender"
  create_namespace  = true
  timeout           = 60
  atomic            = true
  debug             = true

  values_files = [
    "https://raw.githubusercontent.com/mikhae1/terraform-provider-terrahelm/master/tests/charts/values/nginx/common.yaml",
  ]

  # values will be replaced by post renderer just before the deploy to Kubernetes
  values = <<EOF
  basicAuth:
    enabled: true
    username: "base64://YWRtMW4="       // will be replaced to: username: "adm1n"
    password: "base64://cGFzc3cwcmQ="   // will be: password: "passw0rd"
  EOF
}

More examples

Refer to the examples here.

Troubleshooting

If you encounter issues with Helm release, utilize the Helm CLI for debugging. Set the TF_LOG=INFO environment variable to view Helm commands in the provider's logs:

$ TF_LOG=INFO terraform apply
...
terrahelm_release.nginx: Still creating... [2m50s elapsed]
terrahelm_release.nginx: Still creating... [3m0s elapsed]2023-04-01T18:46:53.636+0300 [INFO]  provider.terraform-provider-terrahelm:

Running Helm command:
  .terraform/terrahelm_cache/helm/v3.7.1/helm install nginx .terraform/terrahelm_cache/repos/nginx-http-490743bd --kube-context my-cluster --namespace nginx --create-namespace --version 13.2.1 -f .terraform/terrahelm_cache/values/charts.git/main/nginx-f6749b77d453441e-values.yaml
...

You can now invoke helm commands directly from the command line using the same helm binary and values:

$ .terraform/terrahelm_cache/helm/v3.7.1/helm ...

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL