diff --git a/main.tf b/main.tf index 7733a7a8..0d340c45 100644 --- a/main.tf +++ b/main.tf @@ -32,6 +32,7 @@ variable "drone_rpc_secret" {} # variable "dockerhub_password" {} variable "oauth_client_id" {} variable "oauth_client_secret" {} +variable "url_shortener_geolite_license_key" {} variable "webhook_handler_fb_verify_token" {} variable "webhook_handler_fb_page_token" {} variable "webhook_handler_fb_app_secret" {} @@ -67,6 +68,12 @@ provider "helm" { config_path = var.prod ? "" : "~/.kube/config" } } +# provider "kubectl" { +# host = "kubernetes.viktorbarzin.lan" +# cluster_ca_certificate = base64decode(var.eks_cluster_ca) +# token = data.aws_eks_cluster_auth.main.token +# load_config_file = true +# } # Main module to init infra from module "pxe_server" { @@ -219,4 +226,6 @@ module "kubernetes_cluster" { idrac_username = var.monitoring_idrac_username idrac_password = var.monitoring_idrac_password + + url_shortener_geolite_license_key = var.url_shortener_geolite_license_key } diff --git a/modules/kubernetes/dbaas/main.tf b/modules/kubernetes/dbaas/main.tf new file mode 100644 index 00000000..1d9486d4 --- /dev/null +++ b/modules/kubernetes/dbaas/main.tf @@ -0,0 +1,138 @@ +# DB as a service. Installs MySQL operator +variable "tls_secret_name" {} + +resource "kubernetes_namespace" "dbaas" { + metadata { + name = "dbaas" + } +} + +module "tls_secret" { + source = "../setup_tls_secret" + namespace = "dbaas" + tls_secret_name = var.tls_secret_name +} + +resource "helm_release" "mysql" { + namespace = "dbaas" + create_namespace = false + name = "mysql" + + repository = "https://presslabs.github.io/charts" + chart = "mysql-operator" + + values = [templatefile("${path.module}/mysql_chart_values.yaml", { secretName = var.tls_secret_name })] + +} + +resource "kubernetes_persistent_volume" "mysql-operator" { + metadata { + name = "mysql-operator-pv" + } + spec { + capacity = { + "storage" = "1Gi" + } + access_modes = ["ReadWriteOnce"] + persistent_volume_source { + iscsi { + target_portal = "iscsi.viktorbarzin.lan:3260" + iqn = "iqn.2020-12.lan.viktorbarzin:storage:dbaas:operator" + lun = 0 + fs_type = "ext4" + } + } + } +} + +resource "kubernetes_persistent_volume" "mysql" { + metadata { + name = "mysql-pv" + } + spec { + capacity = { + "storage" = "10Gi" + } + access_modes = ["ReadWriteOnce"] + persistent_volume_source { + iscsi { + target_portal = "iscsi.viktorbarzin.lan:3260" + iqn = "iqn.2020-12.lan.viktorbarzin:storage:dbaas:mysql" + lun = 0 + fs_type = "ext4" + } + } + } +} + +resource "kubernetes_secret" "cluster-password" { + metadata { + name = "cluster-secret" + namespace = "dbaas" + } + type = "Opaque" + data = { + "ROOT_PASSWORD" = "kek" + } +} +# resource "kubernetes_manifest" "mysql-cluster" { +# manifest = { +# apiVersion = "mysql.presslabs.org/v1alpha1" +# kind = "MysqlCluster" +# metadata = { +# name = "mysql-cluster" +# namespace = "dbaas" +# } +# spec = { +# mysqlVersion = "5.7" +# replicas = 1 +# secretName = "cluster-secret" +# mysqlConf = { +# read_only = 0 +# } +# volumeSpec = { +# persistentVolumeClaim = { +# resources = { +# requests = { +# storage = "10Gi" +# } +# } +# } +# } +# } +# } +# } + +# resource "kubectl_manifest" "mysql-cluster" { +# yaml_body = <<-YAML +# apiVersion: mysql.presslabs.org/v1alpha1 +# kind: MysqlCluster +# metadata: +# name: MyCluster +# spec: +# mysqlVersion: "5.7" +# replicas: 1 +# secretName: MyCluster-Secret +# mysqlConf: +# read_only: 0 # mysql forms a single transaction for each sql statement, autocommit for each statement +# automatic_sp_privileges: "ON" # automatically grants the EXECUTE and ALTER ROUTINE privileges to the creator of a stored routine +# auto_generate_certs: "ON" # Auto Generation of Certificate +# auto_increment_increment: 1 # Auto Incrementing value from +1 +# auto_increment_offset: 1 # Auto Increment Offset +# binlog-format: "STATEMENT" # contains various options such ROW(SLOW,SAFE) STATEMENT(FAST,UNSAFE), MIXED(combination of both) +# wait_timeout: 31536000 # 28800 number of seconds the server waits for activity on a non-interactive connection before closing it, You might encounter MySQL server has gone away error, you then tweak this value acccordingly +# interactive_timeout: 28800 # The number of seconds the server waits for activity on an interactive connection before closing it. +# max_allowed_packet: "512M" # Maximum size of MYSQL Network protocol packet that the server can create or read 4MB, 8MB, 16MB, 32MB +# max-binlog-size: 1073741824 # binary logs contains the events that describe database changes, this parameter describe size for the bin_log file. +# log_output: "TABLE" # Format in which the logout will be dumped +# master-info-repository: "TABLE" # Format in which the master info will be dumped +# relay_log_info_repository: "TABLE" # Format in which the relay info will be dumped +# volumeSpec: +# persistentVolumeClaim: +# accessModes: +# - ReadWriteMany +# resources: +# requests: +# storage: 10Gi +# YAML +# } diff --git a/modules/kubernetes/dbaas/mysql_chart_values.yaml b/modules/kubernetes/dbaas/mysql_chart_values.yaml new file mode 100644 index 00000000..16b4161d --- /dev/null +++ b/modules/kubernetes/dbaas/mysql_chart_values.yaml @@ -0,0 +1,10 @@ +--- +orchestrator: + persistence: + enabled: false + ingress: + enabled: true + tls: + - secretName: ${secretName} + hosts: + - db.viktorbarzin.me diff --git a/modules/kubernetes/main.tf b/modules/kubernetes/main.tf index a51d8bdf..67106510 100644 --- a/modules/kubernetes/main.tf +++ b/modules/kubernetes/main.tf @@ -19,6 +19,7 @@ variable "drone_rpc_secret" {} # variable "dockerhub_password" {} variable "oauth_client_id" {} variable "oauth_client_secret" {} +variable "url_shortener_geolite_license_key" {} variable "webhook_handler_fb_verify_token" {} variable "webhook_handler_fb_page_token" {} variable "webhook_handler_fb_app_secret" {} @@ -48,6 +49,11 @@ module "bind" { named_conf_options = var.bind_named_conf_options } +module "dbaas" { + source = "./dbaas" + tls_secret_name = var.tls_secret_name +} + module "dnscrypt" { source = "./dnscrypt" } @@ -172,6 +178,12 @@ module "reloader" { source = "./reloader" } +module "url" { + source = "./url-shortener" + tls_secret_name = var.tls_secret_name + geolite_license_key = var.url_shortener_geolite_license_key +} + module "webhook_handler" { source = "./webhook_handler" tls_secret_name = var.tls_secret_name diff --git a/modules/kubernetes/monitoring/grafana_chart_values.yaml b/modules/kubernetes/monitoring/grafana_chart_values.yaml index fc16dff3..4ee908dd 100644 --- a/modules/kubernetes/monitoring/grafana_chart_values.yaml +++ b/modules/kubernetes/monitoring/grafana_chart_values.yaml @@ -37,6 +37,8 @@ grafana.ini: auth.anonymous: enabled: true org_role: Viewer + # auth.google: + # enabled: true analytics: check_for_updates: "true" grafana_net: diff --git a/modules/kubernetes/url-shortener/main.tf b/modules/kubernetes/url-shortener/main.tf new file mode 100644 index 00000000..d1d5e587 --- /dev/null +++ b/modules/kubernetes/url-shortener/main.tf @@ -0,0 +1,254 @@ +variable "tls_secret_name" {} +variable "geolite_license_key" {} +variable "domain" { + default = "url.viktorbarzin.me" +} + +resource "kubernetes_namespace" "shlink" { + metadata { + name = "url" + } +} + +module "tls_secret" { + source = "../setup_tls_secret" + namespace = "url" + tls_secret_name = var.tls_secret_name +} + +resource "kubernetes_deployment" "shlink" { + metadata { + name = "shlink" + namespace = "url" + labels = { + run = "shlink" + } + } + spec { + replicas = 1 + selector { + match_labels = { + run = "shlink" + } + } + template { + metadata { + labels = { + run = "shlink" + } + } + spec { + container { + image = "shlinkio/shlink:stable" + name = "shlink" + env { + name = "SHORT_DOMAIN_HOST" + value = var.domain + } + env { + name = "SHORT_DOMAIN_SCHEMA" + value = "https" + } + env { + name = "GEOLITE_LICENSE_KEY" + value = var.geolite_license_key + } + resources { + limits = { + cpu = "0.5" + memory = "512Mi" + } + requests = { + cpu = "250m" + memory = "50Mi" + } + } + port { + container_port = 8080 + } + } + } + } + } +} + +resource "kubernetes_service" "shlink" { + metadata { + name = "shlink" + namespace = "url" + labels = { + "run" = "shlink" + } + } + + spec { + selector = { + run = "shlink" + } + port { + name = "http" + port = "80" + target_port = "8080" + } + } +} + +resource "kubernetes_ingress" "shlink" { + metadata { + name = "shlink-ingress" + namespace = "url" + annotations = { + "kubernetes.io/ingress.class" = "nginx" + } + } + + spec { + tls { + hosts = ["url.viktorbarzin.me"] + secret_name = var.tls_secret_name + } + rule { + host = "url.viktorbarzin.me" + http { + path { + path = "/" + backend { + service_name = "shlink" + service_port = "80" + } + } + } + } + } +} + +# Shlink web client + +resource "kubernetes_config_map" "shlink-web" { + metadata { + name = "shlink-web-servers" + namespace = "url" + + annotations = { + "reloader.stakater.com/match" = "true" + } + } + + data = { + "servers.json" = jsonencode([{ + name = "Main" + url = "https://url.viktorbarzin.me" + apiKey = "9f0c32d6-605d-480b-ac80-764e122498b5" + }]) + } +} + +resource "kubernetes_deployment" "shlink-web" { + metadata { + name = "shlink-web" + namespace = "url" + labels = { + run = "shlink-web" + } + annotations = { + "reloader.stakater.com/search" = "true" + } + } + spec { + replicas = 1 + selector { + match_labels = { + run = "shlink-web" + } + } + template { + metadata { + labels = { + run = "shlink-web" + } + } + spec { + container { + image = "shlinkio/shlink-web-client" + name = "shlink-web" + volume_mount { + mount_path = "/usr/share/nginx/html/servers.json" + sub_path = "servers.json" + name = "config" + } + resources { + limits = { + cpu = "0.5" + memory = "512Mi" + } + requests = { + cpu = "250m" + memory = "50Mi" + } + } + port { + container_port = 8080 + } + } + volume { + name = "config" + config_map { + name = "shlink-web-servers" + } + } + } + } + } +} + +resource "kubernetes_service" "shlink-web" { + metadata { + name = "shlink-web" + namespace = "url" + labels = { + "run" = "shlink-web" + } + } + + spec { + selector = { + run = "shlink-web" + } + port { + name = "http" + port = "80" + target_port = "80" + } + } +} + +resource "kubernetes_ingress" "shlink-web" { + metadata { + name = "shlink-web-ingress" + namespace = "url" + annotations = { + "kubernetes.io/ingress.class" = "nginx" + "nginx.ingress.kubernetes.io/auth-tls-verify-client" = "on" + "nginx.ingress.kubernetes.io/auth-tls-secret" = "default/ca-secret" + } + } + + spec { + tls { + hosts = ["shlink.viktorbarzin.me"] + secret_name = var.tls_secret_name + } + rule { + host = "shlink.viktorbarzin.me" + http { + path { + path = "/" + backend { + service_name = "shlink-web" + service_port = "80" + } + } + } + } + } +} diff --git a/terraform.tfstate b/terraform.tfstate index ea76b9f8..99eef8de 100644 Binary files a/terraform.tfstate and b/terraform.tfstate differ diff --git a/terraform.tfvars b/terraform.tfvars index b34d0488..70a8b6c2 100644 Binary files a/terraform.tfvars and b/terraform.tfvars differ diff --git a/versions.tf b/versions.tf index 5d7c4592..08edb954 100644 --- a/versions.tf +++ b/versions.tf @@ -3,6 +3,10 @@ terraform { kubernetes = { source = "hashicorp/kubernetes" } + # kubectl = { + # source = "gavinbunney/kubectl" + # version = ">= 1.7.0" + # } } required_version = ">= 0.13" }