From 70a986913c863bc641f728311ebb7e20f6ec7250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20T=C3=B6lle?= Date: Sun, 5 Dec 2021 00:03:54 +0100 Subject: [PATCH] feat: install flux to new k3s cluster --- .terraform.lock.hcl | 58 ++++++++++++++++ k3s_cluster_v2/flux.tf | 133 ++++++++++++++++++++++++++++++++++++ k3s_cluster_v2/variables.tf | 32 +++++++++ k3s_cluster_v2/versions.tf | 15 ++++ main.tf | 11 +++ output.tf | 8 ++- variables.tf | 11 ++- 7 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 k3s_cluster_v2/flux.tf diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 93cf2fc..0c5ec95 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -1,6 +1,44 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/fluxcd/flux" { + version = "0.8.0" + constraints = ">= 0.0.13" + hashes = [ + "h1:vqux/ZeLIP/GyjHEZhCF5f496zKXCXL4wWDYamAJmQ0=", + "zh:2de31d7842a14dd372baee52d1e8d1c9e90914d15c7b138477f1a8cf5892983c", + "zh:321c2916430fd953adc0b2024599a72dc3679a7659691d8afe4eb3d139bd03d0", + "zh:40933ac440ca27cb9857caddbb062f13750987990219371bae1e6d959568ee6b", + "zh:4ed2de2155cbce0974efb652f2fc67fecb142c1d80927f700e0705be9f2e7f26", + "zh:5b119e74491597c058a2b5719d9060b104fa927103a08669f52088fd7e2c0761", + "zh:699d37a6332e0c9bf7d8be9bc5430e40867006df8b5b10ad4d65452be4abee31", + "zh:6f685b36bfbe50c9b95a31e9992f206024893ee78a22396bfe687a027b6ed6b7", + "zh:8b9600e38bac3fceff792d7862004b891ef7d28453145721ed6a418aeb61247e", + "zh:c29903b6f8937a1ab8eedc23738e166d6d6b8a323a1faf8dac5a2655615859be", + "zh:c49da334f778efc54208130d37da4d4a293b48e3ccf428fb2f334351a32550f6", + "zh:d3b38e27b90f4c9e91e3d67ab633205fdb1635babba665233b8bc3e2c1a3059b", + "zh:f0b9efedb21bf36277414242163bc5174ec3dfc76b6298698b46d221ad271d9c", + "zh:f673623e934e738031da06e6dc2fc33468e7feeac8434e620789489b00d07eda", + ] +} + +provider "registry.terraform.io/gavinbunney/kubectl" { + version = "1.13.1" + constraints = ">= 1.10.0" + hashes = [ + "h1:Kqo0t1R22DYLNsw8kFCBLPeV9zwns+86ijDnBUhJ+iw=", + "zh:212c030cb975e46e3a85a6850c16773974f4498042a45c73b883b25f6e05962d", + "zh:213d1be8a231b04fdc55fd027479dbf0ae5b7ab891804b64f464db771d091ecd", + "zh:45f37b5c43f85d79973d0b890f774531a65def7f8436e435a4e259198f1c62de", + "zh:5a362871827f8582d6129b9c8b7d73c5e4e181155cef4cba1fe0408880db52db", + "zh:78986fdb4c41ac35815e4d41832d24b41b0aac046c046f21db92205115d16bae", + "zh:a6d07a9f066c386f44d61e7e2e83133663e3049f5c6b153fa5601b85cbb788b1", + "zh:bb307e902d2401df42205d57e36a2e094765b87b12f99a24ec2af411bef3c0fa", + "zh:dc3281f9fab38b8daf76d5f0073d2e323574f03d4cef338d6a363380f7f7bb59", + "zh:eb30e7fef17e7630858070d23a59375ba3a87fceaffde1c722338b1ad88df568", + ] +} + provider "registry.terraform.io/hashicorp/http" { version = "1.2.0" constraints = "~> 1.2" @@ -134,3 +172,23 @@ provider "registry.terraform.io/hetznercloud/hcloud" { "zh:d6d87b405c0fd5e576a7e0a8976689d555299806484fdacca205537367d92f37", ] } + +provider "registry.terraform.io/integrations/github" { + version = "4.18.2" + hashes = [ + "h1:7qumrrxL9L9zpwmvNrJhq9GICMgOLIWJeWFu84iK7kU=", + "zh:0905624d48ee1493f0e23942aad742151f3778c5511f6ddd5acb89fe48a35179", + "zh:19f5ecedbba6dfecd8af625d41da45390936e9684d99d4330d1e415c1aa61064", + "zh:2a04c4cff4feaaaf47f99929742f17eba29284b7acd06068111fc7ff2161bcd5", + "zh:3652c758f343f31822816ebd2a593988342c543b0d1374401d453fcffa9abc1c", + "zh:3b37c217dc8ade666430b375d623fd24237377aa91ab4ba7a4f2c698b03293ab", + "zh:486ac6f1027e7c38bb1f0ae41eb62d149d94b263886cd9240ecb5ea7d1da5c77", + "zh:6f0da812a7879332dfa1eec0369b6302ad182abe1151eb46915e6ace497639b7", + "zh:7c7786b6241829c94c3bd2ecdf0c5c591157344832a0dafc31909430d651aca1", + "zh:cf44af2b50c0a00d02e545894285e5a2be18ac73a4959ed53ce5e5d2cdbe707e", + "zh:ecd4eeae228764fcbe7c318174f65d4be82a0fed3820a07de17d9db6ce431763", + "zh:f24e15ec2b564bccc2f1ff2b57a2631de9545167dc85693fdd5ec5bb55061835", + "zh:f5e0d357e7ff7b60b59acf60bfb2f24a14a1efe303e510dfc8bae2f5c6b1d0d4", + "zh:fe8fa19f5184e795ead5be1be7488a88826342f35a2ac81ecde319bb019698d6", + ] +} diff --git a/k3s_cluster_v2/flux.tf b/k3s_cluster_v2/flux.tf new file mode 100644 index 0000000..0afb87b --- /dev/null +++ b/k3s_cluster_v2/flux.tf @@ -0,0 +1,133 @@ +provider "kubectl" { + host = module.k3s.kubernetes.api_endpoint + cluster_ca_certificate = module.k3s.kubernetes.cluster_ca_certificate + client_certificate = module.k3s.kubernetes.client_certificate + client_key = module.k3s.kubernetes.client_key +} + +provider "github" { + owner = var.github_owner + token = var.github_token +} + +# SSH +locals { + known_hosts = "github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=" +} + +resource "tls_private_key" "main" { + algorithm = "ECDSA" + ecdsa_curve = "P256" +} + +# Flux +data "flux_install" "main" { + target_path = var.target_path +} + +data "flux_sync" "main" { + target_path = var.target_path + url = "ssh://git@github.com/${var.github_owner}/${var.repository_name}.git" + branch = var.branch +} + +# Kubernetes +resource "kubernetes_namespace" "flux_system" { + metadata { + name = "flux-system" + } + + lifecycle { + ignore_changes = [ + metadata[0].labels, + ] + } +} + +data "kubectl_file_documents" "install" { + content = data.flux_install.main.content +} + +data "kubectl_file_documents" "sync" { + content = data.flux_sync.main.content +} + +locals { + install = [for v in data.kubectl_file_documents.install.documents : { + data : yamldecode(v) + content : v + } + ] + sync = [for v in data.kubectl_file_documents.sync.documents : { + data : yamldecode(v) + content : v + } + ] +} + +resource "kubectl_manifest" "install" { + for_each = { for v in local.install : lower(join("/", compact([v.data.apiVersion, v.data.kind, lookup(v.data.metadata, "namespace", ""), v.data.metadata.name]))) => v.content } + depends_on = [kubernetes_namespace.flux_system] + yaml_body = each.value +} + +resource "kubectl_manifest" "sync" { + for_each = { for v in local.sync : lower(join("/", compact([v.data.apiVersion, v.data.kind, lookup(v.data.metadata, "namespace", ""), v.data.metadata.name]))) => v.content } + depends_on = [kubernetes_namespace.flux_system] + yaml_body = each.value +} + +resource "kubernetes_secret" "main" { + depends_on = [kubectl_manifest.install] + + metadata { + name = data.flux_sync.main.secret + namespace = data.flux_sync.main.namespace + } + + data = { + identity = tls_private_key.main.private_key_pem + "identity.pub" = tls_private_key.main.public_key_pem + known_hosts = local.known_hosts + } +} + +# GitHub +resource "github_repository" "main" { + name = var.repository_name + visibility = var.repository_visibility + auto_init = true +} + +resource "github_branch_default" "main" { + repository = github_repository.main.name + branch = var.branch +} + +resource "github_repository_deploy_key" "main" { + title = "staging-cluster" + repository = github_repository.main.name + key = tls_private_key.main.public_key_openssh + read_only = true +} + +resource "github_repository_file" "install" { + repository = github_repository.main.name + file = data.flux_install.main.path + content = data.flux_install.main.content + branch = var.branch +} + +resource "github_repository_file" "sync" { + repository = github_repository.main.name + file = data.flux_sync.main.path + content = data.flux_sync.main.content + branch = var.branch +} + +resource "github_repository_file" "kustomize" { + repository = github_repository.main.name + file = data.flux_sync.main.kustomize_path + content = data.flux_sync.main.kustomize_content + branch = var.branch +} diff --git a/k3s_cluster_v2/variables.tf b/k3s_cluster_v2/variables.tf index a0a8813..33841c8 100644 --- a/k3s_cluster_v2/variables.tf +++ b/k3s_cluster_v2/variables.tf @@ -54,4 +54,36 @@ variable "ssh_key" { variable "hcloud_ccm_token" { description = "HCloud API Token used by the hcloud-cloud-controller-manager" type = string + sensitive = true +} + +## Flux +variable "github_owner" { + type = string +} + +variable "github_token" { + type = string + sensitive = true +} + +variable "repository_name" { + type = string +} + +variable "branch" { + type = string +} + +variable "repository_visibility" { + type = string +} + +variable "flux_version" { + type = string +} + +variable "target_path" { + type = string + description = "Relative path to the Git repository root where Flux manifests are committed." } diff --git a/k3s_cluster_v2/versions.tf b/k3s_cluster_v2/versions.tf index b8e33b6..6ca23f3 100644 --- a/k3s_cluster_v2/versions.tf +++ b/k3s_cluster_v2/versions.tf @@ -18,5 +18,20 @@ terraform { null = { source = "hashicorp/null" } + + github = { + source = "integrations/github" + } + kubernetes = { + source = "hashicorp/kubernetes" + } + kubectl = { + source = "gavinbunney/kubectl" + version = ">= 1.10.0" + } + flux = { + source = "fluxcd/flux" + version = ">= 0.0.13" + } } } diff --git a/main.tf b/main.tf index 530c4b5..dab589f 100644 --- a/main.tf +++ b/main.tf @@ -38,6 +38,17 @@ module "k3s_cluster_v2" { ssh_key = file("~/.ssh/id_rsa.pub") hcloud_ccm_token = var.hcloud_ccm_token + ## Flux + github_owner = "apricote" + github_token = var.github_token + repository_name = "home-cloud-flux-v2" + branch = "main" + repository_visibility = "private" + target_path = "" + flux_version = "v0.24.0" + + + providers = { hcloud = hcloud } diff --git a/output.tf b/output.tf index 90a2ebf..b089aa9 100644 --- a/output.tf +++ b/output.tf @@ -1,7 +1,11 @@ -output cluster_public_ip { +output "cluster_public_ip" { value = module.k3s_cluster.server_public_ip } -output cluster_name { +output "cluster_name" { value = local.cluster_name } + +output "summary" { + value = module.k3s_cluster_v2.summary +} diff --git a/variables.tf b/variables.tf index 6790ffb..826f421 100644 --- a/variables.tf +++ b/variables.tf @@ -1,7 +1,14 @@ variable "hcloud_csi_driver_token" { - type = string + type = string + sensitive = true } variable "hcloud_ccm_token" { - type = string + type = string + sensitive = true +} + +variable "github_token" { + type = string + sensitive = true }