feat: ✨ add Homepage deployment module
commit
9db93bc348
@ -0,0 +1,259 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
kubernetes = {
|
||||
source = "hashicorp/kubernetes"
|
||||
version = "2.13.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
match_labels = {
|
||||
"app.kubernetes.io/instance" = "homepage"
|
||||
"app.kubernetes.io/name" = "homepage"
|
||||
}
|
||||
labels = merge({
|
||||
"app.kubernetes.io/version" = "v0.6.7"
|
||||
}, local.match_labels)
|
||||
}
|
||||
|
||||
resource "kubernetes_service_account" "homepage" {
|
||||
metadata {
|
||||
name = "homepage"
|
||||
namespace = var.namespace
|
||||
labels = local.labels
|
||||
}
|
||||
secret {
|
||||
name = "homepage-sa-token"
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_secret" "homepage" {
|
||||
type = "kuberneetes.io/service-account-token"
|
||||
metadata {
|
||||
name = "homepage"
|
||||
namespace = var.namespace
|
||||
labels = local.labels
|
||||
annotations = {
|
||||
"kubernetes.io/service-account.name" = kubernetes_service_account.homepage.metadata.0.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_secret" "homepage_sa_token" {
|
||||
type = "kuberneetes.io/service-account-token"
|
||||
metadata {
|
||||
name = "homepage-sa-token"
|
||||
namespace = var.namespace
|
||||
labels = local.labels
|
||||
annotations = {
|
||||
"kubernetes.io/service-account.name" = kubernetes_service_account.homepage.metadata.0.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_cluster_role" "homepage" {
|
||||
metadata {
|
||||
name = "homepage"
|
||||
labels = local.labels
|
||||
}
|
||||
rule {
|
||||
api_groups = [""]
|
||||
resources = ["namespaces", "pods", "nodes"]
|
||||
verbs = ["get", "list"]
|
||||
}
|
||||
rule {
|
||||
api_groups = ["extensions", "networking.k8s.io"]
|
||||
resources = ["ingresses"]
|
||||
verbs = ["get", "list"]
|
||||
}
|
||||
rule {
|
||||
api_groups = ["metrics.k8s.io"]
|
||||
resources = ["nodes", "pods"]
|
||||
verbs = ["get", "list"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_cluster_role_binding" "homepage" {
|
||||
metadata {
|
||||
name = "homepage"
|
||||
labels = local.labels
|
||||
}
|
||||
role_ref {
|
||||
api_group = "rbac.authorization.k8s.io"
|
||||
kind = "ClusterRole"
|
||||
name = kubernetes_cluster_role.homepage.metadata.0.name
|
||||
}
|
||||
subject {
|
||||
kind = "ServiceAccount"
|
||||
name = kubernetes_service_account.homepage.metadata.0.name
|
||||
namespace = var.namespace
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_deployment" "homepage" {
|
||||
metadata {
|
||||
name = "homepage"
|
||||
namespace = var.namespace
|
||||
labels = local.labels
|
||||
}
|
||||
|
||||
spec {
|
||||
replicas = 1
|
||||
|
||||
selector {
|
||||
match_labels = local.match_labels
|
||||
}
|
||||
|
||||
template {
|
||||
metadata {
|
||||
labels = local.labels
|
||||
annotations = {
|
||||
"ravianand.me/config-hash" = sha1(jsonencode(merge(
|
||||
kubernetes_config_map.homepage_config.data,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
service_account_name = kubernetes_service_account.homepage.metadata.0.name
|
||||
automount_service_account_token = true
|
||||
container {
|
||||
image = "ghcr.io/benphelps/homepage:latest"
|
||||
name = "homepage"
|
||||
port {
|
||||
container_port = 3000
|
||||
}
|
||||
volume_mount {
|
||||
name = "config"
|
||||
mount_path = "/app/config"
|
||||
}
|
||||
volume_mount {
|
||||
name = "logs"
|
||||
mount_path = "/app/config/logs"
|
||||
}
|
||||
dynamic "volume_mount" {
|
||||
for_each = toset(var.volumes)
|
||||
content {
|
||||
name = volume_mount.value.name
|
||||
mount_path = volume_mount.value.mount_path
|
||||
read_only = volume_mount.value.read_only
|
||||
}
|
||||
}
|
||||
liveness_probe {
|
||||
failure_threshold = 3
|
||||
initial_delay_seconds = 0
|
||||
period_seconds = 10
|
||||
tcp_socket {
|
||||
port = 3000
|
||||
}
|
||||
timeout_seconds = 1
|
||||
}
|
||||
readiness_probe {
|
||||
failure_threshold = 3
|
||||
initial_delay_seconds = 0
|
||||
period_seconds = 10
|
||||
tcp_socket {
|
||||
port = 3000
|
||||
}
|
||||
timeout_seconds = 1
|
||||
}
|
||||
startup_probe {
|
||||
failure_threshold = 30
|
||||
initial_delay_seconds = 0
|
||||
period_seconds = 5
|
||||
tcp_socket {
|
||||
port = 3000
|
||||
}
|
||||
timeout_seconds = 1
|
||||
}
|
||||
}
|
||||
volume {
|
||||
name = "config"
|
||||
config_map {
|
||||
name = kubernetes_config_map.homepage_config.metadata.0.name
|
||||
}
|
||||
}
|
||||
dynamic "volume" {
|
||||
for_each = toset(var.volumes)
|
||||
content {
|
||||
name = volume.value.name
|
||||
dynamic "persistent_volume_claim" {
|
||||
for_each = toset(volume.value.persistent_volume_claim != "" ? [volume.value.persistent_volume_claim] : [])
|
||||
content {
|
||||
claim_name = persistent_volume_claim.value
|
||||
}
|
||||
}
|
||||
dynamic "host_path" {
|
||||
for_each = toset(volume.value.host_path.path != "" ? [volume.value.host_path] : [])
|
||||
content {
|
||||
path = host_path.value.path
|
||||
type = host_path.value.type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
volume {
|
||||
name = "logs"
|
||||
empty_dir {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_service" "homepage" {
|
||||
metadata {
|
||||
name = "homepage"
|
||||
namespace = var.namespace
|
||||
}
|
||||
spec {
|
||||
type = "ClusterIP"
|
||||
selector = local.match_labels
|
||||
port {
|
||||
port = 3000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_ingress_v1" "homepage" {
|
||||
metadata {
|
||||
name = "homepage"
|
||||
namespace = var.namespace
|
||||
annotations = var.ingress_annotations
|
||||
}
|
||||
spec {
|
||||
rule {
|
||||
host = var.host
|
||||
http {
|
||||
path {
|
||||
path = "/"
|
||||
path_type = "Prefix"
|
||||
backend {
|
||||
service {
|
||||
name = kubernetes_service.homepage.metadata.0.name
|
||||
port {
|
||||
number = kubernetes_service.homepage.spec.0.port.0.port
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_config_map" "homepage_config" {
|
||||
metadata {
|
||||
name = "homepage-config"
|
||||
namespace = var.namespace
|
||||
}
|
||||
data = {
|
||||
"services.yaml" = yamlencode(var.services_config)
|
||||
"widgets.yaml" = yamlencode(var.widgets_config)
|
||||
"settings.yaml" = yamlencode(var.settings)
|
||||
"bookmarks.yaml" = yamlencode(var.bookmarks)
|
||||
"docker.yaml" = yamlencode(var.docker_config)
|
||||
"kubernetes.yaml" = yamlencode(var.kubernetes_config)
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
variable "host" {
|
||||
description = "Hostname for Hompeage"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "namespace" {
|
||||
description = "Namespace to deploy Homepage to"
|
||||
type = string
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "volumes" {
|
||||
description = "Additional volumes to mount to the pod, useful to display storage"
|
||||
type = list(object({
|
||||
name = string
|
||||
persistent_volume_claim = optional(string, "")
|
||||
host_path = optional(object({
|
||||
path = string
|
||||
type = optional(string, "Directory")
|
||||
}), { path = "", type = "Directory" })
|
||||
mount_path = string
|
||||
read_only = optional(bool, true)
|
||||
}))
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "ingress_annotations" {
|
||||
description = "Annotations to add to the Ingress"
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "services_config" {
|
||||
description = "Configuration file for services"
|
||||
type = list(
|
||||
map(
|
||||
list(
|
||||
map(
|
||||
object({
|
||||
icon = string
|
||||
href = optional(string)
|
||||
namespace = optional(string)
|
||||
app = optional(string)
|
||||
podSelector = optional(string, "")
|
||||
widget = optional(object({
|
||||
type = optional(string)
|
||||
url = optional(string)
|
||||
key = optional(string)
|
||||
username = optional(string)
|
||||
password = optional(string)
|
||||
}))
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "widgets_config" {
|
||||
description = "Configuration for widgets"
|
||||
type = list(map(object({
|
||||
// resources
|
||||
label = optional(string)
|
||||
cpu = optional(bool, false)
|
||||
memory = optional(bool, false)
|
||||
disk = optional(string)
|
||||
// datetime
|
||||
text_size = optional(string)
|
||||
format = optional(object({
|
||||
timeStyle = optional(string)
|
||||
hour12 = optional(bool, false)
|
||||
}))
|
||||
})))
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "settings" {
|
||||
description = "General Homepage settings"
|
||||
type = object({
|
||||
title = optional(string)
|
||||
base = optional(string)
|
||||
background = optional(string)
|
||||
backgroundOpacity = optional(string)
|
||||
theme = optional(string)
|
||||
layout = optional(map(
|
||||
object({
|
||||
icon = optional(string)
|
||||
style = optional(string)
|
||||
columns = optional(number)
|
||||
})
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
variable "bookmarks" {
|
||||
description = "Bookmarks to show in Homepage"
|
||||
type = list(map(any))
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "docker_config" {
|
||||
description = "Homepage Docker config (for reusability of configuration)"
|
||||
type = map(any)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "kubernetes_config" {
|
||||
description = "Kubernetes service config"
|
||||
type = object({
|
||||
mode = string
|
||||
})
|
||||
default = { mode = "cluster" }
|
||||
}
|
Loading…
Reference in New Issue