Support for Kubernetes via Terraform and Manifests (#5721)
# Support for Kubernetes via Terraform and Manifests Adding basic support for the following Kubernetes resources - persistent volume - server - database - persistent volume claim - server - database - deployment - server - database - ingress - server - service - server - database - secret - server --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
90
packages/twenty-docker/k8s/terraform/deployment-db.tf
Normal file
90
packages/twenty-docker/k8s/terraform/deployment-db.tf
Normal file
@ -0,0 +1,90 @@
|
||||
resource "kubernetes_deployment" "twentycrm_db" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-db"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
labels = {
|
||||
app = "${local.twentycrm_app_name}-db"
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
replicas = 1
|
||||
selector {
|
||||
match_labels = {
|
||||
app = "${local.twentycrm_app_name}-db"
|
||||
}
|
||||
}
|
||||
|
||||
strategy {
|
||||
type = "RollingUpdate"
|
||||
rolling_update {
|
||||
max_surge = "1"
|
||||
max_unavailable = "1"
|
||||
}
|
||||
}
|
||||
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "${local.twentycrm_app_name}-db"
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
# security_context {
|
||||
# fs_group = 0
|
||||
# }
|
||||
container {
|
||||
image = local.twentycrm_db_image
|
||||
name = local.twentycrm_app_name
|
||||
stdin = true
|
||||
tty = true
|
||||
security_context {
|
||||
allow_privilege_escalation = true
|
||||
}
|
||||
|
||||
env {
|
||||
name = "POSTGRES_PASSWORD"
|
||||
value = "twenty"
|
||||
}
|
||||
env {
|
||||
name = "BITNAMI_DEBUG"
|
||||
value = true
|
||||
}
|
||||
|
||||
port {
|
||||
container_port = 5432
|
||||
protocol = "TCP"
|
||||
}
|
||||
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "250m"
|
||||
memory = "256Mi"
|
||||
}
|
||||
limits = {
|
||||
cpu = "1000m"
|
||||
memory = "1024Mi"
|
||||
}
|
||||
}
|
||||
|
||||
volume_mount {
|
||||
name = "nfs-twentycrm-db-data"
|
||||
mount_path = "/bitnami/postgresql"
|
||||
}
|
||||
}
|
||||
|
||||
volume {
|
||||
name = "nfs-twentycrm-db-data"
|
||||
|
||||
persistent_volume_claim {
|
||||
claim_name = "nfs-twentycrm-db-data-pvc"
|
||||
}
|
||||
}
|
||||
|
||||
dns_policy = "ClusterFirst"
|
||||
restart_policy = "Always"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
169
packages/twenty-docker/k8s/terraform/deployment-server.tf
Normal file
169
packages/twenty-docker/k8s/terraform/deployment-server.tf
Normal file
@ -0,0 +1,169 @@
|
||||
resource "kubernetes_deployment" "twentycrm_server" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-server"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
labels = {
|
||||
app = "${local.twentycrm_app_name}-server"
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
replicas = 1
|
||||
selector {
|
||||
match_labels = {
|
||||
app = "${local.twentycrm_app_name}-server"
|
||||
}
|
||||
}
|
||||
|
||||
strategy {
|
||||
type = "RollingUpdate"
|
||||
rolling_update {
|
||||
max_surge = "1"
|
||||
max_unavailable = "1"
|
||||
}
|
||||
}
|
||||
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "${local.twentycrm_app_name}-server"
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
container {
|
||||
image = local.twentycrm_server_image
|
||||
name = local.twentycrm_app_name
|
||||
stdin = true
|
||||
tty = true
|
||||
|
||||
security_context {
|
||||
allow_privilege_escalation = true
|
||||
privileged = true
|
||||
run_as_user = 1000
|
||||
}
|
||||
|
||||
env {
|
||||
name = "PORT"
|
||||
value = "3000"
|
||||
}
|
||||
env {
|
||||
name = "DEBUG_MODE"
|
||||
value = false
|
||||
}
|
||||
|
||||
env {
|
||||
name = "SERVER_URL"
|
||||
value = "https://crm.example.com:443"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "FRONT_BASE_URL"
|
||||
value = "https://crm.example.com:443"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "BACKEND_SERVER_URL"
|
||||
value = "https://crm.example.com:443"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "PG_DATABASE_URL"
|
||||
value = "postgres://twenty:twenty@twentycrm-db.twentycrm.svc.cluster.local/default"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "ENABLE_DB_MIGRATIONS"
|
||||
value = "true"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "SIGN_IN_PREFILLED"
|
||||
value = "true"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "STORAGE_TYPE"
|
||||
value = "local"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "ACCESS_TOKEN_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tokens"
|
||||
key = "accessToken"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
env {
|
||||
name = "LOGIN_TOKEN_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tokens"
|
||||
key = "loginToken"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
env {
|
||||
name = "REFRESH_TOKEN_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tokens"
|
||||
key = "refreshToken"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
env {
|
||||
name = "FILE_TOKEN_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tokens"
|
||||
key = "fileToken"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
port {
|
||||
container_port = 3000
|
||||
protocol = "TCP"
|
||||
}
|
||||
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "250m"
|
||||
memory = "256Mi"
|
||||
}
|
||||
limits = {
|
||||
cpu = "1000m"
|
||||
memory = "1024Mi"
|
||||
}
|
||||
}
|
||||
|
||||
volume_mount {
|
||||
name = "nfs-twentycrm-server-data"
|
||||
mount_path = "/app/.local-storage"
|
||||
}
|
||||
}
|
||||
|
||||
volume {
|
||||
name = "nfs-twentycrm-server-data"
|
||||
|
||||
persistent_volume_claim {
|
||||
claim_name = "nfs-twentycrm-server-data-pvc"
|
||||
}
|
||||
}
|
||||
|
||||
dns_policy = "ClusterFirst"
|
||||
restart_policy = "Always"
|
||||
}
|
||||
}
|
||||
}
|
||||
depends_on = [
|
||||
kubernetes_deployment.twentycrm_db,
|
||||
kubernetes_secret.twentycrm_tokens
|
||||
]
|
||||
}
|
||||
30
packages/twenty-docker/k8s/terraform/ingress.tf
Normal file
30
packages/twenty-docker/k8s/terraform/ingress.tf
Normal file
@ -0,0 +1,30 @@
|
||||
resource "kubernetes_ingress" "twentycrm" {
|
||||
wait_for_load_balancer = true
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-ingress"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
annotations = {
|
||||
"kubernetes.io/ingress.class" = "nginx"
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet" = <<EOF
|
||||
more_set_headers "X-Forwarded-For $http_x_forwarded_for";
|
||||
EOF
|
||||
"nginx.ingress.kubernetes.io/force-ssl-redirect" = "false"
|
||||
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTP"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
ingress_class_name = "nginx"
|
||||
rule {
|
||||
host = local.twentycrm_app_hostname
|
||||
http {
|
||||
path {
|
||||
path = "/*"
|
||||
backend {
|
||||
service_name = kubernetes_service.twentycrm_server.metadata.0.name
|
||||
service_port = kubernetes_service.twentycrm_server.spec.0.port.0.port
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
packages/twenty-docker/k8s/terraform/main.tf
Normal file
36
packages/twenty-docker/k8s/terraform/main.tf
Normal file
@ -0,0 +1,36 @@
|
||||
#############
|
||||
# Providers #
|
||||
#############
|
||||
provider "kubernetes" {
|
||||
config_path = "~/.kube/config"
|
||||
}
|
||||
|
||||
#################
|
||||
# Global Locals #
|
||||
#################
|
||||
locals {
|
||||
twentycrm_app_name = "twentycrm"
|
||||
twentycrm_app_hostname = "crm.example.com"
|
||||
twentycrm_server_image = "twentycrm/twenty:v0.10.4"
|
||||
twentycrm_db_image = "twentycrm/twenty-postgres:v0.10.4"
|
||||
twentycrm_db_pv_path = "/path/to/mystorage"
|
||||
twentycrm_db_pv_capacity = "10Gi"
|
||||
twentycrm_db_pvc_requests = "10Gi"
|
||||
twentycrm_server_pv_path = "/path/to/mystorage"
|
||||
twentycrm_server_pv_capacity = "10Gi"
|
||||
twentycrm_server_pvc_requests = "10Gi"
|
||||
}
|
||||
|
||||
####################
|
||||
# Terraform Config #
|
||||
####################
|
||||
terraform {
|
||||
required_version = ">= 1.7.4"
|
||||
required_providers {
|
||||
kubernetes = {
|
||||
source = "hashicorp/kubernetes"
|
||||
version = ">= 2.23.0"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
9
packages/twenty-docker/k8s/terraform/namespace.tf
Normal file
9
packages/twenty-docker/k8s/terraform/namespace.tf
Normal file
@ -0,0 +1,9 @@
|
||||
resource "kubernetes_namespace" "twentycrm" {
|
||||
metadata {
|
||||
annotations = {
|
||||
name = "twentycrm"
|
||||
}
|
||||
|
||||
name = "twentycrm"
|
||||
}
|
||||
}
|
||||
19
packages/twenty-docker/k8s/terraform/pv-db.tf
Normal file
19
packages/twenty-docker/k8s/terraform/pv-db.tf
Normal file
@ -0,0 +1,19 @@
|
||||
resource "kubernetes_persistent_volume" "db" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-db-pv"
|
||||
}
|
||||
spec {
|
||||
storage_class_name = "default"
|
||||
capacity = {
|
||||
storage = local.twentycrm_db_pv_capacity
|
||||
}
|
||||
access_modes = ["ReadWriteOnce"]
|
||||
# refer to Terraform Docs for your specific implementation requirements
|
||||
# https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume
|
||||
persistent_volume_source {
|
||||
local {
|
||||
path = local.twentycrm_db_pv_path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
packages/twenty-docker/k8s/terraform/pv-server.tf
Normal file
19
packages/twenty-docker/k8s/terraform/pv-server.tf
Normal file
@ -0,0 +1,19 @@
|
||||
resource "kubernetes_persistent_volume" "server" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-server-pv"
|
||||
}
|
||||
spec {
|
||||
storage_class_name = "default"
|
||||
capacity = {
|
||||
storage = local.twentycrm_server_pv_capacity
|
||||
}
|
||||
access_modes = ["ReadWriteOnce"]
|
||||
# refer to Terraform Docs for your specific implementation requirements
|
||||
# https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume
|
||||
persistent_volume_source {
|
||||
local {
|
||||
path = local.twentycrm_server_pv_path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
packages/twenty-docker/k8s/terraform/pvc-db.tf
Normal file
15
packages/twenty-docker/k8s/terraform/pvc-db.tf
Normal file
@ -0,0 +1,15 @@
|
||||
resource "kubernetes_persistent_volume_claim" "db" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-db-pvc"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
}
|
||||
spec {
|
||||
access_modes = ["ReadWriteOnce"]
|
||||
resources {
|
||||
requests = {
|
||||
storage = local.twentycrm_db_pvc_requests
|
||||
}
|
||||
}
|
||||
volume_name = kubernetes_persistent_volume.db.metadata.0.name
|
||||
}
|
||||
}
|
||||
15
packages/twenty-docker/k8s/terraform/pvc-server.tf
Normal file
15
packages/twenty-docker/k8s/terraform/pvc-server.tf
Normal file
@ -0,0 +1,15 @@
|
||||
resource "kubernetes_persistent_volume_claim" "server" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-server-pvc"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
}
|
||||
spec {
|
||||
access_modes = ["ReadWriteOnce"]
|
||||
resources {
|
||||
requests = {
|
||||
storage = local.twentycrm_server_pvc_requests
|
||||
}
|
||||
}
|
||||
volume_name = kubernetes_persistent_volume.server.metadata.0.name
|
||||
}
|
||||
}
|
||||
15
packages/twenty-docker/k8s/terraform/secret.tf
Normal file
15
packages/twenty-docker/k8s/terraform/secret.tf
Normal file
@ -0,0 +1,15 @@
|
||||
resource "kubernetes_secret" "twentycrm_tokens" {
|
||||
metadata {
|
||||
name = "tokens"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
}
|
||||
|
||||
data = {
|
||||
accessToken = var.twentycrm_token_accessToken
|
||||
loginToken = var.twentycrm_token_loginToken
|
||||
refreshToken = var.twentycrm_token_refreshToken
|
||||
fileToken = var.twentycrm_token_fileToken
|
||||
}
|
||||
|
||||
# type = "kubernetes.io/basic-auth"
|
||||
}
|
||||
18
packages/twenty-docker/k8s/terraform/service-db.tf
Normal file
18
packages/twenty-docker/k8s/terraform/service-db.tf
Normal file
@ -0,0 +1,18 @@
|
||||
resource "kubernetes_service" "twentycrm_db" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-db"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
}
|
||||
spec {
|
||||
selector = {
|
||||
app = "${local.twentycrm_app_name}-db"
|
||||
}
|
||||
session_affinity = "ClientIP"
|
||||
port {
|
||||
port = 5432
|
||||
target_port = 5432
|
||||
}
|
||||
|
||||
type = "ClusterIP"
|
||||
}
|
||||
}
|
||||
19
packages/twenty-docker/k8s/terraform/service-server.tf
Normal file
19
packages/twenty-docker/k8s/terraform/service-server.tf
Normal file
@ -0,0 +1,19 @@
|
||||
resource "kubernetes_service" "twentycrm_server" {
|
||||
metadata {
|
||||
name = "${local.twentycrm_app_name}-server"
|
||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
||||
}
|
||||
spec {
|
||||
selector = {
|
||||
app = "${local.twentycrm_app_name}-server"
|
||||
}
|
||||
session_affinity = "ClientIP"
|
||||
port {
|
||||
name = "http-tcp"
|
||||
port = 3000
|
||||
target_port = 3000
|
||||
}
|
||||
|
||||
type = "ClusterIP"
|
||||
}
|
||||
}
|
||||
24
packages/twenty-docker/k8s/terraform/variables.tf
Normal file
24
packages/twenty-docker/k8s/terraform/variables.tf
Normal file
@ -0,0 +1,24 @@
|
||||
variable "twentycrm_token_accessToken" {
|
||||
type = string
|
||||
description = "TwentyCRM access Token"
|
||||
}
|
||||
|
||||
variable "twentycrm_token_loginToken" {
|
||||
type = string
|
||||
description = "TwentyCRM login Token"
|
||||
}
|
||||
|
||||
variable "twentycrm_token_refreshToken" {
|
||||
type = string
|
||||
description = "TwentyCRM refresh Token"
|
||||
}
|
||||
|
||||
variable "twentycrm_token_fileToken" {
|
||||
type = string
|
||||
description = "TwentyCRM file Token"
|
||||
}
|
||||
|
||||
variable "twentycrm_pgdb_admin_password" {
|
||||
type = string
|
||||
description = "TwentyCRM password for postgres database"
|
||||
}
|
||||
Reference in New Issue
Block a user