Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mumoshu committed Nov 24, 2019
0 parents commit c44e854
Show file tree
Hide file tree
Showing 16 changed files with 1,387 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Go
on: [push, pull_request]
jobs:

build:
name: Build
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.13
uses: actions/setup-go@v1
with:
go-version: 1.13
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v1

- name: Test
run: make test

- name: Build
run: make build
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
terraform-artifactory.tf
terraform-provider-artifactory
*.dll
*.exe
.DS_Store
example.tf
terraform.tfplan
terraform.tfstate
bin/
modules-dev/
vendor/*/
website/.vagrant
website/build
website/node_modules
.vagrant/
*.backup
./*.tfstate
.terraform/
*.log
*.bak
*~
.*.swp
.idea
resources
resources2
src/
.vscode
.vscode/
dist/
examples/terraform.d
*.iml
54 changes: 54 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.DEFAULT_GOAL := build
OS := $(shell go env GOOS)
ARCH := $(shell go env GOARCH)
PLUGIN_PATH ?= ${HOME}/.terraform.d/plugins/${OS}_${ARCH}
PLUGIN_NAME := terraform-provider-helmfile
DIST_PATH := dist/${OS}_${ARCH}
GO_PACKAGES := $(shell go list ./... | grep -v /vendor/)
GO_FILES := $(shell find . -type f -name '*.go')


.PHONY: all
all: test build

.PHONY: test
test: test-all

.PHONY: test-all
test-all:
@TF_ACC=1 go test -v -race $(GO_PACKAGES)

${DIST_PATH}/${PLUGIN_NAME}: ${GO_FILES}
mkdir -p $(DIST_PATH); \
go build -o $(DIST_PATH)/${PLUGIN_NAME}

.PHONY: build
build: ${DIST_PATH}/${PLUGIN_NAME}

.PHONY: install
install: build
mkdir -p $(PLUGIN_PATH); \
rm -rf $(PLUGIN_PATH)/${PLUGIN_NAME}; \
install -m 0755 $(DIST_PATH)/${PLUGIN_NAME} $(PLUGIN_PATH)/${PLUGIN_NAME}

.PHONY: example/plan
example/plan:
mkdir -p examples/terraform.d/plugins
env PLUGIN_PATH=examples/terraform.d/plugins/$(OS)_$(ARCH) make install
cd examples; terraform init; terraform plan

.PHONY: example/apply
example/apply:
mkdir -p examples/terraform.d/plugins
env PLUGIN_PATH=examples/terraform.d/plugins/$(OS)_$(ARCH) make install
cd examples; terraform init; terraform apply

.PHONY: example/destroy
example/destroy:
mkdir -p examples/terraform.d/plugins
env PLUGIN_PATH=examples/terraform.d/plugins/$(OS)_$(ARCH) make install
cd examples; terraform init; terraform destroy

.PHONY: clean
clean:
rm -rf ${DIST_PATH}/*
172 changes: 172 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# terraform-provider-helmfile

Deploy [Helmfile](https://github.com/roboll/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`

## Prerequisites

Install the `terraform-provider-helmfile` binary under `terraform.d/plugins/${OS}_${ARCH}`.

## Examples

There is nothing to configure for the provider, declare it like so

```
provider "helmfile" {}
resource "helmfile_release_set" "mystack" {
path = "./helmfile.yaml"
# 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
# Helmfile environment name to deploy
# Default: default
environment = "prod"
# Environment variables available to helmfile's requireEnv
environment_variables = {
FOO = "foo"
}
# 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_files = [
"overrides.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:

```console
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`:

```console
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`:

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

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

Outputs:

mystack_apply =
mystack_diff =
```

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

cd terraform-provider-helmfile
go build
5 changes: 5 additions & 0 deletions examples/helmfile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
releases:
- name: {{ .Values.name }}-{{ requiredEnv "FOO" }}
chart: sp/podinfo
labels:
labelkey1: value1
1 change: 1 addition & 0 deletions examples/temp.values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"myapp"}
31 changes: 31 additions & 0 deletions examples/test.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
provider "helmfile" {}

resource "helmfile_release_set" "mystack" {
path = "./helmfile.yaml"

helm_binary = "helm3"

working_directory = path.module

environment = "default"

environment_variables = {
FOO = "foo"
}

values = {
name = "myapp"
}

selector = {
labelkey1 = "value1"
}
}

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

output "mystack_apply" {
value = helmfile_release_set.mystack.apply_output
}
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/mumoshu/terraform-provider-helmfile

go 1.12

require (
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
github.com/hashicorp/terraform-plugin-sdk v1.0.0
github.com/mitchellh/go-linereader v0.0.0-20190213213312-1b945b3263eb
github.com/posener/complete v1.2.1
github.com/rs/xid v1.2.1
)

replace git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999
Loading

0 comments on commit c44e854

Please sign in to comment.