• Stars
    star
    115
  • Rank 305,916 (Top 7 %)
  • Language
    Go
  • Created almost 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Deploy Helmfile releases from Terraform

terraform-provider-helmfile

Deploy Helmfile releases from within Terraform.

Benefits:

  • Entry-point to your infrastructure and app deployments as a whole
  • Input terraform variables and outputs into Helmfile
  • Blue-green deployment of your whole stack with tf's create_before_destroy
  • AWS authentication and AssumeRole support

Prerequisites

  • Helmfile
    • v0.126.0 or greater is highly recommended due to #28

Installation

For Terraform 0.12:

Install the terraform-provider-helmfile binary under .terraform/plugins/${OS}_${ARCH}, so that the binary is at e.g. ${WORKSPACE}/.terraform/plugins/darwin_amd64/terraform-provider-helmfile.

For Terraform 0.13 and later:

The provider is available at Terraform Registry so you can just add the following to your tf file for installation:

terraform {
  required_providers {
    helmfile = {
      source = "mumoshu/helmfile"
      version = "VERSION"
    }
  }
}

Please replace VERSION with the version number of the provider without the v prefix, like 0.3.14.

Examples

There is nothing to configure for the provider, so you firstly declare the provider like:

provider "helmfile" {}

You can define a release in one of the four ways:

Inline helmfile_release

helmfile_release would be a natural choice for users who are familiar with Terraform. It just map each Terraform helmfile_release resource to a Helm release 1-by-1:

resource "helmfile_release" "myapp" {
	# `name` is the optional release name. When omitted, it's set to the ID of the resource, "myapp".
	# name = "myapp-${var.somevar}"
	namespace = "default"
	chart = "sp/podinfo"
	helm_binary = "helm3"

	working_directory = path.module
	values = [
		<<EOF
{ "image": {"tag": "3.14" } }
EOF
	]
}

External helmfile_release_set

External helmfile_release_set is the easiest way for existing Helmfile users.

Exsiting helmfile.yaml 1:1 mapping -

resource "helmfile_release_set" "mystack" {
    content = file("./helmfile.yaml")
}

Existing helmfile.d folder -

resource "helmfile_release_set" "mystack" {
	working_directory = "<directory_where_helmfile.d_exists>"
	kubeconfig        = pathexpand("<kube_config>")
	environment       = "prod"
	values = [
		<<EOF
{ "image": {"tag": "3.14" } }
EOF
	]
}

Inline helmfile_release_set

The inline variant of the release set allows you to render helmfile.yaml without Go template but with the Terraform syntax:

resource "helmfile_release_set" "mystack" {
    # Install and choose from one of installed versions of helm
    # By changing this, you can upgrade helm per release_set
    # Default: helm
    helm_binary = "helm-3.0.0"

    # Install and choose from one of installed versions of helmfile
    # By changing this, you can upgrade helmfile per release_set
    # Default: helmfile
    binary = "helmfile-v0.93.0"

    working_directory = path.module

    # Maximum number of concurrent helm processes to run, 0 is unlimited (0 is a default value)
    concurrency = 0

    # Helmfile environment name to deploy
    # Default: default
    environment = "prod"

    # Environment variables available to helmfile's requireEnv and commands being run by helmfile
    environment_variables = {
        FOO = "foo"
        KUBECONFIG = "path/to/your/kubeconfig"
    }
    
    # State values to be passed to Helmfile
    values = {
      # Corresponds to --state-values-set name=myapp
      name = "myapp"
    }
    
    # State values files to be passed to Helmfile
    values = [
      file("overrides.yaml"),
      file("another.yaml"),
    ]
    
    # Label key-value pairs to filter releases 
    selector = {
      # Corresponds to -l labelkey1=value1
      labelkey1 = "value1"
    }
}

output "mystack_diff" {
  value = helmfile_release_set.mystack.diff_output
}

output "mystack_apply" {
  value = helmfile_release_set.mystack.apply_output
}

In the example above I am changing my working_directory, setting some environment variables that will be utilized by all my helmfiles.

Stdout and stderr from Helmfile runs are available in the debug log files.

Running terraform plan runs helmfile diff.

It shows no changes if helmfile diff did not detect any changes:

helmfile_release_set.mystack: Refreshing state... [id=bnd30hkllhcvvgsrplo0]

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

terraform plan surfaces changes in the diff_output field if helmfile diff detected any changes:

helmfile_release_set.mystack: Refreshing state... [id=bnd30hkllhcvvgsrplo0]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # helmfile_release_set.mystack will be updated in-place
  ~ resource "helmfile_release_set" "mystack" {
        binary                = "helmfile"
      - diff_output           = "Comparing release=myapp-foo, chart=sp/podinfo\n\x1b[33mdefault, myapp-foo-podinfo, Deployment (apps) has changed:\x1b[0m\n  # Source: podinfo/templates/deployment.yaml\n  apiVersion: apps/v1\n  kind: Deployment\n  metadata:\n    name: myapp-foo-podinfo\n    labels:\n      app: podinfo\n      chart: podinfo-3.1.4\n      release: myapp-foo\n      heritage: Helm\n  spec:\n    replicas: 1\n    strategy:\n      type: RollingUpdate\n      rollingUpdate:\n        maxUnavailable: 1\n    selector:\n      matchLabels:\n        app: podinfo\n        release: myapp-foo\n    template:\n      metadata:\n        labels:\n          app: podinfo\n          release: myapp-foo\n        annotations:\n          prometheus.io/scrape: \"true\"\n          prometheus.io/port: \"9898\"\n      spec:\n        terminationGracePeriodSeconds: 30\n        containers:\n          - name: podinfo\n\x1b[31m-           image: \"stefanprodan/podinfo:foobar2aa\"\x1b[0m\n\x1b[32m+           image: \"stefanprodan/podinfo:foobar2a\"\x1b[0m\n            imagePullPolicy: IfNotPresent\n            command:\n              - ./podinfo\n              - --port=9898\n              - --port-metrics=9797\n              - --grpc-port=9999\n              - --grpc-service-name=podinfo\n              - --level=info\n              - --random-delay=false\n              - --random-error=false\n            env:\n            - name: PODINFO_UI_COLOR\n              value: cyan\n            ports:\n              - name: http\n                containerPort: 9898\n                protocol: TCP\n              - name: http-metrics\n                containerPort: 9797\n                protocol: TCP\n              - name: grpc\n                containerPort: 9999\n                protocol: TCP\n            livenessProbe:\n              exec:\n                command:\n                - podcli\n                - check\n                - http\n                - localhost:9898/healthz\n              initialDelaySeconds: 1\n              timeoutSeconds: 5\n            readinessProbe:\n              exec:\n                command:\n                - podcli\n                - check\n                - http\n                - localhost:9898/readyz\n              initialDelaySeconds: 1\n              timeoutSeconds: 5\n            volumeMounts:\n            - name: data\n              mountPath: /data\n            resources:\n              limits: null\n              requests:\n                cpu: 1m\n                memory: 16Mi\n        volumes:\n        - name: data\n          emptyDir: {}\n\nin ./helmfile.yaml: failed processing release myapp-foo: helm3 exited with status 2:\n  Error: identified at least one change, exiting with non-zero exit code (detailed-exitcode parameter enabled)\n  Error: plugin \"diff\" exited with error\n" -> null
      ~ dirty                 = true -> false
        environment           = "default"
        environment_variables = {
            "FOO" = "foo"
        }
        helm_binary           = "helm3"
        id                    = "bnd30hkllhcvvgsrplo0"
        path                  = "./helmfile.yaml"
        selector              = {
            "labelkey1" = "value1"
        }
        values                = {
            "name" = "myapp"
        }
        working_directory     = "."
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Running terraform apply runs helmfile apply to deploy your releases.

The computed field apply_output is used to surface the output from Helmfile. You can use in the string interpolation to produce a useful Terraform output.

In the example below, the output mystack_apply is generated from apply_output so that you can review what has actually changed on helmfile apply:

helmfile_release_set.mystack: Refreshing state... [id=bnd30hkllhcvvgsrplo0]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

mystack_apply = Comparing release=myapp-foo, chart=sp/podinfo
********************

	Release was not present in Helm.  Diff will show entire contents as new.

********************
...

mystack_diff = 

terraform apply just succeeds without any effect when there's no change detected by helmfile:

helmfile_release_set.mystack: Refreshing state... [id=bnd30hkllhcvvgsrplo0]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

mystack_apply =
mystack_diff =

Advanced Features

Declarative binary version management

terraform-provider-helmfile has a built-in package manager called shoal. With that, you can specify the following helmfile_release_set attributes to let the provider install the executable binaries on demand:

  • version for installing helmfile
  • helm_version for installing helm
  • helm_diff_version for installing helm-diff

version and helm_version uses the Go runtime and go-git so it should work without any dependency.

helm_diff_version requires helm plugin install to be runnable. The plugin installation process can vary depending on the plugin and its plugin.yaml.

With the below example, the provider installs helmfile v0.128.0, helm 3.2.1, and helm-diff 3.1.3, so that you don't need to install them beforehand. This should be handy when you're trying to use this provider on Terraform Cloud, whose runtime environment is not available for customization by the user.

helmfile_release_set "mystack" {
  version = "0.128.0"
  helm_version = "3.2.1"
  helm_diff_version = "v3.1.3"

  // snip

AWS authentication and AssumeRole support

Providing any combination of aws_region, aws_profile, and aws_assume_role, the provider obtains the following environment variables and provider it to any helmfile command.

  • aws_region attribute: AWS_DEFAULT_REGION
  • aws_profile attribute: AWS_PROFILE
  • aws_assume_role block: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN obtained by calling sts:AssumeRole
resource "helmfile_release_set" "mystack" {
  aws_region = var.region
  aws_profile = var.profile
  aws_assume_role {
    role_arn = "arn:aws:iam::${var.account_id}:role/${var.role_name}"
  }
  // snip

Those environment variables go from the provider to helmfile, helm, client-go, and finally the aws exec credentials provider that reads the environment variables to call aws eks get-token which internally calls sts:GetCallerIdentity(e.g. aws sts get-caller-identity) for authentication.

See https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html for more information on how authentication works on EKS.

Develop

If you wish to build this yourself, follow the instructions:

cd terraform-provider-helmfile
go build

Acknowledgement

The implementation of this product is highly inspired from terraform-provider-shell. A lot of thanks to the author!

More Repositories

1

kube-airflow

A docker image and kubernetes config files to run Airflow on Kubernetes
Python
649
star
2

aws-secret-operator

A Kubernetes operator that automatically creates and updates Kubernetes secrets according to what are stored in AWS Secrets Manager.
Go
309
star
3

variant

Wrap up your bash scripts into a modern CLI today. Graduate to a full-blown golang app tomorrow.
Go
301
star
4

terraform-provider-eksctl

Manage AWS EKS clusters using Terraform and eksctl
Go
232
star
5

helm-x

Treat any Kustomization or K8s manifests directory as a Helm chart
Go
169
star
6

play2-memcached

A memcached plugin for Play 2.x
Scala
162
star
7

variant2

Turn your bash scripts into a modern, single-executable CLI app today
Go
134
star
8

kube-ssm-agent

Secure, access-controlled, and audited terminal sessions to EKS nodes without SSH
Dockerfile
106
star
9

kube-spot-termination-notice-handler

Moved to https://github.com/kube-aws/kube-spot-termination-notice-handler
Shell
97
star
10

concourse-aws

Auto-scaling Concourse CI v2.2.1 on AWS with Terraform (since 2016.04.14)
Go
72
star
11

play2-typescript

TypeScript assets handling for Play 2.0. Compiles .ts files under the /assets dir along with the project.
Scala
72
star
12

crossover

Minimal sufficient Envoy xDS for Kubernetes that knows https://smi-spec.io/
Go
71
star
13

helmfile-operator

Kubernetes operator that continuously syncs any set of Chart/Kustomize/Manifest fetched from S3/Git/GCS to your cluster
Go
62
star
14

okra

Hot-swap Kubernetes clusters while keeping your service up and running.
Go
48
star
15

decouple-apps-and-eks-clusters-with-tf-and-gitops

Smarty
31
star
16

kodedeploy

CodeDeploy for EKS. Parallel and Continuous (re)delivery to multiple EKS clusters. Blue-green deployment "of" EKS clusters.
Shell
29
star
17

config-registry

Switch between kubeconfigs and avoid unintentional operation on your production clusters.
Go
28
star
18

gosh

(Re)write your bash script in Go and make it testable too
Go
24
star
19

tiny-mmo

A work-in-progress example of server-side implementation of a tiny massive multi-player online game, implemented with Scala 2.10.2 and Akka 2.2
Java
23
star
20

geohash-scala

Geohash library for scala
Scala
23
star
21

prometheus-process-exporter

Helml chart for Prometheus process-exporter
Mustache
22
star
22

waypoint-plugin-helmfile

Helmfile deployment plugin for HashiCorp Waypoint
Go
15
star
23

kube-magic-ip-address

daemonset that assigns a magic IP address to pods. Useful for implementing node-local services on Kubernetes. Use in combination with dd-agent, dd-zipkin-proxy, kube2iam, kiam, and Elastic's apm-server
Shell
15
star
24

kube-fluentd

An ubuntu-slim/s6-overlay/confd based docker image for running fluentd in Kubernetes pods/daemonsets
Makefile
15
star
25

node-detacher

Practically and gracefully stop your K8s node on (termination|scale down|maintenance)
Go
13
star
26

kube-node-init

Kubernetes daemonset for node initial configuration. Currently for modifying files and systemd services on eksctl nodes without changing userdata
Smarty
13
star
27

lambda_bot

JavaScript
12
star
28

argocd-clusterset

A command-line tool and Kubernetes controller to sync EKS clusters into ArgoCD cluster secrets
Go
12
star
29

dcind

Docker Compose (and Daemon) in Docker
Shell
12
star
30

flux-repo

Enterprise-grade secrets management for GitOps
Go
10
star
31

brigade-helmfile-demo

Demo for building an enhanced GitOps pipeline with Flux, Brigade and Helmfile
JavaScript
9
star
32

kubeherd

A opinionated toolkit to automate herding your cattles = ephemeral Kubernetes clusters
Shell
9
star
33

sopsed

Spawning and storage of secure environments powered by sops, inspired from vaulted. Out-of-box support for kubectl, kube-aws, helm, helmfile
Go
9
star
34

helmfile-gitops

8
star
35

nodelocaldns

Temporary location of the nodelocaldns chart until it is upstreamed to helm/charts
Smarty
8
star
36

kube-logrotate

An ubuntu-slim/s6-overlay/confd based docker image for running logrotate via Kubernetes daemonsets
Makefile
7
star
37

idea-play

A plugin for IntelliJ IDEA which supports development of Play framework applications.
Java
7
star
38

actions-runner-controller-ci

Test repo for https://github.com/summerwind/actions-runner-controller
Go
6
star
39

kargo

Deploy your Kubernetes application directly or indirectly
Go
6
star
40

shoal

Declarative, Go-embeddable, and cross-platform package manager powered by https://gofi.sh/
Go
6
star
41

ingress-daemonset-controller

Build your own highly available and efficient external ingress loadbalancer on Kubernetes
Go
6
star
42

conflint

Unified lint runners for various configuration files
Go
5
star
43

fluent-plugin-datadog-log

Sends logs to Datadog Log Management: A port/translation of https://github.com/DataDog/datadog-log-agent to a Fluentd plugin
Ruby
5
star
44

play20-zentasks-tests

Added spec2 tests to Play20's 'zentasks
Scala
4
star
45

nomidroid

Android app to find nearby restaurants, bars, etc with Recruit Web API
Java
4
star
46

versapack

Versatile package manager. Version and host anything in Helm charts repositories
4
star
47

vote4music-play20

A Play 2.0 RC1 port of https://github.com/loicdescotte/vote4music
Scala
4
star
48

homebrew-anyenv

Ruby
4
star
49

terraform-provider-kubectl

Run kubectl against multiple K8s clusters in a single terraform-apply. AWS auth/AssumeRole supported.
Go
3
star
50

kube-node-index-prioritizing-scheduler

Kubernetes scheduler extender that uses sorted nodes' positions as priorities. Use in combination with resource request/limit to implement low-latency highly available front proxy cluster
Go
3
star
51

depot

Ruby
2
star
52

kokodoko

JavaScript
2
star
53

brigade-cd

Go
2
star
54

scripts

my scripts for linux machines
Shell
2
star
55

courier

Go
2
star
56

nodejs-chat

JavaScript
2
star
57

ooina

JavaScript
2
star
58

play-websocket-growl-sample

A sample application notifies the server on Growl, and other users via WebSocket
Java
2
star
59

heartbeat-operator

Monitor any http and tcp services via Kubernetes custom resources
Shell
2
star
60

brigade-automation

TypeScript
2
star
61

nbxmpfilter

xmpfilter for NetBeans
2
star
62

play-scala-lobby-example

Java/Scala mixed app with a WebSocketController in Java, while others are in Scala.
JavaScript
2
star
63

wy

Go
2
star
64

docker-squid-gem-proxy

Dockerfile for building docker image to run Squid-based reverse proxies to rubygems.org, for speeding-up `gem install` or `bundle install`
Shell
2
star
65

hcl2-yaml

YAML syntax for HashiCorp Configuration Language Version 2
Go
2
star
66

tweet_alarm_clock_android

Java
2
star
67

testkit

A toolkit for writing Go tests for your cloud apps, infra-as-code, and gitops configs
Go
1
star
68

elasticdrone

A set of tools to configure auto-scaled Drone.io cluster on AWS in ease
JavaScript
1
star
69

kubeaws-cicd-pipeline-golang

An example of the opinionated deployment pipeline for your Kubernetes-on-AWS-native apps. Secure, declarative, customizable, open app deployments at your hand.
Shell
1
star
70

akka-parallel-tasks

Scala
1
star
71

sing

1
star
72

good-code-is-red-example-for-idea-scala-plugin

Scala
1
star
73

share-snippets

JavaScript
1
star
74

scala-scalable-programming-sidenote

Scala
1
star
75

teleport-on-minikube

Shell
1
star
76

genrun

Go
1
star
77

nomidroid_test

tests for nomidroid the android app.
Java
1
star
78

web_smartphonizer

Scala
1
star
79

idobata4s

The Scala client library for idobata.io API
Scala
1
star
80

specs2-sandbox

Scala
1
star
81

kube-distributed-test-runner

Go
1
star
82

delimited-continuation

An example usage of Delimited Continuation in Scala,;implementing an async HTTP client.
Scala
1
star
83

play2-unit-tests-sample

1
star
84

syaml

Set YAML values with `cat your.yaml | syaml a.b.c newValue`
Go
1
star
85

scala-debian-package

1
star
86

glabel

A GOverlay implementation for putting text labels on GMap2
JavaScript
1
star
87

gitops-demo

Makefile
1
star
88

division

Control-plane of your microservices and Kubernetes clusters
Go
1
star
89

sam-containerized-go-example

Go
1
star
90

mumoauth

Yet another implementation of OAuth aiming to cover both OAuth 1.0a and 2, from Client to Server.
Scala
1
star
91

javascript-missiles-and-lasers

JavaScript
1
star
92

kube-veneur

Sidecar container to run local veneur and Kubernetes service for global https://github.com/stripe/veneur. Uses confd and s6-overlay under the hood.
Makefile
1
star
93

tweet_alarm_clock_android_test

Java
1
star
94

thread_local

An implementation of the thread-local variable for Ruby
Ruby
1
star
95

play-multijpa

a Play! plugin to switch databases for each play.db.jpa.Model subclass
Java
1
star
96

argocd-example-apps

Jsonnet
1
star
97

javascript-hue_circle

Draw a hue circle in JavaScript
JavaScript
1
star
98

logrus-bunyan-formatter

Logrus Bunyan Log Formatter
Go
1
star
99

crdb

Custom Resource DB - Kubernetes custom resources without Kubernetes or self-hosted databases. For any cloud, by leveraging cloudprovider-specific managed databases like AWS DynamoDB
Go
1
star