diff --git a/.gitea/workflows/app-continous-deploy.yaml b/.gitea/workflows/app-continous-deploy.yaml deleted file mode 100644 index 15dcbc9..0000000 --- a/.gitea/workflows/app-continous-deploy.yaml +++ /dev/null @@ -1,88 +0,0 @@ -on: - schedule: - - cron: '0 9 * * 0' # every sunday 9 am - push: - branches: - - main - pull_request: - branches: - - main -jobs: - continuous-deploy: - runs-on: ["deploy", "kubectl"] - env: - GITHUB_TEMP: ${{ runner.temp }} # fix missing GITHUB_TEMP on gitea - steps: - - - name: Checkout code - uses: actions/checkout@v3 - - - name: limbo public actions - env: - WORKSPACE: "${{ gitea.workspace }}" - run: | - curl -fsSL https://git.limbosolutions.com/kb/gitea/raw/branch/main/cloud-scripts/setup-limbo-actions.sh | bash 2>&1 - - - # limbo custom actions required https://git.limbosolutions.com/kb/gitea/raw/branch/main - - name: Configure kubectl config - uses: ./.gitea/limbo_actions/kubectl-setup - with: - kube_server: ${{ secrets.HOSTING_KUBE_SERVER }} - kube_ca_base64: ${{ secrets.HOSTING_KUBE_CA_BASE64 }} - kube_token: ${{ secrets.HOSTING_KUBE_TOKEN }} - - - name: Deploy - shell: bash - env: - # cron jobs env - CRONJOBS_BACKUPS_SECRETS_PBS_REPOSITORY: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_PBS_REPOSITORY }} - CRONJOBS_BACKUPS_SECRETS_PBS_PASSWORD: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_PBS_PASSWORD }} - CRONJOBS_BACKUPS_SECRETS_PBS_FINGERPRINT: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_PBS_FINGERPRINT }} - CRONJOBS_BACKUPS_SECRETS_BORG_REPO: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_BORG_REPO }} - CRONJOBS_BACKUPS_SECRETS_BORG_PASSPHRASE: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_BORG_PASSPHRASE }} - CRONJOBS_BACKUPS_SECRETS_OFFSITE_TARGET_FOLDER: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_OFFSITE_TARGET_FOLDER }} - CRONJOBS_BACKUPS_SECRETS_ID_RSA: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_ID_RSA }} - CRONJOBS_BACKUPS_SECRETS_BORG_KEY: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_BORG_KEY }} - - # helm chart values - APP_HELM_VALUE_VALKEY_GLOBAL_PASSWORD: ${{ secrets.APP_HELM_VALUE_VALKEY_GLOBAL_PASSWORD }} - APP_HELM_VALUE_POSTGRESQL_AUTH_POSTGRESPASSWORD: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_POSTGRESPASSWORD }} - APP_HELM_VALUE_POSTGRESQL_AUTH_PASSWORD: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_PASSWORD }} - APP_HELM_VALUE_POSTGRESQL_AUTH_DATABASE: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_DATABASE }} - APP_HELM_VALUE_POSTGRESQL_AUTH_USERNAME: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_USERNAME }} - APP_HELM_VALUE_GITEA_ADMIN_USERNAME: ${{ secrets.APP_HELM_VALUE_GITEA_ADMIN_USERNAME }} - APP_HELM_VALUE_GITEA_ADMIN_PASSWORD: ${{ secrets.APP_HELM_VALUE_GITEA_ADMIN_PASSWORD }} - APP_HELM_VALUE_GITEA_ADMIN_EMAIL: ${{ secrets.APP_HELM_VALUE_GITEA_ADMIN_EMAIL }} - APP_HELM_VALUE_GITEA_CONFIG_OAUTH2_JWT_SECRET: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_OAUTH2_JWT_SECRET }} - APP_HELM_VALUE_GITEA_CONFIG_SERVER_LFS_JWT_SECRET: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SERVER_LFS_JWT_SECRET }} - APP_HELM_VALUE_GITEA_CONFIG_SECURITY_SECRET_KEY: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_SECRET_KEY }} - APP_HELM_VALUE_GITEA_CONFIG_SECURITY_REVERSE_PROXY_TRUSTED_PROXIES: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_REVERSE_PROXY_TRUSTED_PROXIES }} - APP_HELM_VALUE_GITEA_CONFIG_SECURITY_INTERNAL_TOKEN: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_INTERNAL_TOKEN }} - APP_HELM_VALUE_GITEA_CONFIG_SECURITY_PASSWORD_HASH_ALGO: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_PASSWORD_HASH_ALGO }} - APP_HELM_VALUE_GITEA_CONFIG_SERVICE_OAUTH2_JWT_SECRET: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SERVICE_OAUTH2_JWT_SECRET }} - - run: | - set -euo pipefail - - # ensure cleanup always runs - trap 'rm -f \ - deploy/backups/.env.d/*' EXIT - - # setup secrets files - echo "PBS_REPOSITORY=${CRONJOBS_BACKUPS_SECRETS_PBS_REPOSITORY}" >> deploy/backups/.env.d/secrets - echo "PBS_PASSWORD=${CRONJOBS_BACKUPS_SECRETS_PBS_PASSWORD}" >> deploy/backups/.env.d/secrets - echo "PBS_FINGERPRINT=${CRONJOBS_BACKUPS_SECRETS_PBS_FINGERPRINT}" >> deploy/backups/.env.d/secrets - echo "BORG_REPO=${CRONJOBS_BACKUPS_SECRETS_BORG_REPO}" >> deploy/backups/.env.d/secrets - echo "BORG_PASSPHRASE=${CRONJOBS_BACKUPS_SECRETS_BORG_PASSPHRASE}" >> deploy/backups/.env.d/secrets - echo "OFFSITE_TARGET_FOLDER=${CRONJOBS_BACKUPS_SECRETS_OFFSITE_TARGET_FOLDER}" >> deploy/backups/.env.d/secrets - echo "${CRONJOBS_BACKUPS_SECRETS_ID_RSA}" >> deploy/backups/.env.d/id_rsa - echo "${CRONJOBS_BACKUPS_SECRETS_BORG_KEY}" >> deploy/backups/.env.d/borg_key - - # enforce secrets files security - chmod 600 deploy/backups/.env.d/secrets - chmod 600 deploy/backups/.env.d/id_rsa - chmod 600 deploy/backups/.env.d/borg_key - - # invoke deploy script - ops-scripts/apply-app.sh diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..f07f7a5 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,6 @@ +creation_rules: + # encrypt all values + - path_regex: \.private\.dec\.yaml$ + encrypted_regex: '^(.*)$' + age: + - age1gk946fp37xtm3fv500407zdd5h89a5lvxysrufhau3f73xcq8ewqcu8l5g \ No newline at end of file diff --git a/README.md b/README.md index 5f49f2c..1c5d849 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ kubectl create secret generic flux-sops-age \ **Encrypt secrets:** ``` bash -sops -e deploy/clusters/prod/app/helm-values.private.dec.yaml > deploy/clusters/prod/app/helm-values.private.yaml +sops -e deploy/app/helm-values.private.dec.yaml > deploy/app/helm-values.private.yaml ``` ### Continuous Deploy diff --git a/deploy/app/.gitignore b/deploy/app/.gitignore new file mode 100644 index 0000000..6e1fd1b --- /dev/null +++ b/deploy/app/.gitignore @@ -0,0 +1 @@ +**.dec.* \ No newline at end of file diff --git a/deploy/app/gitea-helm-repo.yaml b/deploy/app/gitea-helm-repo.yaml new file mode 100644 index 0000000..c63d889 --- /dev/null +++ b/deploy/app/gitea-helm-repo.yaml @@ -0,0 +1,8 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: gitea + namespace: git-limbosolutions-com +spec: + interval: 24m + url: https://dl.gitea.com/charts \ No newline at end of file diff --git a/deploy/app/helm-values.private.yaml b/deploy/app/helm-values.private.yaml new file mode 100644 index 0000000..3c4948b --- /dev/null +++ b/deploy/app/helm-values.private.yaml @@ -0,0 +1,44 @@ +valkey: + global: + valkey: + password: ENC[AES256_GCM,data:JLuHt0eFalM=,iv:5ngKNJiVOSk0vQsXNtRtFNE8/i4z1HZ2Y7PMXuyiXmo=,tag:EvO7QS51A1TnMF6TlfcDGA==,type:str] +postgresql: + global: + postgresql: + auth: + postgresPassword: ENC[AES256_GCM,data:lAg0KTIxxaiaDFs=,iv:4hhR966BouRbMJAo6KXEPtVVpldSeGAUs1M+zNw4KZ8=,tag:Uw1D2klZnB1wzeWLOl0dXg==,type:str] + password: ENC[AES256_GCM,data:AUyftj4LoqIZo/6yng==,iv:tC9RV1zhaem4I0l8ZMKPKiF1Uo3ZvqzWwRaNHSdmTYQ=,tag:EVhrS3vI8UxOjjDz9laXRw==,type:str] + database: ENC[AES256_GCM,data:tu3eBZI=,iv:bpBb42MgM8IOrufsu7phJNTsCAXtqlEhHcwIOgfyCKo=,tag:FqiAcuqc87ru+ZzQCwFZ+Q==,type:str] + username: ENC[AES256_GCM,data:ed0ID6WPDuGNc8A=,iv:n5Y39XbUYSD3Y6QG0EOnyGaZhz1KjLW3msbrUOys5a4=,tag:yg7NAJO5rLJU2d7Y/hOv4g==,type:str] +gitea: + admin: + username: ENC[AES256_GCM,data:Ybt8xgzwNsA=,iv:PYde0BEkR0ICg//GJhkQUPW2rljccN1IDCmmxzObB2k=,tag:0pJ4aUOaaxREMB5yK3nhXg==,type:str] + password: ENC[AES256_GCM,data:/IRhJRu4vZl2pAHkL1zL3Gfhp55e3A==,iv:xGi+5pAHvqX8UtyqB8kmJ0VRsajnYyxm4oGoidL0xS4=,tag:Kbvf1LkxUVrzpqLyVi9ZDg==,type:str] + email: ENC[AES256_GCM,data:6Byg8xs2qSqnnfKl6iEF,iv:cb89ChgMHGrmVx5WpDibrFT0Qdb6eIQf5VNGFVG5FUc=,tag:TfqW8XK5q0/hqEQwlRZuAw==,type:str] + config: + oauth2: + JWT_SECRET: ENC[AES256_GCM,data:Fb2865W0zBHHHSvSw4xad3zzsuAnGBYzz0ZVFJ5TfY2xgEmw3ncO2L3NBw==,iv:ksJGhtTS+5/xa+OdJzjvAXSc95ydBgXfTNca5LYbMk0=,tag:YyIOMCIvQ83fvmUHooRQUg==,type:str] + server: ENC[AES256_GCM,data:9y4KFmvUoVp8mm+usMUOuzMyDyb0U/af+TQiWfIZshO0agOF2cnV+2NNgY8U6jscWQ/JtDkDpcZCYA==,iv:zCO2c4PVBKj+9Nmeels9FgfhVdcqYpsgR3fAL2bKbME=,tag:Sq2qs0n8QjhtqcWlMTimEA==,type:str] + security: + SECRET_KEY: ENC[AES256_GCM,data:st0mdJYJqE7g3mx4Cf1zNmaWx18QnQgSyk8kXQiD9uiVlxc7yx+uNUE7U5utFLaKwtF5LchSF4RKHk8E/4Ury5QsrTNQvAwoNdvrvp/DeZ8mdFrDfRBjfpidz/g9MjmvGLgJJLtdaw4InOjYTGUUkqTB+U/6kg==,iv:CwmGW7n7JtnmTm+B1ZhrDLUDdq4D1EuEhsYeq4Og+ys=,tag:6+xT0vhlJYNv5PtsseXRaA==,type:str] + REVERSE_PROXY_TRUSTED_PROXIES: ENC[AES256_GCM,data:DA==,iv:Y0JVk2Da2A/4vBY7H/53YNzMn2MgbNFU/uSu6QLxbPk=,tag:9aaj9fQkIoMdpfaPD8ecDQ==,type:str] + INTERNAL_TOKEN: ENC[AES256_GCM,data:avU6VRFIxoO1dF51jCX1wJBZDcm3B76399YfwGLS7SnsitaMBy3z6Hsg3MqbbJJXhoXTjHGwXugz9YlYwFsMJAH1BP2AboGWba3z1M9OvjYF076MBkR7X4PhYUC9ISRqaefbly7K+wJZ,iv:3eLLxKWMLJzWhvPEESupEm1Xoq9/D2T6RoGhDg8EG7Q=,tag:mitF1RF/LlhOpFdXGS8KCg==,type:str] + PASSWORD_HASH_ALGO: ENC[AES256_GCM,data:PBGUIZun,iv:3TeZDceEzTk3F+9R+DTRPaBLaubBylMZ2W7DQLkuuEM=,tag:7iqwRxGLOev+jvTwtnBULg==,type:str] + service: + oauth2: + JWT_SECRET: ENC[AES256_GCM,data:Ncb9nA6FdkakmSzDXedf+eR4HaWjLjoU22FD7f19s1rgmE0XoUt0EoHWiQ==,iv:XWSJkDQDpmxQoBMuV8LmxN/oj/iRX0LzGip7FtFtIQE=,tag:x8CUuatUCwSWcsog2mlcRA==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhYnBzamFDQVpXWDZ1eHdK + QmVqS3phQVd4ZFFjdVJQNXJlQUh5dnUrbkY0ClVPRVlPUERTN3NZMENma3VjSnVk + aW1aRS9vbDZnWDhWQmcvRkp1blp3ZnMKLS0tIGtoeXYwRG9INXZpVmZFY3pJd2hi + L3ZQSTgvZzVUZnphQ1B5ekVObjRMNm8KFr29C43uC3HCYWH4C4hzrat5wFA3y9V0 + 8AezbRQUCKCbtlMXKtmwEEMTyr1NWzu8cMWreA2aHJf9Xl3o0Dj11g== + -----END AGE ENCRYPTED FILE----- + recipient: age1gk946fp37xtm3fv500407zdd5h89a5lvxysrufhau3f73xcq8ewqcu8l5g + encrypted_regex: ^(.*)$ + lastmodified: "2026-06-02T22:06:55Z" + mac: ENC[AES256_GCM,data:AzScEfkqYNGuhmR8G0sLUINFiMTJtyUHLftAkG5DIy8jbV1SYS2gi9EnjdnaSZggve/xNjf0KnbdKrMWHFgrwkFxJ11tQIvQtz50RIHPuNMXv8vDmTVjvTTJd8ls+KT7fRxlmLE0ipF+PwKlLpHToTb2KmIfYIK12XsifkZ/6PU=,iv:t6UXX7CmfjMMvMmKY8OwRTa4zXdcOuYcPaoHmZxhe9U=,tag:95Iz9VmJLq2VHixXxQ5+0A==,type:str] + version: 3.13.1 diff --git a/deploy/app/kustomization.yaml b/deploy/app/kustomization.yaml new file mode 100644 index 0000000..edad70c --- /dev/null +++ b/deploy/app/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - gitea-helm-repo.yaml + - gitea-helm-release.yaml + +secretGenerator: + - name: gitea-helm-values + files: + - values.yaml=helm-values.yaml + - values.private.yaml=helm-values.private.dec.yaml +generatorOptions: + disableNameSuffixHash: true \ No newline at end of file diff --git a/deploy/flux/gitea-sync.yaml b/deploy/flux/gitea-sync.yaml new file mode 100644 index 0000000..6a03e9a --- /dev/null +++ b/deploy/flux/gitea-sync.yaml @@ -0,0 +1,12 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: gitea-sync + namespace: git-limbosolutions-com +spec: + interval: 1m + sourceRef: + kind: GitRepository + name: git-limbosolutions-com + path: deploy/app + prune: true diff --git a/deploy/flux/kustomization.yaml b/deploy/flux/kustomization.yaml index b30e32d..840e23d 100644 --- a/deploy/flux/kustomization.yaml +++ b/deploy/flux/kustomization.yaml @@ -3,6 +3,7 @@ kind: Kustomization resources: - git-repo.yaml - infra-sync.yaml + - gitea-sync.yaml secretGenerator: - name: flux-repo-ssh-credentials files: