From 5ef95720e8cc38c9b26ddbe3c307dcb43bd1b85c Mon Sep 17 00:00:00 2001 From: Vedant Pareek Date: Tue, 22 Oct 2024 17:37:43 +0530 Subject: [PATCH 1/7] Added variables.tf and versions.tf --- variables.tf | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ versions.tf | 4 ++++ 2 files changed, 60 insertions(+) create mode 100644 variables.tf create mode 100644 versions.tf diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..69b5e0b --- /dev/null +++ b/variables.tf @@ -0,0 +1,56 @@ +variable "chart_name" { + type = string + description = "Name of the chart" +} + +variable "chart_version" { + type = string + description = "Version of the chart" +} + +variable "release_name" { + type = string + description = "Release name of the chart" +} + +variable "namespace" { + type = string + description = "Namespace to install the chart" +} + +variable "create_namespace" { + type = bool + default = false + description = "Create the namespace if it does not exist. Defaults to false" +} + +variable "repo_name" { + type = string + description = "Name of the Helm repository" +} + +variable "repo_url" { + type = string + description = "URL of the Helm repository" +} + +variable "cluster_ca_certificate" { + type = string + description = "CA certificate of the cluster" +} + +variable "cluster_endpoint" { + type = string + description = "Endpoint of the cluster" +} + +variable "token" { + type = string + description = "Token to authenticate with the cluster" +} + +variable "set_values" { + type = any + description = "A map of values to pass to the Helm chart" + default = {} +} diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..ab85202 --- /dev/null +++ b/versions.tf @@ -0,0 +1,4 @@ +terraform { + required_version = ">= 0.13" + # Remove the required_providers block if you're not using any providers in this module +} From 03910577eb4a5e934ed652abed47376f91abf376 Mon Sep 17 00:00:00 2001 From: Harshit Luthra Date: Tue, 22 Oct 2024 18:32:45 +0530 Subject: [PATCH 2/7] add main.tf and readme --- README.md | 56 +++++++++++++++++++++++++++++++++++++++- main.tf | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ variables.tf | 10 -------- 3 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 main.tf diff --git a/README.md b/README.md index 1fd5a2f..d06908a 100644 --- a/README.md +++ b/README.md @@ -1 +1,55 @@ -# terraform-kubernetes-helm \ No newline at end of file +# Terraform Helm Chart Installation Module + +This Terraform module provides a flexible way to install Helm charts on a Kubernetes cluster. It uses a `null_resource` with a `local-exec` provisioner to run Helm commands, allowing for dynamic chart installation and updates. + +## Features + +- Installs or upgrades Helm charts +- Supports custom repositories +- Allows for namespace creation +- Configurable chart values +- Uses temporary files for secure kubeconfig and values handling + +## Requirements + +- Terraform >= 0.13 +- Helm (installed on the machine running Terraform) +- Access to a Kubernetes cluster + +## Input Variables + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| `chart_name` | Name of the Helm chart to install | `string` | n/a | yes | +| `chart_version` | Version of the Helm chart to install | `string` | n/a | yes | +| `release_name` | Name for the Helm release | `string` | n/a | yes | +| `namespace` | Kubernetes namespace to install the release into | `string` | n/a | yes | +| `create_namespace` | Whether to create the namespace if it doesn't exist | `bool` | `false` | no | +| `repo_name` | Name of the Helm repository | `string` | n/a | yes | +| `repo_url` | URL of the Helm repository | `string` | n/a | yes | +| `cluster_ca_certificate` | Base64 encoded CA certificate of the Kubernetes cluster | `string` | n/a | yes | +| `cluster_endpoint` | Endpoint of the Kubernetes cluster | `string` | n/a | yes | +| `token` | Authentication token for the Kubernetes cluster | `string` | n/a | yes | +| `set_values` | Map of values to pass to the Helm chart | `any` | `{}` | no | + +## How it works + +1. The module creates temporary files for the kubeconfig and chart values. +2. It then uses these temporary files to run Helm commands via a `local-exec` provisioner. +3. The Helm repository is added and updated. +4. The chart is installed or upgraded using the provided values. +5. Temporary files are cleaned up after the Helm command execution. + +## Notes + +- Ensure that the machine running Terraform has Helm installed and configured. +- The module uses a `null_resource` with a `local-exec` provisioner, which means the Helm commands are executed on the machine running Terraform, not within Terraform itself. +- Be cautious with sensitive information in `set_values`. While this module uses temporary files, it's generally a good practice to manage secrets separately. + +## Contributing + +Contributions to improve this module are welcome. Please submit a pull request or open an issue on the repository. + +## License + +This module is released under the MIT License. See the [LICENSE](./LICENSE) file for more details. diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..6ffb5f7 --- /dev/null +++ b/main.tf @@ -0,0 +1,72 @@ +resource "null_resource" "helm_install" { + triggers = { + chart_name = var.chart_name + chart_version = var.chart_version + release_name = var.release_name + namespace = var.namespace + always_run = "${timestamp()}" + } + + provisioner "local-exec" { + command = <<-EOT + echo "Starting Helm install process..." + + # Create a temporary kubeconfig file + KUBECONFIG_FILE=$(mktemp) + echo "Created temporary KUBECONFIG file: $KUBECONFIG_FILE" + + # Write the kubeconfig content + cat < $KUBECONFIG_FILE + apiVersion: v1 + kind: Config + clusters: + - cluster: + server: ${var.cluster_endpoint} + certificate-authority-data: ${var.cluster_ca_certificate} + name: kubernetes + contexts: + - context: + cluster: kubernetes + user: aws + name: aws + current-context: aws + users: + - name: aws + user: + token: ${var.token} + EOF + echo "Wrote kubeconfig content to $KUBECONFIG_FILE" + + # Create a temporary values file + VALUES_FILE=$(mktemp) + echo "Created temporary values file: $VALUES_FILE" + + # Write the values content + cat < $VALUES_FILE + ${jsonencode(var.set_values)} + EOF + echo "Wrote values content to $VALUES_FILE" + + # Run Helm command with the temporary kubeconfig and values file + echo "Running Helm command..." + KUBECONFIG=$KUBECONFIG_FILE helm repo add ${var.repo_name} ${var.repo_url} + KUBECONFIG=$KUBECONFIG_FILE helm repo update + KUBECONFIG=$KUBECONFIG_FILE helm upgrade --install ${var.release_name} ${var.repo_name}/${var.chart_name} \ + --version ${var.chart_version} \ + --namespace ${var.namespace} \ + ${var.create_namespace ? "--create-namespace" : ""} \ + -f $VALUES_FILE \ + --debug + + HELM_EXIT_CODE=$? + echo "Helm command exited with code: $HELM_EXIT_CODE" + + # Clean up the temporary files + rm $KUBECONFIG_FILE + rm $VALUES_FILE + echo "Removed temporary KUBECONFIG and values files" + + exit $HELM_EXIT_CODE + EOT + } +} diff --git a/variables.tf b/variables.tf index 69b5e0b..4781583 100644 --- a/variables.tf +++ b/variables.tf @@ -1,52 +1,42 @@ variable "chart_name" { type = string - description = "Name of the chart" } variable "chart_version" { type = string - description = "Version of the chart" } variable "release_name" { type = string - description = "Release name of the chart" } variable "namespace" { type = string - description = "Namespace to install the chart" } variable "create_namespace" { type = bool default = false - description = "Create the namespace if it does not exist. Defaults to false" } variable "repo_name" { type = string - description = "Name of the Helm repository" } variable "repo_url" { type = string - description = "URL of the Helm repository" } variable "cluster_ca_certificate" { type = string - description = "CA certificate of the cluster" } variable "cluster_endpoint" { type = string - description = "Endpoint of the cluster" } variable "token" { type = string - description = "Token to authenticate with the cluster" } variable "set_values" { From 74486a084a8289c0df874ef18f7f903107699c3f Mon Sep 17 00:00:00 2001 From: Vedant Pareek Date: Tue, 22 Oct 2024 18:38:46 +0530 Subject: [PATCH 3/7] Added workflows --- .github/workflows/lint_clean.yaml | 18 ++++++++++++ .github/workflows/terraform-docs.yaml | 16 +++++++++++ .github/workflows/tflint.yaml | 40 +++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 .github/workflows/lint_clean.yaml create mode 100644 .github/workflows/terraform-docs.yaml create mode 100644 .github/workflows/tflint.yaml diff --git a/.github/workflows/lint_clean.yaml b/.github/workflows/lint_clean.yaml new file mode 100644 index 0000000..a15b694 --- /dev/null +++ b/.github/workflows/lint_clean.yaml @@ -0,0 +1,18 @@ +name: 'Lint and Clean' + +on: + pull_request: + + push: + branches: + - main + +jobs: + fmt: + name: Terraform FMT + runs-on: ubuntu-latest + container: + image: hashicorp/terraform:latest + steps: + - uses: actions/checkout@v2 + - run: terraform fmt --recursive --diff -check=true \ No newline at end of file diff --git a/.github/workflows/terraform-docs.yaml b/.github/workflows/terraform-docs.yaml new file mode 100644 index 0000000..5c766b9 --- /dev/null +++ b/.github/workflows/terraform-docs.yaml @@ -0,0 +1,16 @@ +name: Generate terraform docs +on: + - pull_request + +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - name: Render terraform docs and push changes back to PR + uses: terraform-docs/gh-actions@main + with: + git-push: "true" \ No newline at end of file diff --git a/.github/workflows/tflint.yaml b/.github/workflows/tflint.yaml new file mode 100644 index 0000000..42620cf --- /dev/null +++ b/.github/workflows/tflint.yaml @@ -0,0 +1,40 @@ +name: Lint +on: + pull_request: + branches: + - main + +jobs: + tflint: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v3 + name: Checkout source code + + - uses: actions/cache@v3 + name: Cache plugin dir + with: + path: ~/.tflint.d/plugins + key: ${{ matrix.os }}-tflint-${{ hashFiles('.tflint.hcl') }} + + - uses: terraform-linters/setup-tflint@v3 + name: Setup TFLint + with: + tflint_version: v0.47.0 + + - name: Show version + run: tflint --version + + - name: Init TFLint + run: tflint --init + env: + # https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting + GITHUB_TOKEN: ${{ github.token }} + + - name: Run TFLint + run: tflint --minimum-failure-severity=error -f compact \ No newline at end of file From ba31769b384f4b495ed9e2dd39bad25a94c42784 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 22 Oct 2024 13:09:15 +0000 Subject: [PATCH 4/7] terraform-docs: automated action --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index d06908a..02371e1 100644 --- a/README.md +++ b/README.md @@ -53,3 +53,47 @@ Contributions to improve this module are welcome. Please submit a pull request o ## License This module is released under the MIT License. See the [LICENSE](./LICENSE) file for more details. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13 | + +## Providers + +| Name | Version | +|------|---------| +| [null](#provider\_null) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [null_resource.helm_install](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [chart\_name](#input\_chart\_name) | n/a | `string` | n/a | yes | +| [chart\_version](#input\_chart\_version) | n/a | `string` | n/a | yes | +| [cluster\_ca\_certificate](#input\_cluster\_ca\_certificate) | n/a | `string` | n/a | yes | +| [cluster\_endpoint](#input\_cluster\_endpoint) | n/a | `string` | n/a | yes | +| [create\_namespace](#input\_create\_namespace) | n/a | `bool` | `false` | no | +| [namespace](#input\_namespace) | n/a | `string` | n/a | yes | +| [release\_name](#input\_release\_name) | n/a | `string` | n/a | yes | +| [repo\_name](#input\_repo\_name) | n/a | `string` | n/a | yes | +| [repo\_url](#input\_repo\_url) | n/a | `string` | n/a | yes | +| [set\_values](#input\_set\_values) | A map of values to pass to the Helm chart | `any` | `{}` | no | +| [token](#input\_token) | n/a | `string` | n/a | yes | + +## Outputs + +No outputs. + \ No newline at end of file From 466ee91bdcc734cd5cccb30c2cf8a6abeddd97a0 Mon Sep 17 00:00:00 2001 From: Vedant Pareek Date: Tue, 22 Oct 2024 19:09:18 +0530 Subject: [PATCH 5/7] modifed variables --- variables.tf | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 4781583..0fedd35 100644 --- a/variables.tf +++ b/variables.tf @@ -1,46 +1,56 @@ variable "chart_name" { type = string + description = "Name of the chart" } variable "chart_version" { type = string + description = "Version of the chart" } variable "release_name" { type = string + description = "Release name of the chart" } variable "namespace" { type = string + description = "Namespace to install the chart" } variable "create_namespace" { type = bool default = false + description = "Create the namespace if it does not exist. Defaults to false" } variable "repo_name" { type = string + description = "Name of the Helm repository" } variable "repo_url" { type = string + description = "URL of the Helm repository" } variable "cluster_ca_certificate" { type = string + description = "CA certificate of the cluster" } variable "cluster_endpoint" { type = string + description = "Endpoint of the cluster" } variable "token" { type = string + description = "Token to authenticate with the cluster" } variable "set_values" { type = any description = "A map of values to pass to the Helm chart" default = {} -} +} \ No newline at end of file From c42d1bc8fd0c01c1344049ac7db6c818a9679d2a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 22 Oct 2024 13:39:43 +0000 Subject: [PATCH 6/7] terraform-docs: automated action --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 02371e1..1db1466 100644 --- a/README.md +++ b/README.md @@ -81,17 +81,17 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [chart\_name](#input\_chart\_name) | n/a | `string` | n/a | yes | -| [chart\_version](#input\_chart\_version) | n/a | `string` | n/a | yes | -| [cluster\_ca\_certificate](#input\_cluster\_ca\_certificate) | n/a | `string` | n/a | yes | -| [cluster\_endpoint](#input\_cluster\_endpoint) | n/a | `string` | n/a | yes | -| [create\_namespace](#input\_create\_namespace) | n/a | `bool` | `false` | no | -| [namespace](#input\_namespace) | n/a | `string` | n/a | yes | -| [release\_name](#input\_release\_name) | n/a | `string` | n/a | yes | -| [repo\_name](#input\_repo\_name) | n/a | `string` | n/a | yes | -| [repo\_url](#input\_repo\_url) | n/a | `string` | n/a | yes | +| [chart\_name](#input\_chart\_name) | Name of the chart | `string` | n/a | yes | +| [chart\_version](#input\_chart\_version) | Version of the chart | `string` | n/a | yes | +| [cluster\_ca\_certificate](#input\_cluster\_ca\_certificate) | CA certificate of the cluster | `string` | n/a | yes | +| [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint of the cluster | `string` | n/a | yes | +| [create\_namespace](#input\_create\_namespace) | Create the namespace if it does not exist. Defaults to false | `bool` | `false` | no | +| [namespace](#input\_namespace) | Namespace to install the chart | `string` | n/a | yes | +| [release\_name](#input\_release\_name) | Release name of the chart | `string` | n/a | yes | +| [repo\_name](#input\_repo\_name) | Name of the Helm repository | `string` | n/a | yes | +| [repo\_url](#input\_repo\_url) | URL of the Helm repository | `string` | n/a | yes | | [set\_values](#input\_set\_values) | A map of values to pass to the Helm chart | `any` | `{}` | no | -| [token](#input\_token) | n/a | `string` | n/a | yes | +| [token](#input\_token) | Token to authenticate with the cluster | `string` | n/a | yes | ## Outputs From 30d51589e6ac26f36798ef19c7dfc5d65127aba1 Mon Sep 17 00:00:00 2001 From: Vedant Pareek Date: Tue, 22 Oct 2024 19:10:17 +0530 Subject: [PATCH 7/7] terraform fmt --- variables.tf | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/variables.tf b/variables.tf index 0fedd35..ab665d6 100644 --- a/variables.tf +++ b/variables.tf @@ -1,51 +1,51 @@ variable "chart_name" { - type = string + type = string description = "Name of the chart" } variable "chart_version" { - type = string + type = string description = "Version of the chart" } variable "release_name" { - type = string + type = string description = "Release name of the chart" } variable "namespace" { - type = string + type = string description = "Namespace to install the chart" } variable "create_namespace" { - type = bool - default = false + type = bool + default = false description = "Create the namespace if it does not exist. Defaults to false" } variable "repo_name" { - type = string + type = string description = "Name of the Helm repository" } variable "repo_url" { - type = string + type = string description = "URL of the Helm repository" } variable "cluster_ca_certificate" { - type = string + type = string description = "CA certificate of the cluster" } variable "cluster_endpoint" { - type = string + type = string description = "Endpoint of the cluster" } variable "token" { - type = string + type = string description = "Token to authenticate with the cluster" }