this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add local cluster

Khue Doan 7796870a 790763a8

+351 -11
+1 -1
.gitignore
··· 1 1 *.tgz 2 2 *.tfvars 3 - .terraform* 3 + .terragrunt* 4 4 Chart.lock 5 5 kubeconfig.yaml 6 6 private.pem
+3
Makefile
··· 48 48 cd test/e2e && go test 49 49 50 50 fmt: 51 + yamlfmt . 52 + terragrunt hcl format 53 + tofu fmt -recursive 51 54 cd test/e2e && go fmt ./... 52 55 53 56 update:
+4 -4
flake.lock
··· 20 20 }, 21 21 "nixpkgs": { 22 22 "locked": { 23 - "lastModified": 1745868005, 24 - "narHash": "sha256-hZScOyQphT4RUmSEJX+2OxjIlGgLwSd8iW1LNtAWIOs=", 23 + "lastModified": 1748162331, 24 + "narHash": "sha256-rqc2RKYTxP3tbjA+PB3VMRQNnjesrT0pEofXQTrMsS8=", 25 25 "owner": "NixOS", 26 26 "repo": "nixpkgs", 27 - "rev": "330d0a4167924b43f31cc9406df363f71b768a02", 27 + "rev": "7c43f080a7f28b2774f3b3f43234ca11661bf334", 28 28 "type": "github" 29 29 }, 30 30 "original": { 31 31 "owner": "NixOS", 32 - "ref": "nixos-24.11", 32 + "ref": "nixos-25.05", 33 33 "repo": "nixpkgs", 34 34 "type": "github" 35 35 }
+4 -6
flake.nix
··· 1 1 { 2 2 inputs = { 3 - nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; 3 + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; 4 4 flake-utils.url = "github:numtide/flake-utils"; 5 5 }; 6 6 ··· 12 12 packages = [ 13 13 ansible 14 14 ansible-lint 15 - cue 16 - git 17 15 gnumake 18 16 go 19 - k9s 17 + k3d 20 18 kubectl 21 - neovim 22 19 openssh 23 20 opentofu 24 21 pre-commit 25 22 shellcheck 26 - timoni 23 + terragrunt 27 24 wireguard-tools 25 + yamlfmt 28 26 yamllint 29 27 30 28 (python3.withPackages (p: with p; [
+42
infra/local/bootstrap/.terraform.lock.hcl
··· 1 + # This file is maintained automatically by "tofu init". 2 + # Manual edits may be lost in future updates. 3 + 4 + provider "registry.opentofu.org/alekc/kubectl" { 5 + version = "2.1.3" 6 + constraints = "~> 2.0" 7 + hashes = [ 8 + "h1:poWSAAtK4FI1x79C2OyLaNrvWUGTQdr1ZT58edDz+Rs=", 9 + "zh:0e601ae36ebc32eb8c10aff4c48c1125e471fa09f5668465af7581c9057fa22c", 10 + "zh:1773f08a412d1a5f89bac174fe1efdfd255ecdda92d31a2e31937e4abf843a2f", 11 + "zh:1da2db1f940c5d34e31c2384c7bd7acba68725cc1d3ba6db0fec42efe80dbfb7", 12 + "zh:20dc810fb09031bcfea4f276e1311e8286d8d55705f55433598418b7bcc76357", 13 + "zh:326a01c86ba90f6c6eb121bacaabb85cfa9059d6587aea935a9bbb6d3d8e3f3f", 14 + "zh:5a3737ea1e08421fe3e700dc833c6fd2c7b8c3f32f5444e844b3fe0c2352757b", 15 + "zh:5f490acbd0348faefea273cb358db24e684cbdcac07c71002ee26b6cfd2c54a0", 16 + "zh:777688cda955213ba637e2ac6b1994e438a5af4d127a34ecb9bb010a8254f8a8", 17 + "zh:7acc32371053592f55ee0bcbbc2f696a8466415dea7f4bc5a6573f03953fc926", 18 + "zh:81f0108e2efe5ae71e651a8826b61d0ce6918811ccfdc0e5b81b2cfb0f7f57fe", 19 + "zh:88b785ea7185720cf40679cb8fa17e57b8b07fd6322cf2d4000b835282033d81", 20 + "zh:89d833336b5cd027e671b46f9c5bc7d10c5109e95297639bbec8001da89aa2f7", 21 + "zh:df108339a89d4372e5b13f77bd9d53c02a04362fb5d85e1d9b6b47292e30821c", 22 + "zh:e8a2e3a5c50ca124e6014c361d72a9940d8e815f37ae2d1e9487ac77c3043013", 23 + ] 24 + } 25 + 26 + provider "registry.opentofu.org/hashicorp/helm" { 27 + version = "2.17.0" 28 + constraints = "~> 2.17" 29 + hashes = [ 30 + "h1:ShIag7wqd5Rs+zYpVMpjAh+T0ozr4XGYfSTKWqceQBY=", 31 + "zh:02690815e35131a42cb9851f63a3369c216af30ad093d05b39001d43da04b56b", 32 + "zh:27a62f12b29926387f4d71aeeee9f7ffa0ccb81a1b6066ee895716ad050d1b7a", 33 + "zh:2d0a5babfa73604b3fefc9dab9c87f91c77fce756c2e32b294e9f1290aed26c0", 34 + "zh:3976400ceba6dda4636e1d297e3097e1831de5628afa534a166de98a70d1dcbe", 35 + "zh:54440ef14f342b41d75c1aded7487bfcc3f76322b75894235b47b7e89ac4bfa4", 36 + "zh:6512e2ab9f2fa31cbb90d9249647b5c5798f62eb1215ec44da2cdaa24e38ad25", 37 + "zh:795f327ca0b8c5368af0ed03d5d4f6da7260692b4b3ca0bd004ed542e683464d", 38 + "zh:ba659e1d94f224bc3f1fd34cbb9d2663e3a8e734108e5a58eb49eda84b140978", 39 + "zh:c5c8575c4458835c2acbc3d1ed5570589b14baa2525d8fbd04295c097caf41eb", 40 + "zh:e0877a5dac3de138e61eefa26b2f5a13305a17259779465899880f70e11314e0", 41 + ] 42 + }
+17
infra/local/bootstrap/terragrunt.hcl
··· 1 + terraform { 2 + source = "../../modules/local-bootstrap" 3 + } 4 + 5 + dependency "cluster" { 6 + config_path = "../cluster" 7 + } 8 + 9 + inputs = { 10 + cluster = dependency.cluster.outputs.name 11 + credentials = { 12 + host = dependency.cluster.outputs.credentials.host 13 + client_certificate = dependency.cluster.outputs.credentials.client_certificate 14 + client_key = dependency.cluster.outputs.credentials.client_key 15 + cluster_ca_certificate = dependency.cluster.outputs.credentials.cluster_ca_certificate 16 + } 17 + }
+20
infra/local/cluster/.terraform.lock.hcl
··· 1 + # This file is maintained automatically by "tofu init". 2 + # Manual edits may be lost in future updates. 3 + 4 + provider "registry.opentofu.org/moio/k3d" { 5 + version = "0.0.12" 6 + constraints = "0.0.12" 7 + hashes = [ 8 + "h1:Z20ggDhtPcOdAh5e94Kc+Sq7NkeHwQRKx4Llb7gUT+o=", 9 + "zh:57cce978c77dc5505d902e3ba3b1ea61d85db82465a232c71f4821052cd81246", 10 + "zh:8a703d08584e2f53aa2492944e1eae1c432617a060529151d3dfb57c99343250", 11 + "zh:90d76a028be359065bcd295ec591c6a05df531dd2d7d035f4ab8f23e7d83df2a", 12 + "zh:95c6ada0330f8a8223a15da7fb5323baa3aa896767e82c28f3efb6ee535a466a", 13 + "zh:96fbcb99af31a4896faef727e6afcfd6200bafcd8191a7ca57eb96501b39c68b", 14 + "zh:a553d39f4ad61917bbd82e397b31c5954b2541534d434e44b65690e90cffadf2", 15 + "zh:b415fb3df2c93a9dd1a32bb960b940ff7f19adf14281897ce81c379b2a89dcf7", 16 + "zh:ba0df82380747d28b7c1258b83843d395cd3dafa0d2fa89b59f3e6029d696d91", 17 + "zh:d6a5278803a46db826fb0719c0bd059f3e20c8ff08d0463c161f5b680556dae6", 18 + "zh:df16acef3aacfce57505942f4f1cf8ad30e1be43bc0df60666f134a06a1275af", 19 + ] 20 + }
+7
infra/local/cluster/terragrunt.hcl
··· 1 + terraform { 2 + source = "../../modules/local-cluster" 3 + } 4 + 5 + inputs = { 6 + name = "cloudlab" 7 + }
+49
infra/modules/local-bootstrap/argocd.tf
··· 1 + resource "helm_release" "argocd" { 2 + name = "argocd" 3 + namespace = "argocd" 4 + create_namespace = true 5 + repository = "https://argoproj.github.io/argo-helm" 6 + chart = "argo-cd" 7 + version = "8.0.6" 8 + timeout = 60 * 10 9 + 10 + values = [ 11 + yamlencode({ 12 + global = { 13 + domain = "argocd.127-0-0-1.nip.io" 14 + } 15 + configs = { 16 + params = { 17 + "server.insecure" = true 18 + "controller.diff.server.side" = true 19 + } 20 + cm = { 21 + "timeout.reconciliation.jitter" = "60s" 22 + "resource.ignoreResourceUpdatesEnabled" = true 23 + "resource.customizations.ignoreResourceUpdates.all" = yamlencode({ 24 + jsonPointers : [ 25 + "/status" 26 + ] 27 + }) 28 + "users.anonymous.enabled" = true 29 + } 30 + rbac = { 31 + "policy.default" = "role:admin" 32 + } 33 + } 34 + server = { 35 + ingress = { 36 + enabled = true 37 + ingressClassName = "nginx" 38 + tls = false 39 + } 40 + } 41 + repoServer = { 42 + hostNetwork = true 43 + } 44 + dex = { 45 + enabled = false 46 + } 47 + }) 48 + ] 49 + }
+38
infra/modules/local-bootstrap/ingress_nginx.tf
··· 1 + resource "kubectl_manifest" "ingress_nginx" { 2 + server_side_apply = true 3 + yaml_body = yamlencode({ 4 + apiVersion = "argoproj.io/v1alpha1" 5 + kind = "Application" 6 + metadata = { 7 + name = "ingress-nginx" 8 + namespace = helm_release.argocd.namespace 9 + finalizers = ["resources-finalizer.argocd.argoproj.io"] 10 + } 11 + spec = { 12 + project = "default" 13 + destination = { 14 + name = "in-cluster" 15 + namespace = "monitoring" 16 + } 17 + syncPolicy = local.sync_policy 18 + source = { 19 + repoURL = "https://kubernetes.github.io/ingress-nginx" 20 + chart = "ingress-nginx" 21 + targetRevision = "4.11.2" 22 + helm = { 23 + valuesObject = { 24 + controller : { 25 + podLabels : { 26 + "istio.io/dataplane-mode" : "ambient" 27 + } 28 + admissionWebhooks : { 29 + timeoutSeconds : 30 30 + } 31 + } 32 + 33 + } 34 + } 35 + } 36 + } 37 + }) 38 + }
+13
infra/modules/local-bootstrap/locals.tf
··· 1 + locals { 2 + sync_policy = { 3 + automated = { 4 + prune = true 5 + selfHeal = true 6 + } 7 + syncOptions = [ 8 + "CreateNamespace=true", 9 + "ApplyOutOfSyncOnly=true", 10 + "ServerSideApply=true" 11 + ] 12 + } 13 + }
+35
infra/modules/local-bootstrap/loki.tf
··· 1 + resource "kubectl_manifest" "loki" { 2 + server_side_apply = true 3 + yaml_body = yamlencode({ 4 + apiVersion = "argoproj.io/v1alpha1" 5 + kind = "Application" 6 + metadata = { 7 + name = "loki" 8 + namespace = helm_release.argocd.namespace 9 + finalizers = ["resources-finalizer.argocd.argoproj.io"] 10 + } 11 + spec = { 12 + project = "default" 13 + destination = { 14 + name = "in-cluster" 15 + namespace = "monitoring" 16 + } 17 + syncPolicy = local.sync_policy 18 + source = { 19 + repoURL = "https://grafana.github.io/helm-charts" 20 + chart = "loki-stack" 21 + targetRevision = "2.10.2" 22 + helm = { 23 + valuesObject = { 24 + loki = { 25 + isDefault = false 26 + } 27 + serviceMonitor = { 28 + enabled = true 29 + } 30 + } 31 + } 32 + } 33 + } 34 + }) 35 + }
+17
infra/modules/local-bootstrap/variables.tf
··· 1 + variable "cluster" { 2 + type = string 3 + } 4 + 5 + variable "credentials" { 6 + type = object({ 7 + client_certificate = string 8 + client_key = string 9 + cluster_ca_certificate = string 10 + host = string 11 + }) 12 + } 13 + 14 + variable "cluster_domain" { 15 + type = string 16 + default = "127-0-0-1.nip.io" 17 + }
+30
infra/modules/local-bootstrap/versions.tf
··· 1 + terraform { 2 + required_version = "~> 1.8" 3 + 4 + required_providers { 5 + helm = { 6 + source = "hashicorp/helm" 7 + version = "~> 2.17" 8 + } 9 + kubectl = { 10 + source = "alekc/kubectl" 11 + version = "~> 2.0" 12 + } 13 + } 14 + } 15 + 16 + provider "helm" { 17 + kubernetes { 18 + host = var.credentials.host 19 + client_certificate = var.credentials.client_certificate 20 + client_key = var.credentials.client_key 21 + cluster_ca_certificate = var.credentials.cluster_ca_certificate 22 + } 23 + } 24 + 25 + provider "kubectl" { 26 + host = var.credentials.host 27 + client_certificate = var.credentials.client_certificate 28 + client_key = var.credentials.client_key 29 + cluster_ca_certificate = var.credentials.cluster_ca_certificate 30 + }
+52
infra/modules/local-cluster/main.tf
··· 1 + resource "k3d_cluster" "this" { 2 + name = var.name 3 + image = "docker.io/rancher/k3s:v1.30.2-k3s2" 4 + 5 + # See the comments in the mirrors below before deciding to increase the node count 6 + servers = 1 7 + agents = 0 8 + 9 + k3s { 10 + extra_args { 11 + arg = "--disable=traefik" 12 + node_filters = ["server:*"] 13 + } 14 + 15 + extra_args { 16 + arg = "--disable-helm-controller" 17 + node_filters = ["server:*"] 18 + } 19 + } 20 + 21 + port { 22 + host_port = 80 23 + container_port = 80 24 + node_filters = [ 25 + "loadbalancer", 26 + ] 27 + } 28 + 29 + port { 30 + host_port = 443 31 + container_port = 443 32 + node_filters = [ 33 + "loadbalancer", 34 + ] 35 + } 36 + 37 + registries { 38 + config = yamlencode({ 39 + mirrors = { 40 + # Pretent that this registry is external, but it's actually on the same 41 + # node. That means this development cluster can only have 1 node unless 42 + # we have RWX and use a DaemonSet for the in-cluster registry. 43 + # See also the nodePort in ../../system/registry.yaml 44 + "registry.127-0-0-1.nip.io" = { 45 + endpoint = [ 46 + "http://localhost:30000" 47 + ] 48 + } 49 + } 50 + }) 51 + } 52 + }
+8
infra/modules/local-cluster/outputs.tf
··· 1 + output "name" { 2 + value = var.name 3 + } 4 + 5 + output "credentials" { 6 + value = k3d_cluster.this.credentials[0] 7 + sensitive = true 8 + }
+8
infra/modules/local-cluster/terraform.tf
··· 1 + terraform { 2 + required_providers { 3 + k3d = { 4 + source = "moio/k3d" 5 + version = "0.0.12" 6 + } 7 + } 8 + }
+3
infra/modules/local-cluster/variables.tf
··· 1 + variable "name" { 2 + type = string 3 + }