From 7871e252557c0fcfc6fdf68f1ea5ebb2a7bd41b5 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Mon, 1 Jul 2024 11:42:44 +0300 Subject: [PATCH 1/2] Add Terraform install example Signed-off-by: Stefan Prodan --- .gitignore | 7 +++ config/terraform/README.md | 60 +++++++++++++++++++ config/terraform/main.tf | 109 ++++++++++++++++++++++++++++++++++ config/terraform/outputs.tf | 0 config/terraform/providers.tf | 9 +++ config/terraform/variables.tf | 36 +++++++++++ 6 files changed, 221 insertions(+) create mode 100644 config/terraform/README.md create mode 100644 config/terraform/main.tf create mode 100644 config/terraform/outputs.tf create mode 100644 config/terraform/providers.tf create mode 100644 config/terraform/variables.tf diff --git a/.gitignore b/.gitignore index 79fe858..bc05b88 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,10 @@ go.work bin/ disto/ + +# Terraform +**/.terraform +*.tfstate +*.tfstate.* +.terraform.lock.hcl +.terraformrc diff --git a/config/terraform/README.md b/config/terraform/README.md new file mode 100644 index 0000000..97175e4 --- /dev/null +++ b/config/terraform/README.md @@ -0,0 +1,60 @@ +# Install Flux with Terraform + +This example demonstrates how to deploy Flux on a Kubernetes cluster using Terraform +and the `flux-operator` and `flux-instance` Helm charts. + +## Usage + +Create a Kubernetes cluster using KinD: + +```shell +kind create cluster --name flux +``` + +Install the Flux Operator and deploy the Flux instance on the cluster +set as the default context in the `~/.kube/config` file: + +```shell +terraform apply \ + -var flux_version="2.x" \ + -var flux_registry="ghcr.io/fluxcd" \ + -var git_token="${GITHUB_TOKEN}" \ + -var git_url="https://github.com/fluxcd/flux2-kustomize-helm-example.git" \ + -var git_ref="refs/heads/main" \ + -var git_path="clusters/production" +``` + +Note that the `GITHUB_TOKEN` env var must be set to a GitHub personal access token. +The `git_token` variable is used to create a Kubernetes secret in the `flux-system` namespace for +Flux to authenticate with the Git repository over HTTPS. +If the repository is public, the token variable can be omitted. + +Verify the Flux components are running: + +```shell +kubectl -n flux-system get pods +``` + +Verify the Flux instance is syncing the cluster state from the Git repository: + +```shell +kubectl -n flux-system get fluxreport/flux -o yaml +``` + +The output should show the sync status: + +```yaml +apiVersion: fluxcd.controlplane.io/v1 +kind: FluxReport +metadata: + name: flux + namespace: flux-system +spec: + # Distribution status omitted for brevity + sync: + id: kustomization/flux-system + path: clusters/production + ready: true + source: https://github.com/fluxcd/flux2-kustomize-helm-example.git + status: 'Applied revision: refs/heads/main@sha1:21486401be9bcdc37e6ebda48a3b68f8350777c9' +``` diff --git a/config/terraform/main.tf b/config/terraform/main.tf new file mode 100644 index 0000000..db950d2 --- /dev/null +++ b/config/terraform/main.tf @@ -0,0 +1,109 @@ +terraform { + required_version = ">= 1.7" + + required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.27" + } + helm = { + source = "hashicorp/helm" + version = ">= 2.12" + } + } +} + +// Create the flux-system namespace. +resource "kubernetes_namespace" "flux_system" { + metadata { + name = "flux-system" + } + + lifecycle { + ignore_changes = [metadata] + } +} + +// Create a Kubernetes secret with the Git credentials +// if a Git token is provided. +resource "kubernetes_secret" "git_auth" { + count = var.git_token != "" ? 1 : 0 + depends_on = [kubernetes_namespace.flux_system] + + metadata { + name = "flux-system" + namespace = "flux-system" + } + + data = { + username = "git" + password = var.git_token + } + + type = "Opaque" +} + +// Install the Flux Operator. +resource "helm_release" "flux_operator" { + depends_on = [kubernetes_namespace.flux_system] + + name = "flux-operator" + namespace = "flux-system" + repository = "oci://ghcr.io/controlplaneio-fluxcd/charts" + chart = "flux-operator" + wait = true +} + +// Configure the Flux instance. +resource "helm_release" "flux_instance" { + depends_on = [helm_release.flux_operator] + + name = "flux" + namespace = "flux-system" + repository = "oci://ghcr.io/controlplaneio-fluxcd/charts" + chart = "flux-instance" + + // Configure the Flux components and automated upgrades. + set { + name = "instance.distribution.version" + value = var.flux_version + } + set { + name = "instance.distribution.registry" + value = var.flux_registry + } + set_list { + name = "instance.components" + value = [ + "source-controller", + "kustomize-controller", + "helm-controller", + "notification-controller", + "image-reflector-controller", + "image-automation-controller" + ] + } + + // Configure Flux Git sync. + set { + name = "instance.sync.kind" + value = "GitRepository" + } + set { + name = "instance.sync.url" + value = var.git_url + } + set { + name = "instance.sync.path" + value = var.git_path + } + set { + name = "instance.sync.ref" + value = var.git_ref + } + set { + name = "instance.sync.pullSecret" + value = var.git_token != "" ? "flux-system" : "" + } +} + diff --git a/config/terraform/outputs.tf b/config/terraform/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/config/terraform/providers.tf b/config/terraform/providers.tf new file mode 100644 index 0000000..912fdd6 --- /dev/null +++ b/config/terraform/providers.tf @@ -0,0 +1,9 @@ +provider "kubernetes" { + config_path = "~/.kube/config" +} + +provider "helm" { + kubernetes { + config_path = "~/.kube/config" + } +} diff --git a/config/terraform/variables.tf b/config/terraform/variables.tf new file mode 100644 index 0000000..b82b675 --- /dev/null +++ b/config/terraform/variables.tf @@ -0,0 +1,36 @@ +variable "git_token" { + description = "Git PAT" + sensitive = true + type = string + default = "" +} + +variable "git_url" { + description = "Git repository URL" + type = string + nullable = false +} + +variable "git_path" { + description = "Path to the cluster manifests in the Git repository" + type = string + nullable = false +} + +variable "git_ref" { + description = "Git branch or tag in the format refs/heads/main or refs/tags/v1.0.0" + type = string + default = "refs/heads/main" +} + +variable "flux_version" { + description = "Flux version semver range" + type = string + default = "2.x" +} + +variable "flux_registry" { + description = "Flux distribution registry" + type = string + default = "ghcr.io/fluxcd" +} From c58027fce49da256cf427ef6711c8223d2b9fe8d Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Mon, 1 Jul 2024 14:03:26 +0300 Subject: [PATCH 2/2] Add kustomize patches to Terraform example Signed-off-by: Stefan Prodan --- config/terraform/main.tf | 21 +++++++-------------- config/terraform/values/components.yaml | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 config/terraform/values/components.yaml diff --git a/config/terraform/main.tf b/config/terraform/main.tf index db950d2..9f77eea 100644 --- a/config/terraform/main.tf +++ b/config/terraform/main.tf @@ -27,7 +27,7 @@ resource "kubernetes_namespace" "flux_system" { // Create a Kubernetes secret with the Git credentials // if a Git token is provided. resource "kubernetes_secret" "git_auth" { - count = var.git_token != "" ? 1 : 0 + count = var.git_token != "" ? 1 : 0 depends_on = [kubernetes_namespace.flux_system] metadata { @@ -63,7 +63,12 @@ resource "helm_release" "flux_instance" { repository = "oci://ghcr.io/controlplaneio-fluxcd/charts" chart = "flux-instance" - // Configure the Flux components and automated upgrades. + // Configure the Flux components and kustomize patches. + values = [ + file("values/components.yaml") + ] + + // Configure the Flux distribution. set { name = "instance.distribution.version" value = var.flux_version @@ -72,17 +77,6 @@ resource "helm_release" "flux_instance" { name = "instance.distribution.registry" value = var.flux_registry } - set_list { - name = "instance.components" - value = [ - "source-controller", - "kustomize-controller", - "helm-controller", - "notification-controller", - "image-reflector-controller", - "image-automation-controller" - ] - } // Configure Flux Git sync. set { @@ -106,4 +100,3 @@ resource "helm_release" "flux_instance" { value = var.git_token != "" ? "flux-system" : "" } } - diff --git a/config/terraform/values/components.yaml b/config/terraform/values/components.yaml new file mode 100644 index 0000000..4110eb3 --- /dev/null +++ b/config/terraform/values/components.yaml @@ -0,0 +1,20 @@ +instance: + components: + - source-controller + - kustomize-controller + - helm-controller + - notification-controller + - image-reflector-controller + - image-automation-controller + kustomize: + patches: + - target: + kind: Deployment + name: "(kustomize-controller|helm-controller)" + patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --concurrent=10 + - op: add + path: /spec/template/spec/containers/0/args/- + value: --requeue-dependency=10s