Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Terraform install example #58

Merged
merged 2 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,10 @@
go.work
bin/
disto/

# Terraform
**/.terraform
*.tfstate
*.tfstate.*
.terraform.lock.hcl
.terraformrc
60 changes: 60 additions & 0 deletions config/terraform/README.md
Original file line number Diff line number Diff line change
@@ -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'
```
102 changes: 102 additions & 0 deletions config/terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
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 kustomize patches.
values = [
file("values/components.yaml")
]

// Configure the Flux distribution.
set {
name = "instance.distribution.version"
value = var.flux_version
}
set {
name = "instance.distribution.registry"
value = var.flux_registry
}

// 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" : ""
}
}
Empty file added config/terraform/outputs.tf
Empty file.
9 changes: 9 additions & 0 deletions config/terraform/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
provider "kubernetes" {
config_path = "~/.kube/config"
}

provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}
20 changes: 20 additions & 0 deletions config/terraform/values/components.yaml
Original file line number Diff line number Diff line change
@@ -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
36 changes: 36 additions & 0 deletions config/terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -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"
}