Skip to content

Commit

Permalink
tf(tmc-flux-tkgs-cluster): add module to deploy a cluster with a Flux…
Browse files Browse the repository at this point in the history
… Kustomization
  • Loading branch information
giovannibaratta committed Mar 5, 2024
1 parent 32e6f41 commit d1b2118
Show file tree
Hide file tree
Showing 5 changed files with 357 additions and 0 deletions.
134 changes: 134 additions & 0 deletions terraform/modules/tmc-flux-tkgs-cluster/cluster.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
locals {
# This is an arbitrary name
cluster_ca_secret_attribute_name = "trusted-ca"

inject_trusted_cas = var.cluster_additional_trusted_cas != null

cluster_variables = {
"controlPlaneCertificateRotation" : {
"activate" : true,
"daysBefore" : 30
},
"defaultStorageClass" : var.storage_class_name,
"defaultVolumeSnapshotClass" : var.storage_class_name,
"storageClass" : var.storage_class_name,
"storageClasses" : [
var.storage_class_name
],
"nodePoolVolumes" : [
{
"capacity" : {
"storage" : "50G"
},
"mountPath" : "/var/lib/containerd",
"name" : "containerd",
"storageClass" : var.storage_class_name
},
{
"capacity" : {
"storage" : "40G"
},
"mountPath" : "/var/lib/kubelet",
"name" : "kubelet",
"storageClass" : var.storage_class_name
}
]
"vmClass" : var.vm_class
}

cluster_trust_variables = local.inject_trusted_cas ? {
"trust" : {
additionalTrustedCAs : [
{
"name" : local.cluster_ca_secret_attribute_name
}
]
}
} : {}

full_cluster_variables = merge(local.cluster_variables, local.cluster_trust_variables)
}

resource "kubernetes_secret_v1" "cluster_trusted_ca" {
count = local.inject_trusted_cas ? 1 : 0
metadata {
name = "${var.cluster_name}-user-trusted-ca-secret"
namespace = var.cluster_namespace
}

data = {
(local.cluster_ca_secret_attribute_name) = base64encode(var.cluster_additional_trusted_cas)
}

type = "Opaque"
}

resource "tanzu-mission-control_tanzu_kubernetes_cluster" "cluster" {
name = var.cluster_name
management_cluster_name = var.managed_by
# vNS name in which the cluster must be created
provisioner_name = var.cluster_namespace

spec {
cluster_group_name = var.cluster_group

topology {
version = "v1.26.5+vmware.2-fips.1-tkg.1"
cluster_class = "tanzukubernetescluster"
cluster_variables = jsonencode(local.full_cluster_variables)

control_plane {
replicas = var.control_plane_replicas

os_image {
arch = "amd64"
name = "photon"
version = "3"
}
}

core_addon {
provider = "kapp-controller"
type = "kapp"
}

network {
pod_cidr_blocks = [
"172.20.0.0/16",
]
service_cidr_blocks = [
"10.96.0.0/16",
]
}

nodepool {
name = "md-0"

spec {
worker_class = "node-pool"
replicas = var.worker_nodes_replicas

os_image {
arch = "amd64"
name = "photon"
version = "3"
}
}
}
}
}

timeout_policy {
timeout = 60
wait_for_kubeconfig = false
fail_on_timeout = true
}

depends_on = [kubernetes_secret_v1.cluster_trusted_ca]

lifecycle {
# TMC inject automatically an additional value in additionalTrustedCAs generating a perma-diff.
# I still need to find a workaround
ignore_changes = [ spec ]
}
}
119 changes: 119 additions & 0 deletions terraform/modules/tmc-flux-tkgs-cluster/gitops.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# The default package repository installed by TMC does not work and can not be reconciled, hence
# we need a working package repository to install FluxCD dependencies. We need to enable it cluster
# by cluster since the resource is not supported yet at the cluster group level
resource "tanzu-mission-control_package_repository" "tanzu_standard" {
name = "tanzu-standard-repo"

scope {
cluster {
name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.name
provisioner_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.provisioner_name
management_cluster_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.management_cluster_name
}
}

spec {
imgpkg_bundle {
image = "projects.registry.vmware.com/tkg/packages/standard/repo:v2.2.0"
}
}

depends_on = [tanzu-mission-control_tanzu_kubernetes_cluster.cluster]
}

locals {
git_requires_credentials = var.git_repo_credentials != null
}

# Credentials of the the repositories where Flux Kustomizations are hosted
resource "tanzu-mission-control_repository_credential" "cluster_configuration" {
count = local.git_requires_credentials ? 1 : 0
name = "cluster-configuration"

scope {
cluster {
name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.name
provisioner_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.provisioner_name
management_cluster_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.management_cluster_name
}
}

spec {
data {

dynamic "username_password" {
for_each = var.git_repo_credentials.type == "user_pass" ? [var.git_repo_credentials.user_pass] : []

content {
username = username_password.value.username
password = username_password.value.password
}
}

dynamic "ssh_key" {
for_each = var.git_repo_credentials.type == "ssh" ? [var.git_repo_credentials.ssh] : []

content {
identity = ssh_key.value.identity
known_hosts = ssh_key.value.known_hosts
}
}
}
}
}

resource "tanzu-mission-control_git_repository" "cluster_configuration" {
name = "cluster-configuration"

# The namespace must exists in the target cluster
namespace_name = "tanzu-continuousdelivery-resources"

scope {
cluster {
name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.name
provisioner_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.provisioner_name
management_cluster_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.management_cluster_name
}
}

spec {
url = var.git_repo_url
secret_ref = local.git_requires_credentials ? tanzu-mission-control_repository_credential.cluster_configuration[0].name : null
interval = "60s"
git_implementation = "GO_GIT"
ref {
branch = var.git_branch
}
}

depends_on = [ tanzu-mission-control_repository_credential.cluster_configuration ]
}

resource "tanzu-mission-control_kustomization" "cluster_configuration" {
name = "cluster-configuration"

# The namespace must exists in the target cluster
namespace_name = "tanzu-continuousdelivery-resources"

scope {
cluster {
name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.name
provisioner_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.provisioner_name
management_cluster_name = tanzu-mission-control_tanzu_kubernetes_cluster.cluster.management_cluster_name
}
}

spec {
# Path in the Git repository. The folder must contain a kustomization.yaml file
path = var.cluster_overlay_path
prune = true
interval = "60s"

source {
name = tanzu-mission-control_git_repository.cluster_configuration.name
namespace = tanzu-mission-control_git_repository.cluster_configuration.namespace_name
}
}

depends_on = [ tanzu-mission-control_git_repository.cluster_configuration ]
}
91 changes: 91 additions & 0 deletions terraform/modules/tmc-flux-tkgs-cluster/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
variable "cluster_name" {
type = string
}

variable "cluster_namespace" {
type = string
}

variable "vm_class" {
type = string
}

variable "storage_class_name" {
type = string
}

variable "cluster_group" {
type = string
default = null
nullable = true
}

variable "managed_by" {
description = "Name of the supervisor cluster that will manage the cluster"
type = string
}

variable "worker_nodes_replicas" {
type = number
default = 3
}

variable "control_plane_replicas" {
type = number
default = 1
}

variable "cluster_additional_trusted_cas" {
type = string
default = null
nullable = true
}

variable "git_repo_credentials" {
type = object({
type = string
ssh = optional(object({
identity = string
known_hosts = string
}))
user_pass = optional(object({
username = string
password = string
}))
})

sensitive = true
nullable = true
default = null

validation {
condition = var.git_repo_credentials == null || try(contains(["ssh", "user_pass"], var.git_repo_credentials.type), false)
error_message = "supported values for type are 'ssh' or 'user_pass'"
}

validation {
condition = var.git_repo_credentials == null || try(var.git_repo_credentials.type != "ssh" || var.git_repo_credentials.ssh != null, false)
error_message = "If type is 'ssh' the 'ssh' object must be set"
}

validation {
condition = var.git_repo_credentials == null || try(var.git_repo_credentials.type != "user_pass" || var.git_repo_credentials.user_pass != null, false)
error_message = "If type is 'ssh' the 'ssh' object must be set"
}
}

variable "git_repo_url" {
type = string
description = "The URL should not include https and there shouldn't be any trailing /"
}

variable "git_branch" {
type = string
description = "The URL should not include https and there shouldn't be any trailing /"
default = "main"
}

variable "cluster_overlay_path" {
type = string
description = "Path in the Git repo that contains the kustomization.yaml file for the cluster"
}
1 change: 1 addition & 0 deletions terraform/modules/tmc-flux-tkgs-cluster/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.1
12 changes: 12 additions & 0 deletions terraform/modules/tmc-flux-tkgs-cluster/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
terraform {
required_providers {
tanzu-mission-control = {
source = "vmware/tanzu-mission-control"
version = "~> 1.4.3"
}

kubernetes = {
source = "hashicorp/kubernetes"
}
}
}

0 comments on commit d1b2118

Please sign in to comment.