diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..ff76bd9 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,5 @@ +creation_rules: + - path_regex: secrets.yaml + key_groups: + - age: + - age1vy36vn6w3f07rxm40tsy0u4gvqtjqznrs69ue4fkgxd06n4jl3esq8l60v diff --git a/.woodpecker/cdh.yaml b/.woodpecker/cdh.yaml new file mode 100644 index 0000000..8347ef4 --- /dev/null +++ b/.woodpecker/cdh.yaml @@ -0,0 +1,31 @@ +# ---------------------------------------------- +# -- Check da helm pipeline +# ---------------------------------------------- +when: + - event: cron + cron: nightly +steps: + check badhouseplants: + image: ghcr.io/allanger/check-da-helm-helmfile-secrets:stable + secrets: + - sops_age_key + environment: + RUST_LOG: info + commands: + - cdh --kind helmfile -p $CI_WORKSPACE/helmfile.yaml -o + + notification: + image: deblan/woodpecker-email + settings: + dsn: + from_secret: smtp_dsn + from: + address: woody@badhouseplants.net + name: Woody Woodpecker + recipients: + - allanger@badhouseplants.net + subject: CDH result + target: main + attachment: result.html + when: + - status: [success, failure] diff --git a/.woodpecker/helmfile.yaml b/.woodpecker/helmfile.yaml new file mode 100644 index 0000000..2f99845 --- /dev/null +++ b/.woodpecker/helmfile.yaml @@ -0,0 +1,27 @@ +when: + event: push + +steps: + diff: + image: ghcr.io/helmfile/helmfile:canary + secrets: [sops_age_key, kubeconfig_content] + when: + - branch: + exclude: + - main + commands: + - mkdir $HOME/.kube + - echo "$KUBECONFIG_CONTENT" > $HOME/.kube/config && chmod 0600 $HOME/.kube/config + - helmfile diff --suppress-secrets + + apply: + image: ghcr.io/helmfile/helmfile:canary + secrets: [sops_age_key, kubeconfig_content] + when: + - branch: + include: + - main + commands: + - mkdir $HOME/.kube + - echo "$KUBECONFIG_CONTENT" > $HOME/.kube/config && chmod 0600 $HOME/.kube/config + - helmfile apply diff --git a/environments.yaml b/environments.yaml new file mode 100644 index 0000000..9d8cb3f --- /dev/null +++ b/environments.yaml @@ -0,0 +1,3 @@ +environments: + default: + kubeContext: badhouseplants diff --git a/helmfile.yaml b/helmfile.yaml new file mode 100644 index 0000000..e6e3cee --- /dev/null +++ b/helmfile.yaml @@ -0,0 +1,30 @@ +--- +bases: + - environments.yaml + +templates: + ext-istio-resource: + dependencies: + - chart: bedag/raw + version: 2.0.0 + alias: istio + values: + - '{{ requiredEnv "PWD" }}/istio.yaml' + +repositories: + - name: bedag + url: https://bedag.github.io/helm-charts/ + - name: minecraft + url: https://itzg.github.io/minecraft-server-charts/ + +releases: + - name: minecraft + chart: minecraft/minecraft + namespace: minecraft-application + version: 4.15.0 + values: + - ./values.yaml + secrets: + - ./secrets.yaml + inherit: + - template: ext-istio-resource diff --git a/istio.yaml b/istio.yaml new file mode 100644 index 0000000..1c834bc --- /dev/null +++ b/istio.yaml @@ -0,0 +1,36 @@ +--- +istio: + templates: + - | + {{ range .Values.istio }} + --- + apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + metadata: + name: {{ .name }} + spec: + gateways: + - "{{ .gateway }}" + hosts: + - {{ .hostname | quote }} + {{- if eq .kind "http" }} + http: + - match: + - uri: + prefix: / + route: + - destination: + host: {{ .service }} + port: + number: {{ .port }} + {{- else if eq .kind "tcp" }} + tcp: + - match: + - port: {{ .port_match }} + route: + - destination: + host: {{ .service }} + port: + number: {{ .port }} + {{ end }} + {{ end }} diff --git a/secrets.yaml b/secrets.yaml new file mode 100644 index 0000000..0df3977 --- /dev/null +++ b/secrets.yaml @@ -0,0 +1,28 @@ +minecraftServer: + rcon: + password: ENC[AES256_GCM,data:d7rEX5rOJNXikocvJBSoCnA1aTx2jKfV7A==,iv:P5wsHV2XAzL6Ny1TwgsMEp+IbFFY2cObdfV+q//X01c=,tag:x+FOgJ8OvGcs8C0cEicejQ==,type:str] +mcbackup: + resticEnvs: + RESTIC_PASSWORD: ENC[AES256_GCM,data:AOYlclTvz+DVlYAPxG1X+V/5KfQLTwzImbcxlU01,iv:KolGzA//wWOolocX3T5zxWJ0jfWkWg+PrGbME+D2iFU=,tag:uDuU+sdcvVyjwcxh/UEOrg==,type:str] + AWS_SECRET_ACCESS_KEY: ENC[AES256_GCM,data:8IBX/nwoqyR/xhr3umY=,iv:4FIGY9dryZ+G48vevaAdZAbU8Dlj+mdEtnytTuiP9Aw=,tag:b8vwsOD+WhclZhO/nxMmug==,type:str] + AWS_ACCESS_KEY_ID: ENC[AES256_GCM,data:Cvh5NCtE,iv:w9FeowyjjPqNzz6MwIUytVQbcRIdn0qcSm0tnjpZQiQ=,tag:z2bV6d6XLJWgOU6Nfd9sBQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1vy36vn6w3f07rxm40tsy0u4gvqtjqznrs69ue4fkgxd06n4jl3esq8l60v + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFZmxLUDNRTUoxS0tjWmRW + c1ZuZFRqZVBVbjQ3UlhDQnZhb3M4R3ZPVVRjCi9BQkFVT2l2c1MrQzI3MGo5YUQ2 + Ti9jbHZUeVlGYWsycllWT3EyR2U4cVEKLS0tIGJBZ2IvakpHYzkrMXBqWFlSK1Fs + bkZBbXlpNC9uVGEwNDZ3WllaT01kdTQKYac1Tjq7EwfSNq1I8dyxZGuJ8Zkk0qTJ + zI/n40s54Y6rv4u5qTkIvW6HLp1NRm5jofpmq53Ss/yvsgwyWMmMyA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-02-20T23:30:18Z" + mac: ENC[AES256_GCM,data:u3ngPkQ5ZJHLUbFzCg/mhG8k4V9w0N4UzxeV2gOENJAC1hQnv6ZzB9PSWvqRlgu6TiBCNg1RC8AecxX2p7/9L2HyeQpfxj3J/oY0tyXlWdUJ9uVMG9b7F0jdP5a2rRoQWJ1YhI4ThZDVaittNy/jINlfNrTwWfIehVAd+CdcOp4=,iv:YymBTrvWAGvtFYu60oZQw0L3kgv1cnUy0MIV0jsFs6s=,tag:ULfzTGZq+z49FC9up6qm1g==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/values.yaml b/values.yaml new file mode 100644 index 0000000..e5df96a --- /dev/null +++ b/values.yaml @@ -0,0 +1,180 @@ +--- +# -------------------------------------------------- +# -- Extensions values +# -------------------------------------------------- +service-account: + enabled: true + resources: + - name: minecraft-exporter + label: + app: minecraft-minecraft-metrics + endpoints: + port: metrics +# ------------------------------------------ +# -- Istio extenstion. Just because I'm +# -- not using ingress nginx +# ------------------------------------------ +istio: + enabled: true + istio: + - name: minecraft-tcp + gateway: istio-system/badhouseplants-minecraft + kind: tcp + port_match: 25565 + hostname: "*" + service: minecraft-minecraft + port: 25565 +# -------------------------------------------------- +# -- Main values +# -------------------------------------------------- +image: + tag: java17-graalvm-ce + pullPolicy: Always + +resources: + requests: + memory: 3Gi + cpu: 256m + limits: + memory: 3Gi + +lifecycle: + postStart: + - bash + - -c + - for i in {1..100}; do mc-health && break || sleep 20; done && mc-send-to-console setpassword 11223345 + +readinessProbe: + command: + - mc-health + periodSeconds: 20 + failureThreshold: 50 + timeoutSeconds: 10 +livenessProbe: + timeoutSeconds: 10 + +minecraftServer: + overrideServerProperties: true + eula: "TRUE" + onlineMode: false + difficulty: hard + hardcore: true + version: 1.20.1 + maxWorldSize: 90000 + type: "PAPER" + paperDownloadUrl: https://api.papermc.io/v2/projects/paper/versions/1.20.1/builds/170/downloads/paper-1.20.1-170.jar + gameMode: survival + pvp: true + rcon: + enabled: true + withGeneratedPassword: false + port: 25575 + serviceType: ClusterIP + extraPorts: + - name: metrics + containerPort: 9225 + protocol: TCP + service: + enabled: true + embedded: false + labels: + exporter: minecraft + type: ClusterIP + port: 9925 + ingress: + enabled: false +persistence: + dataDir: + enabled: true + Size: 15Gi +mcbackup: + enabled: false + backupInterval: 2h + pauseIfNoPlayers: "false" + pruneBackupsDays: 2 + rconRetries: 5 + rconRetryInterval: 10s + excludes: "*.jar,cache,logs" + backupMethod: restic + resticRepository: s3:https://s3.e.badhouseplants.net:443/restic/minecraft + resticAdditionalTags: "mc_backups" + pruneResticRetention: "--keep-last 12 --keep-daily 1 --keep-weekly 2 --keep-monthly 2 --keep-yearly 2" + resources: + requests: + memory: 512Mi + cpu: 100m + persistence: + backupDir: + enabled: false +# --------------------------------------------- +# -- Install Plugins +# --------------------------------------------- +initContainers: + - name: 0-install-prometheus-exporter + image: alpine/curl + command: + - curl + - -L + - "https://github.com/sladkoff/minecraft-prometheus-exporter/releases/download/v2.5.0/minecraft-prometheus-exporter-2.5.0.jar" + - -o + - /data/plugins/prometheus-exporter.jar + volumeMounts: + - name: plugins + mountPath: /data/plugins + readOnly: false + - name: 0-install-password-plugin + image: alpine/curl + command: + - curl + - -L + - "https://github.com/timbru31/PasswordProtect/releases/download/PasswordProtect-3.1.0/PasswordProtect.jar" + - -o + - /data/plugins/PasswordProtect.jar + volumeMounts: + - name: plugins + mountPath: /data/plugins + readOnly: false + - name: 0-install-gravity-control-plugin + image: alpine/curl + command: + - curl + - -L + - https://github.com/e-im/GravityControl/releases/download/v1.3.0/GravityControl-1.3.0.jar + - -o + - /data/plugins/GravityControl-1.3.0.jar + volumeMounts: + - name: plugins + mountPath: /data/plugins + readOnly: false + - name: 0-install-fast-minecart-plugin + image: alpine/curl + command: + - curl + - -L + - https://github.com/certainly1182/FastMinecarts/releases/download/v1.0.1/FastMinecarts.jar + - -o + - /data/plugins/FastMinecarts.jar + volumeMounts: + - name: plugins + mountPath: /data/plugins + - name: 1-add-plugins-to-minecraft + image: alpine/curl + command: + - sh + - -c + - cp -r /in /out/plugins + volumeMounts: + - name: plugins + mountPath: /in + readOnly: false + - name: datadir + mountPath: /out +extraVolumes: + - volumeMounts: + - name: plugins + mountPath: /data/plugins + readOnly: false + volumes: + - name: plugins + emptyDir: + sizeLimit: 500Mi