Major changes
This commit is contained in:
+2
-1
@@ -5,7 +5,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- "terraform/k8sapps/**"
|
- "terraform/apps/contabo/**"
|
||||||
jobs:
|
jobs:
|
||||||
iac-apply:
|
iac-apply:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -35,6 +35,7 @@ jobs:
|
|||||||
- name: Setup Kubernetes Environment
|
- name: Setup Kubernetes Environment
|
||||||
uses: ./.github/actions/setup-k8s-env
|
uses: ./.github/actions/setup-k8s-env
|
||||||
with:
|
with:
|
||||||
|
host: prod-01.alexpires.me
|
||||||
project-id: ${{ secrets.BW_PROJECT_ID }}
|
project-id: ${{ secrets.BW_PROJECT_ID }}
|
||||||
organization-id: ${{ secrets.BW_ORGANIZATION_ID }}
|
organization-id: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||||
access-token: ${{ secrets.BW_ACCESS_TOKEN }}
|
access-token: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
FROM python:3.11-slim
|
|
||||||
ARG MCP_VERSION=0.2.0
|
|
||||||
ARG UID=1000
|
|
||||||
ARG GID=1000
|
|
||||||
RUN groupadd --system --gid ${GID} worker && \
|
|
||||||
adduser --system --gid ${GID} --uid ${UID} --home /home/worker worker
|
|
||||||
ENV PATH=/home/worker/.local/bin:$PATH
|
|
||||||
WORKDIR /home/worker
|
|
||||||
# Super user custom actions
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
curl \
|
|
||||||
tar \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
RUN curl -L https://gitea.com/gitea/gitea-mcp/releases/download/v${MCP_VERSION}/gitea-mcp_Linux_x86_64.tar.gz \
|
|
||||||
| tar -xz -C /usr/local/bin \
|
|
||||||
&& chmod +x /usr/local/bin/gitea-mcp
|
|
||||||
# End of super user custom actions
|
|
||||||
USER worker
|
|
||||||
RUN pip install mcpo uv
|
|
||||||
EXPOSE 8000
|
|
||||||
# Worker custom actions
|
|
||||||
ENV GITEA_HOST="https://gitea.com"
|
|
||||||
ENV GITEA_INSECURE="false"
|
|
||||||
ENV GITEA_ACCESS_TOKEN="<your personal access token>"
|
|
||||||
CMD ["uvx", "mcpo", "--host", "0.0.0.0", "--port", "8000", "--", "gitea-mcp"]
|
|
||||||
# End of worker custom actions
|
|
||||||
@@ -32,8 +32,7 @@ sshd_max_auth_tries: 10
|
|||||||
ufw_enable: true
|
ufw_enable: true
|
||||||
fw_allowed_ports:
|
fw_allowed_ports:
|
||||||
- { rule: "allow", port: "22", proto: "tcp" }
|
- { rule: "allow", port: "22", proto: "tcp" }
|
||||||
- { rule: "allow", port: "8000", proto: "tcp" }
|
- { rule: "allow", port: "443", proto: "tcp" }
|
||||||
- { rule: "allow", port: "8080", proto: "tcp" }
|
|
||||||
|
|
||||||
ufw_outgoing_traffic:
|
ufw_outgoing_traffic:
|
||||||
- 22 # SSH
|
- 22 # SSH
|
||||||
@@ -42,8 +41,13 @@ ufw_outgoing_traffic:
|
|||||||
- 123 # NTP
|
- 123 # NTP
|
||||||
- 443 # HTTPS
|
- 443 # HTTPS
|
||||||
- 853 # DNS over TLS
|
- 853 # DNS over TLS
|
||||||
- 11434 # Ollama
|
- 10250 # Kubelet
|
||||||
- 8880 # Kokoro-FastAPI
|
- 8880 # Kokoro-FastAPI
|
||||||
|
- 11434 # Ollama
|
||||||
|
- 16443 # Kubernetes API
|
||||||
|
- 4443
|
||||||
|
- 9443
|
||||||
|
- 995 # POP3S
|
||||||
|
|
||||||
ufw_default_forward_policy: "ACCEPT"
|
ufw_default_forward_policy: "ACCEPT"
|
||||||
|
|
||||||
@@ -77,6 +81,18 @@ unattended_reboot_time: "04:30"
|
|||||||
duo_users: ["*", "!provision"]
|
duo_users: ["*", "!provision"]
|
||||||
duo_api_hostname: api-7cda1654.duosecurity.com
|
duo_api_hostname: api-7cda1654.duosecurity.com
|
||||||
|
|
||||||
|
# Kubernetes specific settings
|
||||||
|
microk8s_allowed_hosts:
|
||||||
|
- 10.19.4.0/24
|
||||||
|
- 10.5.5.5
|
||||||
|
microk8s_alt_names: "{{ hostname }}"
|
||||||
|
|
||||||
|
# Let's encrypt issuer
|
||||||
|
microk8s_lets_encrypt_issuer: false
|
||||||
|
microk8s_encryption_secret: "{{ lookup('env', 'MICROK8S_ENCRYPTION_SECRET') }}"
|
||||||
|
microk8s_users:
|
||||||
|
- username: operator
|
||||||
|
enabled: true
|
||||||
|
|
||||||
# podman services settings
|
# podman services settings
|
||||||
open_webui_home: "/srv/open-webui"
|
persistent_data: "/srv"
|
||||||
mcp_home: "/srv/mcp"
|
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
- name: Setup open-webui
|
- name: Setup open-webui
|
||||||
hosts: openwebui
|
hosts: openwebui
|
||||||
vars:
|
|
||||||
podman_user: "{{ open_webui_user | default('openwebui') }}"
|
|
||||||
podman_group: "{{ open_webui_group | default('openwebui') }}"
|
|
||||||
podman_user_home: "{{ open_webui_home | default('/home/open-webui') }}"
|
|
||||||
podman_user_folders:
|
|
||||||
- data
|
|
||||||
pods:
|
|
||||||
- name: open-webui
|
|
||||||
repo:
|
|
||||||
image: ghcr.io/open-webui/open-webui
|
|
||||||
tag: main
|
|
||||||
ports:
|
|
||||||
- "0.0.0.0:{{ open_webui_port | default(8080) }}:8080/tcp"
|
|
||||||
volumes:
|
|
||||||
- "{{ open_webui_home }}/data:/app/backend/data:Z"
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Setup Pods
|
- name: Set required facts
|
||||||
ansible.builtin.include_tasks:
|
ansible.builtin.set_fact:
|
||||||
file: tasks/podman.yml
|
open_webui_home: "{{ persistent_data | default('/var/lib') }}/open_webui"
|
||||||
|
open_webui_user_id: 0
|
||||||
|
open_webui_group_id: 0
|
||||||
|
tags: always
|
||||||
|
|
||||||
|
- name: Create required open_webui data folder
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: "{{ item }}"
|
||||||
|
mode: "0750"
|
||||||
|
owner: "{{ open_webui_user_id }}"
|
||||||
|
group: "{{ open_webui_group_id }}"
|
||||||
|
with_items:
|
||||||
|
- "{{ open_webui_home }}"
|
||||||
|
tags:
|
||||||
|
- tasks
|
||||||
|
- tasks::folders
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ microk8s_metallb_version: 0.14.9
|
|||||||
# certificate manager
|
# certificate manager
|
||||||
microk8s_issuer_email: webmaster@localhost.localdomain
|
microk8s_issuer_email: webmaster@localhost.localdomain
|
||||||
microk8s_certmgr_version: 1.14.5
|
microk8s_certmgr_version: 1.14.5
|
||||||
|
microk8s_lets_encrypt_issuer: true
|
||||||
|
|
||||||
# microk8s specific
|
# microk8s specific
|
||||||
microk8s_channel: "{{ microk8s_k8s_version }}/stable"
|
microk8s_channel: "{{ microk8s_k8s_version }}/stable"
|
||||||
@@ -39,4 +40,4 @@ microk8s_iac_user: "provision"
|
|||||||
|
|
||||||
microk8s_encryption_secret: "a13labs"
|
microk8s_encryption_secret: "a13labs"
|
||||||
microk8s_encryption_cfg: "/etc/microk8s_encryption.yaml"
|
microk8s_encryption_cfg: "/etc/microk8s_encryption.yaml"
|
||||||
microk8s_encryption_kms_socket:
|
microk8s_encryption_kms_socket: ""
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
wait: true
|
wait: true
|
||||||
|
|
||||||
- name: CertManager | Register LetsEncrypt (prod)
|
- name: CertManager | Register LetsEncrypt (prod)
|
||||||
|
when: microk8s_lets_encrypt_issuer is true
|
||||||
environment:
|
environment:
|
||||||
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
|
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
|
||||||
vars:
|
vars:
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
class: public
|
class: public
|
||||||
|
|
||||||
- name: CertManager | Register LetsEncrypt (staging)
|
- name: CertManager | Register LetsEncrypt (staging)
|
||||||
|
when: microk8s_lets_encrypt_issuer is true
|
||||||
environment:
|
environment:
|
||||||
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
|
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
|
||||||
vars:
|
vars:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ resources:
|
|||||||
- secrets
|
- secrets
|
||||||
- configmaps
|
- configmaps
|
||||||
providers:
|
providers:
|
||||||
{% if microk8s_encryption_kms_socket is defined %}
|
{% if microk8s_encryption_kms_socket != "" %}
|
||||||
- kms:
|
- kms:
|
||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
name: aws-encryption-provider
|
name: aws-encryption-provider
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ prod-01.alexpires.me
|
|||||||
|
|
||||||
[microk8s]
|
[microk8s]
|
||||||
prod-01.alexpires.me
|
prod-01.alexpires.me
|
||||||
|
dev-01.alexpires.dev
|
||||||
|
|
||||||
[iac]
|
[iac]
|
||||||
prod-01.alexpires.me
|
prod-01.alexpires.me
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
module "open-webui" {
|
||||||
|
source = "../../modules/apps/open-webui"
|
||||||
|
|
||||||
|
persistent_folder = local.persistent_folder
|
||||||
|
fqdn = local.open_webui_fqdn
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
terraform {
|
||||||
|
backend "s3" {
|
||||||
|
bucket = "a13labs.infra.eu"
|
||||||
|
key = "apps.dev-01.core.infra.tfstate"
|
||||||
|
region = "eu-west-1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
locals {
|
||||||
|
|
||||||
|
# storage
|
||||||
|
persistent_folder = "/srv"
|
||||||
|
|
||||||
|
primary_domain = "alexpires.me"
|
||||||
|
open_webui_fqdn = "ai.${local.primary_domain}"
|
||||||
|
internal_issuer = "internal-ca"
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
resource "tls_private_key" "tls" {
|
||||||
|
algorithm = "ED25519"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_self_signed_cert" "tls" {
|
||||||
|
private_key_pem = tls_private_key.tls.private_key_pem
|
||||||
|
|
||||||
|
subject {
|
||||||
|
common_name = "kube-ca"
|
||||||
|
organization = "Alexandre Pires, Portugal"
|
||||||
|
}
|
||||||
|
|
||||||
|
validity_period_hours = 87600
|
||||||
|
is_ca_certificate = true
|
||||||
|
|
||||||
|
allowed_uses = [
|
||||||
|
"cert_signing",
|
||||||
|
"key_encipherment",
|
||||||
|
"digital_signature",
|
||||||
|
"crl_signing"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "kubernetes_secret" "root_ca" {
|
||||||
|
metadata {
|
||||||
|
name = "root-ca"
|
||||||
|
namespace = "cert-manager"
|
||||||
|
}
|
||||||
|
data = {
|
||||||
|
"tls.crt" = tls_self_signed_cert.tls.cert_pem
|
||||||
|
"tls.key" = tls_private_key.tls.private_key_pem
|
||||||
|
}
|
||||||
|
|
||||||
|
type = "kubernetes.io/tls"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "kubernetes_manifest" "cluster_issuer" {
|
||||||
|
|
||||||
|
manifest = {
|
||||||
|
apiVersion = "cert-manager.io/v1"
|
||||||
|
kind = "ClusterIssuer"
|
||||||
|
metadata = {
|
||||||
|
name = local.internal_issuer
|
||||||
|
annotations = {
|
||||||
|
"cert-manager.io/issuer-group" = "cert-manager.io"
|
||||||
|
"cert-manager.io/issuer-kind" = "Issuer"
|
||||||
|
"cert-manager.io/issuer-name" = local.internal_issuer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spec = {
|
||||||
|
ca = {
|
||||||
|
secretName = "root-ca"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,8 +47,6 @@ resource "kubernetes_cluster_role" "operator_maintenance_role" {
|
|||||||
verbs = ["get", "list", "watch", "create", "delete", "patch", "update"]
|
verbs = ["get", "list", "watch", "create", "delete", "patch", "update"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Allow reading Pod logs
|
# Allow reading Pod logs
|
||||||
rule {
|
rule {
|
||||||
api_groups = [""]
|
api_groups = [""]
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = "~>1.8"
|
||||||
|
required_providers {
|
||||||
|
kubernetes = {
|
||||||
|
source = "hashicorp/kubernetes"
|
||||||
|
version = "2.36.0"
|
||||||
|
}
|
||||||
|
tls = {
|
||||||
|
source = "hashicorp/tls"
|
||||||
|
version = "4.0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "kubernetes" {
|
||||||
|
config_path = "~/.kube/config"
|
||||||
|
config_context = "microk8s-dev-01"
|
||||||
|
insecure = true
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
module "websites" {
|
module "websites" {
|
||||||
source = "../modules/apps/nginx"
|
source = "../../modules/apps/nginx"
|
||||||
persistent_folder = local.persistent_folder
|
persistent_folder = local.persistent_folder
|
||||||
websites = local.websites
|
websites = local.websites
|
||||||
}
|
}
|
||||||
|
|
||||||
module "rustdesk" {
|
module "rustdesk" {
|
||||||
source = "../modules/apps/rustdesk"
|
source = "../../modules/apps/rustdesk"
|
||||||
|
|
||||||
persistent_folder = local.persistent_folder
|
persistent_folder = local.persistent_folder
|
||||||
fqdn = local.rustdesk_fqdn
|
fqdn = local.rustdesk_fqdn
|
||||||
@@ -14,7 +14,7 @@ module "rustdesk" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "m3uproxy" {
|
module "m3uproxy" {
|
||||||
source = "../modules/apps/m3uproxy"
|
source = "../../modules/apps/m3uproxy"
|
||||||
|
|
||||||
persistent_folder = local.persistent_folder
|
persistent_folder = local.persistent_folder
|
||||||
tag = local.m3uproxy_version
|
tag = local.m3uproxy_version
|
||||||
@@ -36,7 +36,7 @@ module "m3uproxy" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "mail" {
|
module "mail" {
|
||||||
source = "../modules/apps/mail"
|
source = "../../modules/apps/mail"
|
||||||
|
|
||||||
persistent_folder = local.persistent_folder
|
persistent_folder = local.persistent_folder
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ module "mail" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "gitea" {
|
module "gitea" {
|
||||||
source = "../modules/apps/gitea"
|
source = "../../modules/apps/gitea"
|
||||||
|
|
||||||
persistent_folder = local.persistent_folder
|
persistent_folder = local.persistent_folder
|
||||||
database_folder = local.database_folder
|
database_folder = local.database_folder
|
||||||
@@ -94,7 +94,7 @@ module "gitea" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "sftpgo" {
|
module "sftpgo" {
|
||||||
source = "../modules/apps/sftpgo"
|
source = "../../modules/apps/sftpgo"
|
||||||
|
|
||||||
persistent_folder = local.persistent_folder
|
persistent_folder = local.persistent_folder
|
||||||
backup_folder = local.sftpgo_backup_path
|
backup_folder = local.sftpgo_backup_path
|
||||||
@@ -116,7 +116,7 @@ module "sftpgo" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "trivy" {
|
module "trivy" {
|
||||||
source = "../modules/utils/trivy"
|
source = "../../modules/utils/trivy"
|
||||||
|
|
||||||
persistent_folder = local.persistent_folder
|
persistent_folder = local.persistent_folder
|
||||||
cron_schedule = local.trivy_cronjob_schedule
|
cron_schedule = local.trivy_cronjob_schedule
|
||||||
@@ -130,7 +130,7 @@ module "trivy" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "ssh_locker_web" {
|
module "ssh_locker_web" {
|
||||||
source = "../modules/apps/ssh_locker_web"
|
source = "../../modules/apps/ssh_locker_web"
|
||||||
|
|
||||||
duo_client_id = var.server_api_duo_client_id
|
duo_client_id = var.server_api_duo_client_id
|
||||||
duo_client_secret = var.server_api_duo_client_secret
|
duo_client_secret = var.server_api_duo_client_secret
|
||||||
@@ -141,7 +141,7 @@ module "ssh_locker_web" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "reverse_proxy" {
|
module "reverse_proxy" {
|
||||||
source = "../modules/apps/nginx-reverse-proxy"
|
source = "../../modules/apps/nginx-reverse-proxy"
|
||||||
|
|
||||||
services = local.reverse_proxy_services
|
services = local.reverse_proxy_services
|
||||||
wireguard_config = local.reverse_proxy_wireguard_config
|
wireguard_config = local.reverse_proxy_wireguard_config
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
module "mail_backup" {
|
module "mail_backup" {
|
||||||
|
|
||||||
source = "../modules/utils/scw_rclone"
|
source = "../../modules/utils/scw_rclone"
|
||||||
|
|
||||||
namespace = module.mail.namespace
|
namespace = module.mail.namespace
|
||||||
app_name = module.mail.app_name
|
app_name = module.mail.app_name
|
||||||
@@ -19,7 +19,7 @@ module "mail_backup" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module "gitea_backup" {
|
module "gitea_backup" {
|
||||||
source = "../modules/utils/scw_rclone"
|
source = "../../modules/utils/scw_rclone"
|
||||||
|
|
||||||
namespace = module.gitea.namespace
|
namespace = module.gitea.namespace
|
||||||
app_name = module.gitea.app_name
|
app_name = module.gitea.app_name
|
||||||
@@ -39,7 +39,7 @@ module "gitea_backup" {
|
|||||||
|
|
||||||
module "sftpgo_backup" {
|
module "sftpgo_backup" {
|
||||||
|
|
||||||
source = "../modules/utils/scw_rclone"
|
source = "../../modules/utils/scw_rclone"
|
||||||
|
|
||||||
namespace = module.sftpgo.namespace
|
namespace = module.sftpgo.namespace
|
||||||
app_name = module.sftpgo.app_name
|
app_name = module.sftpgo.app_name
|
||||||
@@ -98,21 +98,23 @@ locals {
|
|||||||
https_port = 8443
|
https_port = 8443
|
||||||
tls = true
|
tls = true
|
||||||
fqdn = ["ai.alexpires.me"]
|
fqdn = ["ai.alexpires.me"]
|
||||||
upstream = "http://10.19.4.136:8080"
|
upstream = "https://10.19.4.136"
|
||||||
locations = [
|
locations = [
|
||||||
{
|
{
|
||||||
path = "/ws/socket.io/"
|
path = "/ws/socket.io/"
|
||||||
headers = {
|
headers = {
|
||||||
|
"Host" = "$host"
|
||||||
|
"X-Forwarded-For" = "$remote_addr"
|
||||||
"Upgrade" = "$http_upgrade"
|
"Upgrade" = "$http_upgrade"
|
||||||
"Connection" = "upgrade"
|
"Connection" = "upgrade"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
# {
|
||||||
private = true
|
# private = true
|
||||||
path = "/tools/gitea"
|
# path = "/tools/gitea"
|
||||||
upstream = "http://10.19.4.136:8000"
|
# upstream = "http://10.19.4.136:8000"
|
||||||
rewrite = "^/tools/gitea/(.*)$ /$1 break"
|
# rewrite = "^/tools/gitea/(.*)$ /$1 break"
|
||||||
},
|
# },
|
||||||
{
|
{
|
||||||
private = true
|
private = true
|
||||||
path = "/providers/ollama"
|
path = "/providers/ollama"
|
||||||
@@ -121,6 +123,10 @@ locals {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path = "/"
|
path = "/"
|
||||||
|
headers = {
|
||||||
|
"Host" = "$host"
|
||||||
|
"X-Forwarded-For" = "$remote_addr"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
resource "kubernetes_service_account" "operator_service_account" {
|
||||||
|
metadata {
|
||||||
|
name = "operator"
|
||||||
|
namespace = "default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "kubernetes_cluster_role" "operator_maintenance_role" {
|
||||||
|
metadata {
|
||||||
|
name = "operator-maintenance-role"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow managing Pods (create, delete, exec, restart)
|
||||||
|
rule {
|
||||||
|
api_groups = [""]
|
||||||
|
resources = ["pods"]
|
||||||
|
verbs = ["get", "list", "watch", "create", "delete", "patch", "update", "exec"]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
api_groups = [""]
|
||||||
|
resources = ["replicationcontrollers"]
|
||||||
|
verbs = ["get", "list"]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
api_groups = ["autoscaling"]
|
||||||
|
resources = ["horizontalpodautoscalers"]
|
||||||
|
verbs = ["get", "list", "watch"]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
api_groups = ["apps"]
|
||||||
|
resources = ["deployments", "replicasets", "statefulsets", "daemonsets"]
|
||||||
|
verbs = ["get", "list", "watch"]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
api_groups = ["batch"]
|
||||||
|
resources = ["cronjobs"]
|
||||||
|
verbs = ["get", "list", "watch"]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
api_groups = ["batch"]
|
||||||
|
resources = ["jobs"]
|
||||||
|
verbs = ["get", "list", "watch", "create", "delete", "patch", "update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow reading Pod logs
|
||||||
|
rule {
|
||||||
|
api_groups = [""]
|
||||||
|
resources = ["pods/log"]
|
||||||
|
verbs = ["get", "list"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow managing Pod eviction for draining nodes, etc.
|
||||||
|
rule {
|
||||||
|
api_groups = ["policy"]
|
||||||
|
resources = ["pods/eviction"]
|
||||||
|
verbs = ["create"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow reading Namespaces (usually required for multi-namespace tools)
|
||||||
|
rule {
|
||||||
|
api_groups = [""]
|
||||||
|
resources = ["namespaces"]
|
||||||
|
verbs = ["get", "list", "watch"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow reading and managing PodDisruptionBudgets (useful for draining nodes)
|
||||||
|
rule {
|
||||||
|
api_groups = ["policy"]
|
||||||
|
resources = ["poddisruptionbudgets"]
|
||||||
|
verbs = ["get", "list", "watch", "patch", "update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow managing Nodes (e.g., for cordoning, draining)
|
||||||
|
rule {
|
||||||
|
api_groups = [""]
|
||||||
|
resources = ["nodes"]
|
||||||
|
verbs = ["get", "list", "patch", "update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow reading PersistentVolumeClaims (PVCs) but not PersistentVolumes
|
||||||
|
rule {
|
||||||
|
api_groups = [""]
|
||||||
|
resources = ["persistentvolumeclaims"]
|
||||||
|
verbs = ["get", "list", "watch"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow listing and getting services and endpoints (but not updating)
|
||||||
|
rule {
|
||||||
|
api_groups = [""]
|
||||||
|
resources = ["services", "endpoints"]
|
||||||
|
verbs = ["get", "list", "watch"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "kubernetes_cluster_role_binding" "operator_maintenance_binding" {
|
||||||
|
metadata {
|
||||||
|
name = "operator-maintenance-binding"
|
||||||
|
}
|
||||||
|
|
||||||
|
role_ref {
|
||||||
|
kind = "ClusterRole"
|
||||||
|
name = kubernetes_cluster_role.operator_maintenance_role.metadata[0].name
|
||||||
|
api_group = "rbac.authorization.k8s.io"
|
||||||
|
}
|
||||||
|
|
||||||
|
subject {
|
||||||
|
kind = "ServiceAccount"
|
||||||
|
namespace = "default"
|
||||||
|
name = kubernetes_service_account.operator_service_account.metadata[0].name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "kubernetes_secret" "operator_access_token" {
|
||||||
|
metadata {
|
||||||
|
annotations = {
|
||||||
|
"kubernetes.io/service-account.name" = kubernetes_service_account.operator_service_account.metadata[0].name
|
||||||
|
}
|
||||||
|
name = "operator-token"
|
||||||
|
namespace = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
type = "kubernetes.io/service-account-token"
|
||||||
|
wait_for_service_account_token = true
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ terraform {
|
|||||||
|
|
||||||
provider "kubernetes" {
|
provider "kubernetes" {
|
||||||
config_path = "~/.kube/config"
|
config_path = "~/.kube/config"
|
||||||
config_context = "microk8s"
|
config_context = "microk8s-prod-01"
|
||||||
insecure = true
|
insecure = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
||||||
|
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY
|
||||||
@@ -102,6 +102,7 @@ resource "kubernetes_deployment" "m3uproxy" {
|
|||||||
container_port = 8080
|
container_port = 8080
|
||||||
name = "http"
|
name = "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
readiness_probe {
|
readiness_probe {
|
||||||
http_get {
|
http_get {
|
||||||
path = "/health"
|
path = "/health"
|
||||||
@@ -111,6 +112,7 @@ resource "kubernetes_deployment" "m3uproxy" {
|
|||||||
period_seconds = 10
|
period_seconds = 10
|
||||||
failure_threshold = 10
|
failure_threshold = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
env {
|
env {
|
||||||
name = "USERNAME"
|
name = "USERNAME"
|
||||||
value_from {
|
value_from {
|
||||||
@@ -120,6 +122,7 @@ resource "kubernetes_deployment" "m3uproxy" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env {
|
env {
|
||||||
name = "PASSWORD"
|
name = "PASSWORD"
|
||||||
value_from {
|
value_from {
|
||||||
@@ -129,11 +132,13 @@ resource "kubernetes_deployment" "m3uproxy" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_context {
|
security_context {
|
||||||
allow_privilege_escalation = false
|
allow_privilege_escalation = false
|
||||||
run_as_user = 1000
|
run_as_user = 1000
|
||||||
run_as_group = 1000
|
run_as_group = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
volume_mount {
|
volume_mount {
|
||||||
name = "m3uproxy-config"
|
name = "m3uproxy-config"
|
||||||
mount_path = "/app/conf/m3uproxy.json"
|
mount_path = "/app/conf/m3uproxy.json"
|
||||||
|
|||||||
@@ -322,6 +322,9 @@ resource "kubernetes_deployment" "reverse_proxy" {
|
|||||||
}
|
}
|
||||||
initial_delay_seconds = 5
|
initial_delay_seconds = 5
|
||||||
period_seconds = 10
|
period_seconds = 10
|
||||||
|
failure_threshold = 10
|
||||||
|
timeout_seconds = 5
|
||||||
|
success_threshold = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
security_context {
|
security_context {
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
locals {
|
||||||
|
persistent_folder = var.persistent_folder
|
||||||
|
app_path = "${local.persistent_folder}/open-webui"
|
||||||
|
|
||||||
|
app_version = var.tag
|
||||||
|
app_fqdn = var.fqdn
|
||||||
|
}
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user