feat: add Homepage deployment module

main
RaviAnand Mohabir 2 years ago
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…
Cancel
Save