diff --git a/.gitea/template b/.gitea/template new file mode 100644 index 0000000..d0bddb1 --- /dev/null +++ b/.gitea/template @@ -0,0 +1,11 @@ +# Expand all .go files, anywhere in the repository +**.yaml + +# All text files in the text directory +text/*.txt + +# A specific file +a/b/c/d.json + +# Batch files in both upper or lower case can be matched +**.[bB][aA][tT] diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..4cbfec9 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,24 @@ +--- + +# This example uses YAML anchors which allows reuse of multiple keys +# without having to repeat yourself. +# Also see https://github.com/Mic92/dotfiles/blob/master/nixos/.sops.yaml +# for a more complex example. +keys: + age: + - &cluster_age_key age13jnzxrtrghlh8zvc9q3d8yd2a9xdp8jset72l8dwz6pept3j3c0qkmxd47 +creation_rules: + - path_regex: .+secret(\.sops)?\.ya?ml + input_type: yaml + encrypted_regex: ^(data|stringData)$ + key_groups: + - age: &key_groups + - *cluster_age_key + - path_regex: .+secret(\.sops)?\.env + input_type: env + key_groups: + - age: *key_groups +stores: + yaml: + indent: 2 + diff --git a/README.md b/README.md index e44af10..58cda29 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,199 @@ -# tenant-tpl +# Welcome to your ${REPOS_NAME}-tenant -Tenant Gitea template \ No newline at end of file +## Table of contents + +1. [General Overview](#General-Overview) +2. [Usefull Links](#Usefull-links) +3. [About GitOps](#About-Git-Ops) +4. [How To](#How-To) + +## General Overview + +Your namespace have been deployed and is now accessible from openshift cli or +directly through the cluster +[console](https://console-openshift-console.apps.${CLUSTER_NAME}.kvant.cloud/) + +A dummy application 'echo-server' have been deployed on it. It's a good example +on how we recommend to deploy application using our flux setup. You will find +several reference in the [How](#How-To) section that README. + +### Usefull links + +* [Get me to my Namespace](https://console-openshift-console.apps.${CLUSTER_NAME}.kvant.cloud/k8s/cluster/projects/${REPOS_NAME}-ns) +* [Monitoring](XXXXX) +* [Flux Doc](https://fluxcd.io/flux/) +* [Sops](https://getsops.io/) + +## About Git Ops + +This repository is already fully configured to work in a GitOps Way +(https://www.gitops.tech/#what-is-gitops). We use [`FluxCD`](#Flux-Doc) has our +GitOps Tools. We highly recommand to take advantage of that setup to deploy +your application however it's not mandatory and you can use another way to ship +them. + +### Our Flux Setup + +`Repository Overview` + +```shell +. +├── echo-server +│   ├── app +│   │   ├── helmrelease.yaml +│   │   └── kustomization.yaml +│   └── ks.yaml +├── kustomization.yaml +├── README.md +└── repos + ├── helm + │   ├── bjw-s.yaml + │   └── kustomization.yaml + └── kustomization.yaml +``` +We use the [`./kustomization.yaml`](${REPO_LINK}/kustomization.yaml) as our +main entrypoint that will include our [flux +kustomization](https://fluxcd.io/flux/components/kustomize/kustomizations/). + +[`./echo-server/ks.yaml`](${REPO_LINK}/echo-server/ks.yaml) Is a good example +on how create new flux kustomization definition you could use it as a template +for your next kusto. You'll find inside a breakdown and comments on line that +are mandatory. + +The echo-server [helmrelease](${REPO_LINK}/echo-server/app/helmrelease.yaml) is +example of a simple application that is accessible at a given URI. It use the +helmchart template [bjw-s.yaml](${REPO_LINK}/repos/helm/bjw-s.yaml). This chart +should cover pretty much all you need to deploy an app. + + +## How To + +### SSL and DNS + +#### Bring your own certificate and domain + +[WIP] + +#### Use Predefined Domain + +You can spawn any application using your namespace associated Domain. +`${REPOS_NAME}.pub.${CLUSTER}.kvant.cloud` + +### Storage + +We are providing two type of storage. Object Storage and Volumes. + + +### Request a Object Storage + +```yaml +apiVersion: objectbucket.io/v1alpha1 +kind: ObjectBucketClaim +metadata: + name: +spec: + generateBucketName: + storageClassName: openshift-storage.noobaa.io + +``` + +### Request a PV + +In the data section of your helmrelease. + +```yaml +data: + enabled: true + type: persistentVolumeClaim + accessMode: ReadWriteOnce + size: 1Gi +``` +### Secret Encryption + +In regard of GitOps there is multiple way to handle encryption of secret that +live within a git repository. We recommending you to use [SOPS](https://getsops.io/) as +you encryption engine. + +We have already Setup a key [Private key](Path_to_sops_private_key) dedicated +to your namespace that will be able to decrypt any secret that you is in your git repository. + + +[`./sops.yaml`](${REPO_LINK}/.sops.yaml) is the configuration file that will +handle how you secret will be encrypted while using sops. + +#### Quick Start + +To work with secret you'll need: +* [SOPS stable release](https://github.com/getsops/sops/releases) +* [age](https://age-encryption.org/) + +##### Create your own key + +###### Linux + +```shell +mkdir -p $XDG_CONFIG_HOME/sops/age +age-keygen -o $XDG_CONFIG_HOME/sops/age/keys.txt +``` +###### MacOS + +```shell +mkdir -p "$HOME/Library/Application Support/sops/age" +age-keygen -o "$HOME/Library/Application Support/sops/age/keys.txt" +``` +##### Propagate your Public key + +Edit the [`./sops.yaml`](${REPO_LINK}/.sops.yaml) file and add your public key +that you have generated previously. + + +```shell +$ cat .sops.yaml + --- + + # This example uses YAML anchors which allows reuse of multiple keys + # without having to repeat yourself. + # Also see https://github.com/Mic92/dotfiles/blob/master/nixos/.sops.yaml + # for a more complex example. + keys: + age: + - &cluster_age_key age13jnzxrtrghlh8zvc9q3d8yd2a9xdp8jset72l8dwz6pept3j3c0qkmxd47 + - &YOUR_KEY_NAME + creation_rules: + - path_regex: .+secret(\.sops)?\.ya?ml + input_type: yaml + encrypted_regex: ^(data|stringData)$ + key_groups: + - age: &key_groups + - *cluster_age_key + - *YOUR_KEY_NAME + - path_regex: .+secret(\.sops)?\.env + input_type: env + key_groups: + - age: *key_groups + stores: + yaml: + indent: 2 +``` +##### Create your first secret + +``` +$ sops name_of_you_file.secret.sops.yaml + +``` +You can then deploy it the cluster will be able to Decrypt it using it's public +key + +##### Rewrapping secret + +In case add/remove a key secret generated previously will need to be +reencrypted with the appropriate key. We have place a [shell +script](${REPO_LINK}/scripts/rewrap-secret.sh) that will do that for you. + +It will reencrypt all the secret that it will find in folder and subfolder +following the .sops.yaml rules files of your directory. + + +| :boom: INFOS | +|:----------------------------| +| You can have as many .sops.yaml file as you want in your repository | diff --git a/echo-server/app/helmrelease.yaml b/echo-server/app/helmrelease.yaml new file mode 100644 index 0000000..8f17cf2 --- /dev/null +++ b/echo-server/app/helmrelease.yaml @@ -0,0 +1,102 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: &app echo-server +spec: + serviceAccountName: ${REPOS_NAME}-sa + interval: 30m + chart: + spec: + chart: app-template + version: 3.2.1 + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: ${REPOS_NAME}-ns + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + strategy: rollback + retries: 3 + values: + controllers: + echo-server: + replicas: 2 + strategy: RollingUpdate + containers: + app: + image: + repository: ghcr.io/mendhak/http-https-echo + tag: 33 + env: + HTTP_PORT: &port 8080 + LOG_WITHOUT_NEWLINE: true + LOG_IGNORE_PATH: /healthz + PROMETHEUS_ENABLED: true + probes: + liveness: &probes + enabled: true + custom: true + spec: + httpGet: + path: /healthz + port: *port + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: *probes + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: { drop: ["ALL"] } + seccompProfile: + type: RuntimeDefault + resources: + requests: + cpu: 10m + limits: + memory: 64Mi + defaultPodOptions: + securityContext: + runAsNonRoot: true + seccompProfile: { type: RuntimeDefault } + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/name: *app + service: + app: + controller: echo-server + ports: + http: + port: *port + serviceMonitor: + app: + serviceName: echo-server + endpoints: + - port: http + scheme: http + path: /metrics + interval: 1m + scrapeTimeout: 10s + ingress: + app: + className: external + hosts: + #- host: "{{ .Release.Name }}{{ .Release.Namespace }}.pub.staging.kvant.cloud" + - host: "{{ .Release.Name }}{{ .Release.Namespace }}.pub.${CLUSTER_DOMAIN}" + paths: + - path: / + service: + identifier: app + port: http + diff --git a/echo-server/app/kustomization.yaml b/echo-server/app/kustomization.yaml new file mode 100644 index 0000000..ce84014 --- /dev/null +++ b/echo-server/app/kustomization.yaml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + diff --git a/echo-server/ks.yaml b/echo-server/ks.yaml new file mode 100644 index 0000000..20bd16c --- /dev/null +++ b/echo-server/ks.yaml @@ -0,0 +1,22 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app echo-server + namespace: ${REPOS_NAME}-ns +spec: + targetNamespace: ${REPOS_NAME}-ns + commonMetadata: + labels: + app.kubernetes.io/name: *app + path: ./echo-server/app + prune: true + serviceAccountName: ${REPOS_NAME}-sa + sourceRef: + kind: GitRepository + name: ${REPOS_NAME}-tenant-repos + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m diff --git a/kustomization.yaml b/kustomization.yaml new file mode 100644 index 0000000..1e5d16d --- /dev/null +++ b/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - echo-server/ks.yaml + - repos/ diff --git a/repos/helm/bjw-s.yaml b/repos/helm/bjw-s.yaml new file mode 100644 index 0000000..65e6749 --- /dev/null +++ b/repos/helm/bjw-s.yaml @@ -0,0 +1,12 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1.json +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: bjw-s + namespace: ${REPOS_NAME}-ns +spec: + type: oci + interval: 5m + url: oci://ghcr.io/bjw-s/helm + diff --git a/repos/helm/kustomization.yaml b/repos/helm/kustomization.yaml new file mode 100644 index 0000000..3ca9458 --- /dev/null +++ b/repos/helm/kustomization.yaml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./bjw-s.yaml + diff --git a/repos/kustomization.yaml b/repos/kustomization.yaml new file mode 100644 index 0000000..6394dc2 --- /dev/null +++ b/repos/kustomization.yaml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helm +