diff --git a/README.md b/README.md index 7d158d7..1c83958 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,5 @@ Hodgepodge of Terraform modules. * K8S * Get Join (Get join config from Kuberenetes control plane) + * K8s-At-Home (Deploy a chart from the k8s-at-home helm repo) + * Traefik Ingress (Creats Ingress CRDs for host based routing) diff --git a/modules/k8s/k8s-at-home/main.tf b/modules/k8s/k8s-at-home/main.tf new file mode 100644 index 0000000..87c85dd --- /dev/null +++ b/modules/k8s/k8s-at-home/main.tf @@ -0,0 +1,33 @@ +resource "kubernetes_namespace" "namespace" { + count = var.create_namespace ? 1 : 0 + metadata { + name = var.namespace + } +} + +locals { + values = yamlencode( + merge(tomap({ + env = merge({ + TZ = var.timezone, + }, var.helm_envs) + }), + var.helm_values, + )) +} + +resource "helm_release" "k8s" { + repository = "https://k8s-at-home.com/charts/" + name = var.name + chart = var.chart + version = var.chart_version + namespace = var.namespace + + values = [ + local.values, + ] + + depends_on = [ + kubernetes_namespace.namespace, + ] +} diff --git a/modules/k8s/k8s-at-home/variables.tf b/modules/k8s/k8s-at-home/variables.tf new file mode 100644 index 0000000..5427183 --- /dev/null +++ b/modules/k8s/k8s-at-home/variables.tf @@ -0,0 +1,44 @@ +variable "chart_version" { + description = "The version of the helm chart to use. Note that this is different from the app/container version." + type = string +} + +variable "create_namespace" { + description = "Create namespace or deploy to existing." + type = bool + default = true +} + +variable "namespace" { + description = "Which Kubernetes Namespace to deploy the chart into." + type = string + default = "default" +} + +variable "name" { + description = "Name of chart deployment." + type = string +} + +variable "chart" { + description = "Name of k8s-at-home chart." + type = string +} + +variable "timezone" { + description = "Timezone for the service." + type = string + default = "US/Pacific" +} + +variable "helm_envs" { + description = "Map of envs for helm chart. Merged with timezone." + type = any + default = {} +} + +variable "helm_values" { + description = "Additional helm values to pass in as a map. Timezone will be included already." + type = any + default = {} +} diff --git a/modules/k8s/k8s-at-home/versions.tf b/modules/k8s/k8s-at-home/versions.tf new file mode 100644 index 0000000..ee171a9 --- /dev/null +++ b/modules/k8s/k8s-at-home/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 1.0" + } + helm = { + source = "hashicorp/helm" + version = "~> 2.0" + } + aws = { + source = "hashicorp/aws" + version = "~> 3.0" + } + } +} diff --git a/modules/k8s/traefik-ingress/main.tf b/modules/k8s/traefik-ingress/main.tf new file mode 100644 index 0000000..913c8eb --- /dev/null +++ b/modules/k8s/traefik-ingress/main.tf @@ -0,0 +1,30 @@ +resource "helm_release" "k8s" { + name = "${var.name}-traefik-ingress" + chart = "${path.module}/traefik-ingress" + namespace = var.namespace + + set { + name = "namespace" + value = var.namespace + } + set { + name = "name" + value = var.name + } + set { + name = "certResolver" + value = var.cert_resolver + } + set { + name = "host" + value = var.host + } + set { + name = "serviceName" + value = var.service + } + set { + name = "servicePort" + value = var.service_port + } +} diff --git a/modules/k8s/traefik-ingress/traefik-ingress/.helmignore b/modules/k8s/traefik-ingress/traefik-ingress/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/modules/k8s/traefik-ingress/traefik-ingress/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/modules/k8s/traefik-ingress/traefik-ingress/Chart.yaml b/modules/k8s/traefik-ingress/traefik-ingress/Chart.yaml new file mode 100644 index 0000000..2907434 --- /dev/null +++ b/modules/k8s/traefik-ingress/traefik-ingress/Chart.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v2 +name: traefik-ingress +description: A Helm chart for Kubernetes +type: application +version: 0.0.4 +appVersion: "2.6.0" diff --git a/modules/k8s/traefik-ingress/traefik-ingress/templates/_helpers.tpl b/modules/k8s/traefik-ingress/traefik-ingress/templates/_helpers.tpl new file mode 100644 index 0000000..2ffcbec --- /dev/null +++ b/modules/k8s/traefik-ingress/traefik-ingress/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "traefik-ingress.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "traefik-ingress.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "traefik-ingress.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/modules/k8s/traefik-ingress/traefik-ingress/templates/ingress.yml b/modules/k8s/traefik-ingress/traefik-ingress/templates/ingress.yml new file mode 100644 index 0000000..80b4339 --- /dev/null +++ b/modules/k8s/traefik-ingress/traefik-ingress/templates/ingress.yml @@ -0,0 +1,10 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Values.name }} + annotations: + kubernetes.io/ingress.class: traefik +spec: + rules: + - host: {{ .Values.host }} diff --git a/modules/k8s/traefik-ingress/traefik-ingress/templates/ingressroute.yaml b/modules/k8s/traefik-ingress/traefik-ingress/templates/ingressroute.yaml new file mode 100644 index 0000000..669517d --- /dev/null +++ b/modules/k8s/traefik-ingress/traefik-ingress/templates/ingressroute.yaml @@ -0,0 +1,17 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: {{ .Values.name }} +spec: + entryPoints: + - websecure + tls: + certResolver: {{ .Values.certResolver }} + routes: + - match: Host(`{{ .Values.host }}`) + kind: Rule + services: + - name: {{ .Values.serviceName }} + kind: Service + namespace: {{ .Values.namespace }} + port: {{ .Values.servicePort }} diff --git a/modules/k8s/traefik-ingress/variables.tf b/modules/k8s/traefik-ingress/variables.tf new file mode 100644 index 0000000..811d89b --- /dev/null +++ b/modules/k8s/traefik-ingress/variables.tf @@ -0,0 +1,30 @@ +variable "namespace" { + description = "Which Kubernetes Namespace to deploy the traefik ingress CRDs into." + type = string + default = "default" +} + +variable "name" { + description = "Name to use for Traefik ingress release. Must be unique per namespace." + type = string +} + +variable "host" { + description = "Traefik host match." + type = string +} + +variable "cert_resolver" { + description = "Name of cert resolver to use to generate TLS cert for this hostname." + type = string +} + +variable "service" { + description = "Kubernetes service name to route host match rule to." + type = string +} + +variable "service_port" { + description = "Kubernetes service port to route to." + type = number +} diff --git a/modules/k8s/traefik-ingress/versions.tf b/modules/k8s/traefik-ingress/versions.tf new file mode 100644 index 0000000..ee171a9 --- /dev/null +++ b/modules/k8s/traefik-ingress/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 1.0" + } + helm = { + source = "hashicorp/helm" + version = "~> 2.0" + } + aws = { + source = "hashicorp/aws" + version = "~> 3.0" + } + } +}