├── .github ├── actions │ └── helmfile │ │ ├── Dockerfile │ │ ├── action.yaml │ │ ├── entrypoint.sh │ │ └── main.js └── workflows │ └── pr-test.yaml ├── Dockerfile ├── LICENSE ├── README.md ├── charts.yaml ├── charts ├── cert-manager │ └── helmfile │ │ ├── base.yaml.gotmpl │ │ └── cluster-issuer.yaml.gotmpl ├── cluster-system │ └── helmfile │ │ └── base.yaml.gotmpl ├── concourse │ └── helmfile │ │ └── values.yaml.gotmpl ├── elasticsearch │ └── helmfile │ │ ├── secrets.yaml.gotmpl │ │ └── values.yaml.gotmpl ├── externaldns │ └── helmfile │ │ └── base.yaml.gotmpl ├── fluentbit │ └── helmfile │ │ └── values.yaml.gotmpl ├── gangway │ ├── .helmignore │ ├── Chart.yaml │ ├── OWNERS │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap.yaml │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ ├── key.yaml │ │ ├── service.yaml │ │ └── ssl.yaml │ └── values.yaml ├── grafana │ └── helmfile │ │ └── values.yaml.gotmpl ├── harbor │ └── helmfile │ │ ├── secrets.yaml.gotmpl │ │ └── values.yaml.gotmpl ├── ingress │ └── helmfile │ │ └── base.yaml.gotmpl ├── kibana │ └── helmfile │ │ └── values.yaml.gotmpl ├── kubeapps │ └── helmfile │ │ ├── oidc.yaml.gotmpl │ │ └── values.yaml.gotmpl ├── loki │ └── helmfile │ │ ├── raw.yaml.gotmpl │ │ └── values.yaml.gotmpl ├── minio │ └── helmfile │ │ └── values.yaml.gotmpl ├── mystique │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ └── mystique.yaml │ └── values.yaml ├── prometheus │ └── helmfile │ │ └── values.yaml.gotmpl ├── promtail │ └── helmfile │ │ └── values.yaml.gotmpl ├── raw │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ └── manifests.yaml │ └── values.yaml ├── spinnaker │ └── helmfile │ │ ├── secrets.yaml.gotmpl │ │ ├── uaa.yaml.gotmpl │ │ └── values.yaml.gotmpl └── wavefront │ └── helmfile │ └── values.yaml.gotmpl ├── docs ├── default │ ├── concourse.png │ ├── grafana.png │ ├── harbor.png │ ├── install.md │ ├── kibana.png │ ├── loki.png │ └── spinnaker.png └── gcp-uaa-openid │ └── install.md ├── envs ├── .gitignore ├── default │ ├── charts.yaml.gotmpl │ ├── envs.sh │ └── values.yaml.gotmpl └── gcp-uaa-openid │ ├── charts.yaml.gotmpl │ ├── envs.sh │ └── values.yaml.gotmpl ├── helmfile.yaml ├── releases: ├── resources ├── cert-manager │ ├── crds.yaml │ └── newcrds.yaml ├── eirini │ └── topology-aware-storage-class.yaml └── harbor │ └── namespace.yaml ├── scripts ├── check-namespaces.sh ├── create-namespace.sh ├── fileExists ├── uaa-clients.sh └── yamlsplit.sh ├── values.yaml └── values └── gangway └── values.yaml.gotmpl /.github/actions/helmfile/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM "ubuntu:latest" 2 | 3 | WORKDIR /tmp 4 | 5 | RUN apt-get update && apt-get install -yq curl git tree 6 | 7 | RUN \ 8 | curl -sSL https://get.helm.sh/helm-v3.1.1-linux-amd64.tar.gz | tar xzf - \ 9 | && cp linux-amd64/helm /bin/helm && chmod +x /bin/helm \ 10 | && helm plugin install https://github.com/databus23/helm-diff --version v3.1.1 11 | 12 | RUN \ 13 | curl -sSL https://github.com/roboll/helmfile/releases/download/v0.102.0/helmfile_linux_amd64 > /bin/helmfile \ 14 | && chmod +x /bin/helmfile 15 | 16 | RUN \ 17 | curl -sSL https://github.com/mikefarah/yq/releases/download/3.2.1/yq_linux_amd64 > /bin/yq \ 18 | && chmod +x /bin/yq 19 | 20 | RUN \ 21 | curl -sSL https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl > /bin/kubectl \ 22 | && chmod +x /bin/kubectl 23 | 24 | # COPY entrypoint.sh /entrypoint.sh 25 | 26 | # WORKDIR /src 27 | 28 | # ENTRYPOINT [ "/entrypoint.sh" ] -------------------------------------------------------------------------------- /.github/actions/helmfile/action.yaml: -------------------------------------------------------------------------------- 1 | name: "Helmfile Apply" 2 | description: "Run Helmfile Apply" 3 | author: "Paul Czarkowski" 4 | branding: 5 | color: blue 6 | icon: anchor 7 | inputs: 8 | action: 9 | command: "either lint or apply" 10 | runs: 11 | using: "node12" 12 | main: "main.js" 13 | -------------------------------------------------------------------------------- /.github/actions/helmfile/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eox pipefail 4 | 5 | install_prereqs() { 6 | 7 | docker_exec sh -c ' 8 | apt-get update && apt-get install -yq curl git 9 | 10 | if ! which helm; then 11 | curl -sSL https://get.helm.sh/helm-v3.1.1-linux-amd64.tar.gz | tar xzf - 12 | cp linux-amd64/helm /bin/helm 13 | chmod +x /bin/helm 14 | fi 15 | 16 | if ! helm plugin list | grep "^diff\s"; then 17 | helm plugin install https://github.com/databus23/helm-diff 18 | fi 19 | 20 | if ! which helmfile; then 21 | curl -sSL https://github.com/roboll/helmfile/releases/download/v0.102.0/helmfile_linux_amd64 > /bin/helmfile 22 | chmod +x /bin/helmfile 23 | fi 24 | 25 | if [[ "${INPUT_COMMAND}" == "apply" ]]; then 26 | if ! which yq; then 27 | curl -sSL https://github.com/mikefarah/yq/releases/download/3.2.1/yq_linux_amd64 > /bin/yq 28 | chmod +x /bin/yq 29 | fi 30 | if ! which kubectl; then 31 | curl -sSL https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl > /bin/kubectl 32 | chmod +x /bin/kubectl 33 | fi 34 | fi 35 | ' 36 | } 37 | 38 | build_container() { 39 | echo 'Building action container...' 40 | if ! docker inspect --type image action > /dev/null; then 41 | docker build -t action . 42 | fi 43 | } 44 | 45 | run_container() { 46 | echo 'Running action container...' 47 | # source ./envs/default/envs.sh 48 | # env > ./envs/default/docker-envs.list 49 | if docker inspect --type container runner > /dev/null; then 50 | docker rm -f runner 51 | sleep 5 52 | fi 53 | 54 | local args=(run --rm --interactive --detach --network host --name runner "--volume=$(pwd):/workdir" "--workdir=/workdir") 55 | args+=("-e" "KUBECONFIG=${KUBECONFIG}") 56 | # args+=("--env-file" "./envs/default/docker-envs.list") 57 | args+=("action" "cat") 58 | docker "${args[@]}" 59 | 60 | echo 61 | } 62 | 63 | docker_exec() { 64 | docker exec --workdir=/workdir --interactive runner "$@" 65 | } 66 | 67 | if [[ -n ${GITHUB_WORKSPACE} ]]; then 68 | cd "${GITHUB_WORKSPACE}" 69 | fi 70 | 71 | build_container 72 | run_container 73 | 74 | if [[ "${INPUT_COMMAND}" == "apply" ]]; then 75 | docker_exec sh -c ' 76 | . ./envs/default/envs.sh 77 | ./scripts/check-namespaces.sh -c -d 78 | helmfile apply 79 | ' 80 | elif [[ "${INPUT_COMMAND}" == "diff" ]]; then 81 | docker_exec sh -c ' 82 | . ./envs/default/envs.sh 83 | ./scripts/check-namespaces.sh -c -d 84 | helmfile diff 85 | ' 86 | else 87 | docker_exec sh -c ' 88 | . ./envs/default/envs.sh 89 | helmfile lint 90 | ' 91 | fi 92 | -------------------------------------------------------------------------------- /.github/actions/helmfile/main.js: -------------------------------------------------------------------------------- 1 | // Copyright The Helm Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // # You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // # See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | const spawnSync = require('child_process').spawnSync; 16 | const path = require("path"); 17 | 18 | const proc = spawnSync('bash', [path.join(__dirname, 'entrypoint.sh')], {stdio: 'inherit'}); 19 | process.exit(proc.status) -------------------------------------------------------------------------------- /.github/workflows/pr-test.yaml: -------------------------------------------------------------------------------- 1 | name: Test Deploy using Helmfile 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | lint-test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | 10 | - name: Checkout 11 | uses: actions/checkout@v1 12 | 13 | - name: Run helmfile lint 14 | uses: ./.github/actions/helmfile 15 | with: 16 | command: lint 17 | 18 | - name: Create kind cluster 19 | uses: helm/kind-action@v1.0.0-alpha.3 20 | with: 21 | install_local_path_provisioner: true 22 | node_image: kindest/node:v1.15.7@sha256:e2df133f80ef633c53c0200114fce2ed5e1f6947477dbc83261a6a921169488d 23 | env: 24 | KUBECONFIG: ./envs/default/kubeconfig 25 | 26 | - name: Run helmfile apply 27 | uses: ./.github/actions/helmfile 28 | with: 29 | command: apply 30 | env: 31 | KUBECONFIG: ./envs/default/kubeconfig 32 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM "ubuntu:latest" 2 | 3 | WORKDIR /tmp 4 | 5 | RUN apt-get update && apt-get install -yq curl git tree 6 | 7 | RUN \ 8 | curl -sSL https://get.helm.sh/helm-v3.1.1-linux-amd64.tar.gz | tar xzf - \ 9 | && cp linux-amd64/helm /bin/helm && chmod +x /bin/helm \ 10 | && helm plugin install https://github.com/databus23/helm-diff --version v3.1.1 11 | 12 | RUN \ 13 | curl -sSL https://github.com/roboll/helmfile/releases/download/v0.102.0/helmfile_linux_amd64 > /bin/helmfile \ 14 | && chmod +x /bin/helmfile 15 | 16 | RUN \ 17 | curl -sSL https://github.com/mikefarah/yq/releases/download/3.2.1/yq_linux_amd64 > /bin/yq \ 18 | && chmod +x /bin/yq 19 | 20 | RUN \ 21 | curl -sSL https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl > /bin/kubectl \ 22 | && chmod +x /bin/kubectl 23 | 24 | COPY . /pook 25 | 26 | # COPY entrypoint.sh /entrypoint.sh 27 | 28 | WORKDIR /pook 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Paul Czarkowski 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Platform Operations on Kubernetes (POOK) 2 | 3 | This project demonstrates how to set up and Platform Operations infrastructure on Kubernetes by providing a Reference Implementation of many platform level components such as CI, CD, Metrics, Logging, Policy Enforcement and security. 4 | 5 | It was designed using Pivotal Container Service (PKS) as the Kubernetes provider with RBAC being provided by UAA, but the default environment should work on any Kubernetes cluster with advanced features like Oauth2/openid integration and DNS/Cert management requiring certain platform pieces provided by the underlying cloud. 6 | 7 | We take advantage of a few tools to streamline things, firstly [Helm](https://helm.sh) as all of the infrastructure tooling is available in public Helm charts (although some charts may be vendored in here for custom changes). We use Helmfile to provide a wrapper over helm to allow for more complex installation workflows. 8 | 9 | With the goal of doing a gitops style workflow for deploying this, it is expected that you'll have seperate `env` directory(s) containing the customizations for a particular environment or cluster. 10 | 11 | For the most part you should just need to edit `envs/default/envs.sh` and fill it in with your details. This is a shell script that will export environment variables to be used by Helmfile. The reason for this is that if you have passwords/secrets you can store them outside of git and have the script extract them from wherever you keep them. 12 | 13 | ## Prerequisites 14 | 15 | > Note: helmfile can use helm2 in tillerless mode, or helm3. Either way, there is no need to run tiller in your cluster. 16 | 17 | It's expected that you already have the basic Kubernetes client tools like `kubectl` installed. 18 | 19 | * [kubectl](https://kubernetes.io) 20 | * [helm](https://helm.sh/docs/using_helm/#quickstart-guide) 21 | * [helmfile](https://github.com/roboll/helmfile#installation) 22 | * [helmdiff](https://github.com/databus23/helm-diff#install) 23 | * [helm tillerless](https://github.com/rimusz/helm-tiller#installation) 24 | 25 | A happy script: 26 | 27 | ```bash 28 | #!/bin/bash 29 | helm init --client-only || echo "probably helm3" 30 | helm plugin install https://github.com/databus23/helm-diff 31 | helm plugin install https://github.com/rimusz/helm-tiller 32 | wget -O ~/bin/helmfile https://github.com/roboll/helmfile/releases/download/v0.102.0/helmfile_linux_amd64 33 | chmod +x ~/bin/helmfile 34 | ``` 35 | 36 | 37 | ## Included Software 38 | 39 | ### Metrics and Observability 40 | 41 | * Grafana 42 | * Prometheus 43 | * EFK (Elasticsearch, Fluentd, Kibana) or Loki + PromTail 44 | 45 | ### CI / CD 46 | 47 | * Concourse 48 | * Harbor 49 | * Spinnaker 50 | 51 | ### Other 52 | 53 | * Minio (for Spinnaker and Harbor artifacts) 54 | 55 | ## Example Deployment 56 | 57 | ### Default environment 58 | 59 | This will deploy a default environment with no external auth or ingress set up. 60 | 61 | See [docs/default/install.md](docs/default/install.md) 62 | 63 | ### OIDC/UAA environment 64 | 65 | This will deploy an environment with Ingress, SSL, DNS, and UAA backed OIDC authentication for all apps. 66 | 67 | See [docs/gcp-uaa-openid/install.md](docs/gcp-uaa-openid/install.md) 68 | 69 | 70 | ## Customizing Platform Operations on Kubernetes 71 | 72 | Every Kubernetes cluster is different, just as every user of Kubernetes wants things installed differently. This gives us a fun challenge of needing to make it simple to deploy software, but also make the deployment flexible enough to suit most cases, and extendable for the rest. 73 | 74 | Thankfully `helm` and `helmfile` give us the tools we need to do this. Utilizing `helmfile` allows us to build a gitops style system where we have a code repo (this one) and one or more environment repos that provides the environment specific details. 75 | 76 | ### Code Repo 77 | 78 | In the Code Repo (this one) is a [helmfile.yaml](./helmfile.yaml) file that provides the fundamental work of installing our software by combining multiple helm charts together in an ordered and structured way. 79 | 80 | Like Helm charts the `helmfile.yaml` can be treated as a template and values can be rendered into it. We can utilize this functionality and put most of our logic into a seperate values file. 81 | 82 | The default set of values live in the [default environment](envs/default/values.yaml.gotmpl). This is used to specify which charts to install, their version, and the upstream Helm chart repository. 83 | 84 | Also inside the Code Repo is a set of values files, each chart has its own directory with at least a default `values.yaml.tmpl` file. This file is the equivalent of an individual Chart's values file except it also can be rendered as a template. This allows us to amongst other things load in environment variables for passwords and secrets so that they are not stored in source control. 85 | 86 | Each chart's values file can be overridden inside the primary values file by specifying an alternative location. 87 | 88 | ### Environment Repo 89 | 90 | The default (and other generic examples) environment is found inside this repo under `envs/default`. This contains the default `values.yaml.tmpl` file as described above. It can be modified to enable/disable specific Charts or to change the upstream repository or version. 91 | 92 | Also in the environment repo is an `envs.sh` file. This is a source file written in bash that contains exportable environment variables to further configure the environment. Values can be stored directly in this file, or they can be programmatically loaded from external sources. 93 | 94 | If you need to even further customize a chart you could copy that chart's `values.yaml.tmpl` file from the code repo into the environment repository and then modify it to suit. This gives you complete configurability of the Chart if you need it. 95 | -------------------------------------------------------------------------------- /charts.yaml: -------------------------------------------------------------------------------- 1 | ## A list of helm charts to be installed 2 | ## anything in here can be overridden in 3 | ## `$env_dir/charts.yaml.gotmpl` 4 | 5 | ## `values:` is a list of .yaml or .yaml.gotmpl 6 | ## files that helmfile applies as to the chart 7 | ## as that chart's. helmfile will merge them in 8 | ## order with ascending priority. 9 | 10 | ## `raw:` is a list of of resources that you want 11 | ## to be rendered as raw manifests. This is used to 12 | ## add secrets and certs and other things that the 13 | ## helm chart itself may not support. 14 | 15 | ## `secrets:` is a list of encrypted secrets 16 | ## see: https://github.com/roboll/helmfile#secrets 17 | 18 | ## Cluster Operations 19 | charts: 20 | clusterSystem: 21 | name: cluster-system-extras 22 | enabled: true 23 | namespace: cluster-system 24 | chart: ./charts/mystique 25 | values: 26 | - charts/cluster-system/helmfile/base.yaml.gotmpl 27 | 28 | ingress: 29 | enabled: false 30 | name: ingress 31 | namespace: cluster-system 32 | repository: 33 | name: stable 34 | url: https://kubernetes-charts.storage.googleapis.com 35 | chart: stable/nginx-ingress 36 | version: 1.6.17 37 | values: 38 | - charts/ingress/helmfile/base.yaml.gotmpl 39 | 40 | certManager: 41 | enabled: false 42 | repository: 43 | name: jetstack 44 | url: https://charts.jetstack.io 45 | name: cert-manager 46 | namespace: cluster-system 47 | chart: jetstack/cert-manager 48 | version: v0.13.0 49 | values: 50 | - charts/cert-manager/helmfile/base.yaml.gotmpl 51 | raw: 52 | - charts/cert-manager/helmfile/cluster-issuer.yaml.gotmpl 53 | 54 | externalDNS: 55 | enabled: false 56 | name: external-dns 57 | repository: 58 | name: stable 59 | url: https://kubernetes-charts.storage.googleapis.com 60 | namespace: cluster-system 61 | version: 2.6.4 62 | chart: stable/external-dns 63 | values: 64 | - charts/externaldns/helmfile/base.yaml.gotmpl 65 | 66 | ## CI/CD 67 | spinnaker: 68 | enabled: true 69 | repository: 70 | name: stable 71 | url: https://kubernetes-charts.storage.googleapis.com 72 | name: spinnaker 73 | namespace: spinnaker 74 | timeout: 600 75 | version: 2.0.0-rc1 76 | chart: stable/spinnaker 77 | values: 78 | - charts/spinnaker/helmfile/values.yaml.gotmpl 79 | raw: 80 | - charts/spinnaker/helmfile/secrets.yaml.gotmpl 81 | 82 | concourse: 83 | enabled: true 84 | repository: 85 | name: concourse 86 | url: https://concourse-charts.storage.googleapis.com 87 | name: concourse 88 | namespace: concourse 89 | chart: stable/concourse 90 | version: 8.3.7 91 | values: 92 | - charts/concourse/helmfile/values.yaml.gotmpl 93 | 94 | ## Artifact Storage 95 | 96 | minio: 97 | enabled: true 98 | repository: 99 | name: bitnami 100 | url: https://charts.bitnami.com/bitnami 101 | name: minio 102 | namespace: minio 103 | chart: bitnami/minio 104 | version: 2.2.0 105 | values: 106 | - charts/minio/helmfile/values.yaml.gotmpl 107 | 108 | harbor: 109 | enabled: true 110 | repository: 111 | name: harbor 112 | url: https://helm.goharbor.io 113 | name: harbor 114 | namespace: harbor 115 | chart: harbor/harbor 116 | version: 1.3.1 117 | values: 118 | - charts/harbor/helmfile/values.yaml.gotmpl 119 | raw: 120 | - charts/harbor/helmfile/secrets.yaml.gotmpl 121 | 122 | ## Metrics 123 | grafana: 124 | enabled: true 125 | repository: 126 | name: stable 127 | url: https://kubernetes-charts.storage.googleapis.com 128 | name: grafana 129 | namespace: metrics 130 | chart: stable/grafana 131 | version: 5.0.5 132 | values: 133 | - charts/grafana/helmfile/values.yaml.gotmpl 134 | 135 | prometheus: 136 | enabled: true 137 | repository: 138 | name: stable 139 | url: https://kubernetes-charts.storage.googleapis.com 140 | name: prometheus 141 | namespace: metrics 142 | chart: stable/prometheus 143 | version: 11.0.2 144 | values: 145 | - charts/prometheus/helmfile/values.yaml.gotmpl 146 | 147 | ## Logging 148 | ## Generally speaking you'll only enable one set of either Loki+Promtail, or ELK 149 | loki: 150 | enabled: true 151 | repository: 152 | url: https://grafana.github.io/loki/charts 153 | name: loki 154 | name: loki 155 | namespace: logging 156 | chart: loki/loki 157 | version: 0.25.1 158 | values: 159 | - charts/loki/helmfile/values.yaml.gotmpl 160 | raw: 161 | - charts/loki/helmfile/raw.yaml.gotmpl 162 | 163 | promtail: 164 | enabled: true 165 | repository: 166 | url: https://grafana.github.io/loki/charts 167 | name: loki 168 | name: promtail 169 | namespace: logging 170 | chart: loki/promtail 171 | version: 0.19.2 172 | values: 173 | - charts/promtail/helmfile/values.yaml.gotmpl 174 | 175 | elasticsearch: 176 | enabled: false 177 | repository: 178 | url: https://helm.elastic.co 179 | name: elastic 180 | name: elasticsearch 181 | namespace: logging 182 | chart: elastic/elasticsearch 183 | version: 7.4.1 184 | values: 185 | - charts/elasticsearch/helmfile/values.yaml.gotmpl 186 | raw: 187 | - charts/elasticsearch/helmfile/secrets.yaml.gotmpl 188 | 189 | kibana: 190 | enabled: false 191 | repository: 192 | url: https://helm.elastic.co 193 | name: elastic 194 | name: kibana 195 | namespace: logging 196 | chart: elastic/kibana 197 | version: 7.4.1 198 | values: 199 | - charts/kibana/helmfile/values.yaml.gotmpl 200 | 201 | fluentbit: 202 | enabled: false 203 | repository: 204 | name: stable 205 | url: https://kubernetes-charts.storage.googleapis.com 206 | name: fluentbit 207 | namespace: logging 208 | chart: stable/fluent-bit 209 | version: 2.7.3 210 | values: 211 | - charts/fluentbit/helmfile/values.yaml.gotmpl 212 | 213 | # misc 214 | kubeapps: 215 | enabled: true 216 | repository: 217 | url: https://charts.bitnami.com/bitnami 218 | name: bitnami 219 | name: kubeapps 220 | namespace: kubeapps 221 | chart: bitnami/kubeapps 222 | version: 3.4.3 223 | values: 224 | - charts/kubeapps/helmfile/values.yaml.gotmpl 225 | 226 | # wavefront 227 | wavefront: 228 | enabled: false 229 | repository: 230 | url: https://wavefronthq.github.io/helm/ 231 | name: wavefront 232 | chart: wavefront/wavefront 233 | name: wavefront 234 | namespace: wavefront 235 | version: 1.1.6 236 | values: 237 | - charts/wavefront/helmfile/values.yaml.gotmpl -------------------------------------------------------------------------------- /charts/cert-manager/helmfile/base.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | createCustomResource: false 2 | fullnameOverride: cert-manager 3 | ingressShim: 4 | resources: 5 | requests: 6 | cpu: 10m 7 | memory: 32Mi 8 | defaultIssuerName: letsencrypt-prod 9 | defaultIssuerKind: ClusterIssuer 10 | webhook: 11 | enabled: false 12 | resources: 13 | requests: 14 | cpu: 10m 15 | memory: 32Mi -------------------------------------------------------------------------------- /charts/cert-manager/helmfile/cluster-issuer.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | manifests: 2 | - metadata: 3 | name: letsencrypt-prod 4 | apiVersion: cert-manager.io/v1alpha2 5 | kind: ClusterIssuer 6 | spec: 7 | acme: 8 | server: https://acme-v02.api.letsencrypt.org/directory 9 | email: {{ requiredEnv "CERT_MANAGER_EMAIL" }} 10 | privateKeySecretRef: 11 | name: letsencrypt-prod 12 | solvers: 13 | - dns01: 14 | clouddns: 15 | project: {{ requiredEnv "GOOGLE_PROJECT_ID" }} 16 | serviceAccountSecretRef: 17 | name: google-credentials 18 | key: "credentials.json" 19 | -------------------------------------------------------------------------------- /charts/cluster-system/helmfile/base.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | manifests: 2 | - name: extra-config 3 | apiVersion: v1 4 | kind: ConfigMap 5 | body: 6 | {{- if eq (env "CLOUD_PROVIDER") "gcp" }} 7 | - name: google-credentials 8 | apiVersion: v1 9 | kind: Secret 10 | body: 11 | data: 12 | credentials.json: {{ requiredEnv "GOOGLE_APPLICATION_CREDENTIALS_SECRET" }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /charts/concourse/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | nameOverride: concourse 2 | fullnameOverride: concourse 3 | 4 | concourse: 5 | web: 6 | auth: 7 | mainTeam: 8 | localUser: admin 9 | {{- if eq (env "AUTH_TYPE") "uaa" }} 10 | oidc: 11 | user: {{ requiredEnv "CONCOURSE_OIDC_USER" }} 12 | {{- end }} 13 | {{- if eq (env "AUTH_TYPE") "uaa" }} 14 | oidc: 15 | enabled: true 16 | displayName: "Concourse UAA Auth" 17 | issuer: {{ requiredEnv "UAA_URL" }}/oauth/token 18 | useCaCert: true 19 | scope: "openid,roles,uaa.user" 20 | userNameKey: user_name 21 | {{- end }} 22 | clusterName: concourse 23 | externalUrl: {{ requiredEnv "CONCOURSE_URL" }} 24 | worker: 25 | baggageclaim: 26 | driver: overlay 27 | 28 | worker: 29 | enabled: true 30 | replicas: 2 31 | 32 | web: 33 | service: 34 | type: ClusterIP 35 | ingress: 36 | enabled: {{ .Values._.ingress.enabled }} 37 | hosts: [{{ env "CONCOURSE_DNS" }}] 38 | tls: 39 | - secretName: concourse-tls 40 | hosts: 41 | - {{ env "CONCOURSE_DNS" }} 42 | annotations: 43 | kubernetes.io/ingress.class: 'nginx' 44 | ingress.kubernetes.io/ssl-redirect: 'true' 45 | cert-manager.io/cluster-issuer: 'letsencrypt-prod' 46 | cert-manager.io/acme-challenge-type: 'dns01' 47 | cert-manager.io/acme-dns01-provider: 'prod-clouddns' 48 | kubernetes.io/tls-acme: 'true' 49 | 50 | secrets: 51 | localUsers: admin:{{ requiredEnv "CONCOURSE_ADMIN_PASSWORD" }} 52 | {{- if env "UAA_ROOT_CA_CERT" }} 53 | oidcCaCert: | 54 | {{- env "UAA_ROOT_CA_CERT" | nindent 12 }} 55 | {{- end }} 56 | {{- if eq (env "AUTH_TYPE") "uaa" }} 57 | oidcClientId: {{ requiredEnv "CONCOURSE_OIDC_CLIENT_ID" }} 58 | oidcClientSecret: {{ requiredEnv "CONCOURSE_OIDC_CLIENT_SECRET" }} 59 | {{- end }} -------------------------------------------------------------------------------- /charts/elasticsearch/helmfile/secrets.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | manifests: 2 | {{- if env "ELASTICSEARCH_PASSWORD" }} 3 | - metadata: 4 | name: elasticsearch-credentials 5 | apiVersion: v1 6 | kind: Secret 7 | data: 8 | password: {{ env "ELASTICSEARCH_PASSWORD" | b64enc }} 9 | {{- end }} 10 | - metadata: 11 | name: elastic-certificates 12 | apiVersion: v1 13 | kind: Secret 14 | type: kubernetes.io/tls 15 | data: 16 | tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBd082VmlKekhCZlhYMzJnZFh3ZVlZZ012Y2VNbTY3UWNicG04TXh3cXBKcWlkT1U5ClhETGV2ckU0eXB4NXIrYnFLNjZsOWpjT2E4bjNYMWt5dEZ2RTFUeFRoZnJjS21qNFlCcFM3dDQrNG80OFh4a2UKeDYybkh6dVAyOHdLSkNBRnA5UU9BR1FCTndFTGgyQ3Zjcm52TnExY21PRXpML1hlZXdaVE1IVFBobWdycTcxbwp2QU5INWFvVVh4ckw0VG5rZjVtOWRrL25veFNlU1ZMVnZjTVU2YWVDT3YwZGg5b1N4YjQ0K1NIaG9CM201WHBtCm95REpnaHlTT3JoWEZGWDJIRERaYWJhcVozWEhmQ0pSWExhVlFNUCt6eldKQnRLVWNqdHNWMzJmczRKTklYUGsKdkVTZHZWOWJjc0pDVHMvSmFvOGlNMFlRSjEvK3B4MmdNNlVnNHdJREFRQUJBb0lCQUNQVHFqMEdNQWN4VWZjUQpsSE96SzE3NERIVnZveWlkOTdHcUpzS3U5bFEreXZBK0taalhjWG1qMjFIMG9MeERlelRGWjloQy9SQ1RIcmE4CkQ2aGlhampXelFQU1E5UTBUZnM2cUMvbllYSWN5NlUxT3Z3RmlVVkpnRHRtdG5OaTV1bjFmT3docGdBYTE1TTYKSnhwODRLa2NwRmRYYW5QN2ltYjZFN1NwM0dldTJXUTFNVHBCVGtxblVzbzg2emJyb1F3WU4vMmtYU2VHOGFudwpEbnR2YXQxS2p2SmMzMHdGN2pZOVZRNW1qUXI4a2prczBtNkVUZDFOWFg1QU5oZ2d1QitQblpJRE1xa3FzSllqCnJoTEYyVDNsNzNQYVNZaHNiK2E3TmNjL1hoQ0hQOXRaWGJ4bldMenF4Qlo1Y282SCtaUHBEeTFWUjVYTWlKVlIKME9mc3N6RUNnWUVBK2FFQ3g1Mmc2ZjZBNFg3VmFNN2UramZiUzk0RVRnNFdrSG9TQzhWRi9jbTRPVi96Y1M1TAovTkNrSmJhWEIwbkpJSSt4R3d2TXJNdTI4UXdvNnBWbVREVEZmNHRWUmx5cnVKbmNkeTRTZ2hIOW1PaXBFbTg3CklLUmUwQzJZbWQrOTN6dUs3VW9ibzNGalpldlZWdlkrUzd3QitSVEEyL3ZoL3pSdDFHZ2tTcGNDZ1lFQXhkc2kKZzRNM1pySlVDZE1HWUd5MGhyOHlydVVSR3Q0Uks4bVVWUnZxREF1VnEwZ1d1T2o5ZStRZGFlT1kzOFlwd01tQQpMMHFlUmxRaTJNUHExZ3RFVGZsRFJxWnp6YmRLN1AvaWo1K2FNQ0gxODVsYXY2ZHBLdlNMRzhFZFUrbWR6T0dOCkQ3bTkxMyt6RWxIQ0J4SXNSRUgrNVpacGdJRmw0aUM1Z25paDRaVUNnWUI4QnlYTWJHTXhIOFNGUlhGZk83bkoKOU1xK3JUYlNXV21ZcXk0Z0x3b1JpSkpCMzR5akpXK1gwMHBiZXBjYmhldXFnL3BwQjduUCtQK1NVSXBiMDVNYQpOZllTNHZXaG1oV3dDTEpqZkw2eFphTHN3RnlRempkQWhxcWRJS3A3ZVpGclFyaEtJZElOcVI3TDJ4c0t0QnBMCm9zUVFMK0dLNjJGa1hYWmNYTW43VFFLQmdHa1lJL1lOTGRGTDZkMnFESm9OUTdyTE5tVzE0T2NQaTdsaGdudk8KcnZ3azd5UWl6NGI2b3lJNm9mRUw1cmorTGxGcjlyMm4rZmhMV3BNZlJjN1ovemNYcnNlSlJMdkJuM2ZSMTRzSQpjTU1lVnVGRTFQSTJQMk9FcjV0WGNYZVFBTFRDSGNaN2w3NHU0M1JZbnlKWVlkRUQ2UndVVUFmbE03UHdRL2xzCmtEZ2RBb0dBRHdWMkRraTVzenFFbXZPUjJxSStvaXRTaWxlelpYcWNiaFVORloxV1dnWXorN1JOREIwckxpNmQKN2wwbkZCOTQ1WlZ4cXJpWmd2WDBGR2NJQzF1Yk5PRUlvNk5VL2pWQ1JJYXZ1OEp2d1IreVN5VTFjT3hBWElIcAo3Mlc5VXRMRno0YldUODhUOTFFdHFFczNPMCszM1ppcEpOSW9saEpnL2RHZG82UHBGbzg9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== 17 | tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURpRENDQW5DZ0F3SUJBZ0lKQUlmbDBxRDc5Y3drTUEwR0NTcUdTSWIzRFFFQkN3VUFNQkl4RURBT0JnTlYKQkFNTUIzUmxjM1F0WTJFd0hoY05NakF3TVRFd01qQTFPREUwV2hjTk1qQXdNekV3TWpBMU9ERTBXakFmTVIwdwpHd1lEVlFRRERCUmxiR0Z6ZEdsamMyVmhjbU5vTFcxaGMzUmxjakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTUR1bFlpY3h3WDExOTlvSFY4SG1HSURMM0hqSnV1MEhHNlp2RE1jS3FTYW9uVGwKUFZ3eTNyNnhPTXFjZWEvbTZpdXVwZlkzRG12SjkxOVpNclJieE5VOFU0WDYzQ3BvK0dBYVV1N2VQdUtPUEY4WgpIc2V0cHg4N2o5dk1DaVFnQmFmVURnQmtBVGNCQzRkZ3IzSzU3emF0WEpqaE15LzEzbnNHVXpCMHo0Wm9LNnU5CmFMd0RSK1dxRkY4YXkrRTU1SCtadlhaUDU2TVVua2xTMWIzREZPbW5nanI5SFlmYUVzVytPUGtoNGFBZDV1VjYKWnFNZ3lZSWNranE0VnhSVjlod3cyV20ycW1kMXgzd2lVVnkybFVERC9zODFpUWJTbEhJN2JGZDluN09DVFNGego1THhFbmIxZlczTENRazdQeVdxUElqTkdFQ2RmL3FjZG9ET2xJT01DQXdFQUFhT0IwekNCMERBSkJnTlZIUk1FCkFqQUFNQXNHQTFVZER3UUVBd0lGNERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXcKZ1pZR0ExVWRFUVNCampDQmk0SWNaV3hoYzNScFkzTmxZWEpqYUMxdFlYTjBaWEl1Ykc5bloybHVaNElOWld4aApjM1JwWTNObFlYSmphSUlXWld4aGMzUnBZM05sWVhKamFDMXRZWE4wWlhJdE1JSVdaV3hoYzNScFkzTmxZWEpqCmFDMXRZWE4wWlhJdE1ZSVdaV3hoYzNScFkzTmxZWEpqYUMxdFlYTjBaWEl0TW9JVVpXeGhjM1JwWTNObFlYSmoKYUMxdFlYTjBaWEl3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUVQQm9FMU9DUTV1VTFkYjBVTFJnRDR5SzBFVgp4bHlMM1JlM3JOaytqRVY0cEo5cmI0VU40aVg2NklZellJOU1wVStGUmNZLzhzQlBWL3pGa2lJR1g1UlQ2OTBaCjJQakY1TkRaQXp3T0RieVVyaDJwK2N5RmxiTnlDc3RmdXg4eEd1VWhiaHJubzM1UHc0bXJsM1JjcDVtRy9YcCsKRjlEc1k4dkpRUDVpWUoxaHk5REh0STBZZ2xzS1g4WUZkVFdMak5nZWptZ1BxazNwbTNjWUljWTNIdHJ3SGxSYwpQajRaSVJCc0g2MDZHZDVXMWw3V3ZRTGxOd096RW9RY0psTzhveHFKYTRseVlzOUREZUR2Z2diSnV3bVZ2eUxuClBMUU9ySXoySXFPNnRadkU2ZzNTd05OWUJIcFJsajV5RWZMOTd0Vm9FYmM0MjlFVk9sMHpPdUZEOXBZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== 18 | ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNvRENDQVlnQ0NRREM4aFdHL2ZscGZ6QU5CZ2txaGtpRzl3MEJBUXNGQURBU01SQXdEZ1lEVlFRRERBZDAKWlhOMExXTmhNQjRYRFRJd01ERXhNREl3TkRrek1Gb1hEVEl3TURNeE1ESXdORGt6TUZvd0VqRVFNQTRHQTFVRQpBd3dIZEdWemRDMWpZVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMMmVGbzdyCkEySWZiQXorb0JJUlE5UUh3em1vRWlCdm9ROXFUVWF1VDdCRDJzTHl2MWJHRHV4TGN4N1lJbE10U0w5blRjdjIKS25uNm44UzJybWVuRVlqTTdVNG90dFNGd2pET09aRDRVenMrWWdqSjBYVWE5Q2czL2hPZmRpT1M3S1JER0llTwpJbVN0QW94QkhDUU1nVi9XU2VVbUZtUU4rMjFoVDdHMTd1anJsVW12OUl5Nzh5SHBLQXpMd2pLcTk1c3BZblpFCmpyaWJRUzZ1VWlUTDZCTGtOZDl5c0laSXgvOWtwdlBrUkd3S2M3Z2tmMzBPSUFuOGVkV2RzRnRUVlVWZG9vc2gKOFA2SEhkdjJoczhCMDBtUVYrODBwck1IRGxhKzhyYitwb2luR1p3SUI4MXNMaWUzYVg1MVRKVTJyN3UrNGdyRApzZ3NZeU91ZkN6QU5NTmNDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFHdmF0dEN6TW5DM0lFNG83CnpteFdCL1lJUjBWQVZwYlJCNjFJY0FuYU8wTWJ1KzN3c3NHbk9PZC91UEU1MjBLRUs0YlBkUHVhSVA0OE5yN2wKb0wyWmlOTFowTW1tVWpSaUJzQTFXRndBN0o4S3lNZzJRZkZ0MGJRT1c4aWE3b29IUmNiSnJZcVF4SHphMmY3NApmS1RXT2lqbktla3RyOXorcS9CMGhCUlFTenY5VWNXNXFCZm1OUlZGVWYvSDI1SlJtVzhOV2VZRHRYV0pLUEptCmVPZ2JUV01ZREZla2dsNlBqMHpiZ2N3VVdTcVMrMjlkUnpNanV5c1pQYnV1ekxMMkdZMWNPSy92ZWRMcGRuZWUKQW91MXZDcnoxMWFPbUFLZEo2Qjd1dEZ1WnJvc2RjS2JmMXJiRGVhYlpLbGlQellPRnIzRkYwVE9oblVtb0lDSApmNElQanc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== 19 | {{- if eq (env "AUTH_TYPE") "uaa" }} 20 | - metadata: 21 | name: elastic-oidc-client 22 | apiVersion: v1 23 | kind: Secret 24 | data: 25 | client-secret: {{ requiredEnv "ELASTICSEARCH_OIDC_CLIENT_SECRET" | b64enc }} 26 | {{- end }} -------------------------------------------------------------------------------- /charts/elasticsearch/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | clusterName: elasticsearch 2 | replicas: 3 3 | 4 | rbac: 5 | create: true 6 | 7 | nodeGroup: "master" 8 | 9 | sysctlInitContainer: 10 | enabled: false 11 | 12 | roles: 13 | master: "true" 14 | ingest: "true" 15 | data: "true" 16 | 17 | protocol: https 18 | 19 | secretMounts: 20 | - name: elastic-certificates 21 | secretName: elastic-certificates 22 | path: /usr/share/elasticsearch/config/certs 23 | 24 | esConfig: 25 | elasticsearch.yml: | 26 | xpack.security.enabled: true 27 | xpack.security.transport.ssl.enabled: true 28 | xpack.security.transport.ssl.verification_mode: certificate 29 | xpack.security.transport.ssl.key: /usr/share/elasticsearch/config/certs/tls.key 30 | xpack.security.transport.ssl.certificate: /usr/share/elasticsearch/config/certs/tls.crt 31 | xpack.security.transport.ssl.certificate_authorities: ["/usr/share/elasticsearch/config/certs/ca.crt"] 32 | xpack.security.http.ssl.enabled: true 33 | xpack.security.http.ssl.verification_mode: certificate 34 | xpack.security.http.ssl.key: /usr/share/elasticsearch/config/certs/tls.key 35 | xpack.security.http.ssl.certificate: /usr/share/elasticsearch/config/certs/tls.crt 36 | xpack.security.http.ssl.certificate_authorities: ["/usr/share/elasticsearch/config/certs/ca.crt"] 37 | {{- if eq "uaa" (env "AUTH_TYPE") }} 38 | xpack.security.authc.token.enabled: true 39 | xpack.security.authc.realms.oidc.oidc1: 40 | order: 2 41 | rp.client_id: "{{ env "ELASTICSEARCH_OIDC_CLIENT_ID" }}" 42 | rp.response_type: code 43 | rp.redirect_uri: "{{ env "KIBANA_URL" }}/api/security/v1/oidc" 44 | op.issuer: "{{ env "ELASTICSEARCH_OIDC_TOKEN_URL" }}" 45 | op.authorization_endpoint: "{{ env "ELASTICSEARCH_OIDC_AUTH_URL" }}" 46 | op.token_endpoint: "{{ env "ELASTICSEARCH_OIDC_TOKEN_URL" }}" 47 | op.jwkset_path: "{{ env "ELASTICSEARCH_OIDC_JWKS_URL" }}" 48 | op.userinfo_endpoint: "{{ env "ELASTICSEARCH_OIDC_USERINFO_URL" }}" 49 | op.endsession_endpoint: "{{ env "ELASTICSEARCH_OIDC_LOGOUT_URL" }}" 50 | rp.post_logout_redirect_uri: "{{ env "KIBANA_URL" }}/logged_out" 51 | claims.principal: user_name 52 | #claims.groups: "http://example.info/claims/groups" 53 | {{- end }} 54 | {{- if env "ELASTICSEARCH_PASSWORD" }} 55 | extraEnvs: 56 | - name: "ELASTIC_PASSWORD" 57 | valueFrom: 58 | secretKeyRef: 59 | name: elasticsearch-credentials 60 | key: password 61 | - name: "ELASTIC_USERNAME" 62 | value: {{ requiredEnv "ELASTICSEARCH_USERNAME" | quote }} 63 | {{- end }} 64 | 65 | {{- if eq "uaa" (env "AUTH_TYPE") }} 66 | keystore: 67 | - secretName: elastic-oidc-client 68 | items: 69 | - key: client-secret 70 | path: xpack.security.authc.realms.oidc.oidc1.rp.client_secret 71 | {{- end }} -------------------------------------------------------------------------------- /charts/externaldns/helmfile/base.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | sources: 2 | - service 3 | - ingress 4 | rbac: 5 | create: "true" 6 | provider: google 7 | google: 8 | project: {{ env "GOOGLE_PROJECT_ID" }} 9 | serviceAccountSecret: {{ requiredEnv "EXTERNAL_DNS_SECRET" }} 10 | domainFilters: 11 | - {{ requiredEnv "EXTERNAL_DNS_DOMAIN" }} 12 | resources: 13 | limits: 14 | memory: 50Mi 15 | cpu: 100m 16 | requests: 17 | memory: 50Mi 18 | cpu: 10m -------------------------------------------------------------------------------- /charts/fluentbit/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | nameOverride: fluentbit 2 | fullnameOverride: fluentbit 3 | 4 | backend: 5 | type: es 6 | es: 7 | host: elasticsearch-master.{{ .Values.elasticsearch.namespace }} 8 | {{- if env "ELASTICSEARCH_PASSWORD" }} 9 | http_user: {{ requiredEnv "ELASTICSEARCH_USERNAME" }} 10 | http_passwd_secret: elasticsearch-credentials 11 | http_passwd_secret_key: password 12 | {{- end }} 13 | tls: "on" 14 | tls_verify: "off" 15 | 16 | image: 17 | fluent_bit: 18 | tag: 1.2.2-debug 19 | 20 | service: 21 | logLevel: debug 22 | 23 | securityContext: 24 | runAsUser: 0 25 | 26 | extraVolumes: 27 | - hostPath: 28 | path: /var/vcap/store 29 | name: varvcapstore 30 | - hostPath: 31 | path: /var/vcap/data 32 | name: varvcapdata 33 | 34 | extraVolumeMounts: 35 | - mountPath: /var/vcap/store 36 | name: varvcapstore 37 | readOnly: true 38 | - mountPath: /var/vcap/data 39 | name: varvcapdata 40 | readOnly: true 41 | -------------------------------------------------------------------------------- /charts/gangway/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/gangway/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: An application that can be used to easily enable authentication flows via OIDC for a kubernetes cluster. 3 | name: gangway 4 | version: 0.4.0 5 | appVersion: 3.3.0 6 | home: https://github.com/heptiolabs/gangway 7 | sources: 8 | - https://github.com/heptiolabs/gangway 9 | engine: gotpl 10 | maintainers: 11 | - name: rk295 12 | email: robin@kearney.co.uk 13 | -------------------------------------------------------------------------------- /charts/gangway/OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - rk295 3 | reviewers: 4 | - rk295 5 | 6 | -------------------------------------------------------------------------------- /charts/gangway/README.md: -------------------------------------------------------------------------------- 1 | # Gangway 2 | 3 | An application that can be used to easily enable authentication flows via OIDC for a kubernetes cluster. 4 | 5 | ## TL;DR 6 | 7 | helm install stable/gangway 8 | 9 | ## Introduction 10 | 11 | The chart deploys an instance of Gangway into a Kubernetes cluster using the Helm package manager. 12 | 13 | This chart will do the following: 14 | 15 | * Create a deployment of [gangway] within your Kubernetes Cluster. 16 | 17 | ## Installing the Chart 18 | 19 | To install the chart with the release name `my-release`: 20 | 21 | ```bash 22 | helm install --name my-release stable/gangway 23 | ``` 24 | 25 | Due to the nature of OIDC configuration, deploying the chart without at least some of the values being set will not result in a functioning application. See the Configuration section below for more information. 26 | 27 | ## Configuration 28 | 29 | The following table lists the configurable parameters of the external-dns chart and their default values. 30 | 31 | All values under the `gangway` top level object are passed directly to the Gangway container via a `yaml` config file. The contents of that object in [`values.yaml`](values.yaml) are lifted directly from the Gangway [documentation](https://github.com/heptiolabs/gangway/tree/master/docs). 32 | 33 | At a minimum you *must* configure any of the values marked as **required** in the table below. 34 | 35 | | Parameter | Description | Default | 36 | | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | 37 | | `affinity` | List of affinities (requires Kubernetes >=1.6) | `{}` | 38 | | `extraVolumes` | List of extra volumes | `[]` | 39 | | `extraVolumeMounts` | List of extra volumeMounts | `[]` | 40 | | `gangway.allowEmptyClientSecret` | Some identity providers accept an empty client secret, this is not generally considered a good idea. If you have to use an empty secret and accept the risks that come with that then you can set this to true. | `false` | 41 | | `gangway.apiServerURL` | The API server endpoint used to configure kubectl. **Required** | `""` | 42 | | `gangway.audience` | Endpoint that provides user profile information [optional]. Not all providers will require this. To be taken from the configuration of your OIDC provider. **Required** | `""` | 43 | | `gangway.authorizeURL` | OAuth2 URL to start authorization flow. To be taken from the configuration of your OIDC provider. **Required** | `""` | 44 | | `gangway.certFile` | The public cert file (including root and intermediates) to use when serving TLS. | `/etc/gangway/tls/tls.crt` | 45 | | `gangway.clientID` | API client ID as indicated by the identity provider. **Required** | `""` | 46 | | `gangway.clientSecret` | API client secret as indicated by the identity provider. **Required** | `""` | 47 | | `gangway.cluster_ca_path` | The path to find the CA bundle for the API server. Used to configure kubectl. This is typically mounted into the default location for workloads running on a Kubernetes cluster and doesn't need to be set. | `""` | 48 | | `gangway.clusterName` | The cluster name. Used in UI and kubectl config instructions. **Required** | `""` | 49 | | `gangway.host` | The address to listen on. Defaults to 0.0.0.0 to listen on all interfaces. | `80` | 50 | | `gangway.httpPath` | The path gangway uses to create urls (defaults to "") | `/` | 51 | | `gangway.keyFile` | The private key file when serving TLS. | `/etc/gangway/tls/tls.key` | 52 | | `gangway.port` | The port to listen on. Defaults to 8080. | `80` | 53 | | `gangway.redirectURL` | Where to redirect back to. This should be a URL where gangway is reachable. Typically this also needs to be registered as part of the oauth application with the oAuth provider. **Required** | `""` | 54 | | `gangway.scopes` | Used to specify the scope of the requested Oauth authorization. | `["openid", "profile", "email", "offline_access"]` | 55 | | `gangway.serveTLS` | Should Gangway serve TLS vs. plain HTTP? | `false` | 56 | | `gangway.sessionKey` | Encryption key for cookie contents. Will autogenerate if not provided. Caution: Do not use auto generation in production environments. | `""` | 57 | | `gangway.tokenURL` | OAuth2 URL to obtain access tokens. To be taken from the configuration of your OIDC provider. **Required** | `""` | 58 | | `gangway.trustedCAPath` | The path to a root CA to trust for self signed certificates at the Oauth2 URLs | `""` | 59 | | `gangway.usernameClaim` | The JWT claim to use as the username. This is used in UI. Default is "nickname". This is combined with the clusterName for the "user" portion of the kubeconfig. | `name` | 60 | | `trustedCACert` | Specify a CA cert to trust for self signed certificates at the Oauth2 URLs. | `""` | 61 | | `image.repository` | Container image name (Including repository name if not `hub.docker.com`). | `gcr.io/heptio-images/gangway` | 62 | | `image.pullPolicy` | Container pull policy. | `IfNotPresent` | 63 | | `image.tag` | Container image tag. | `v3.2.0` | 64 | | `image.pullSecrets` | Name of Secret resource containing private registry credentials | `""` | 65 | | `ingress.annotations` | Ingress annotations | `{}` | 66 | | `ingress.enabled` | Enables or Disables the ingress resource | `false` | 67 | | `ingress.hosts` | List of FQDN's for the ingress | `""` | 68 | | `ingress.tls.hosts` | List of FQDN's the above secret is associated with | `""` | 69 | | `ingress.tls.secretName` | Name of the secret to use | `""` | 70 | | `ingress.tls` | List of SSL certs to use | `""` | 71 | | `livenessProbe.scheme` | Scheme to use for httpGet probe, `HTTP` or `HTTPS`. | `HTTP` | 72 | | `nodeSelector` | Node labels for pod assignment | `{}` | 73 | | `podAnnotations` | Additional annotations to apply to the pod. | `{}` | 74 | | `resources` | CPU/Memory resource requests/limits. | `{}` | 75 | | `readinessProbe.scheme` | Scheme to use for httpGet probe, `HTTP` or `HTTPS`. | `HTTP` | 76 | | `service.port` | The port the service should listen on | `80` | 77 | | `service.type` | Type of service to create | `ClusterIP` | 78 | | `tls.certData` | The Public cert data. This is normally safe to leave alone. | `""` | 79 | | `tls.existingSecret` | An existing secret with a `tls.crt` and `tls.key` | `""` | 80 | | `tls.keyData` | The Private key data | `""` | 81 | | `tolerations` | List of node taints to tolerate (requires Kubernetes >= 1.6) | `[]` | 82 | 83 | You will likely want to expose Gangway to your users somehow, possibly by way of an ingress, the values below would be a way of doing this with the [Traefik] ingress controller, this assumes TLS offload is happening at the load balancer: 84 | 85 | ```yaml 86 | ingress: 87 | enabled: true 88 | annotations: 89 | kubernetes.io/ingress.class: traefik 90 | path: / 91 | hosts: 92 | - gangway.your-domain.com 93 | tls: [] 94 | ``` 95 | 96 | ## Note about `gangway.sessionKey` 97 | 98 | The chart will auto generate a random value for `gangway.sessionKey` when you install the chart. Gangway uses this via the [Gorilla Secure Cookie] Go library to encrypt the contents of cookies sent to the users browser. Relying on the autogeneration is acceptable in testing environments, however in production you are strongly advised to provide your own random value for this variable. If you do not and you subsequently update your Helm deployment this key will be regenerated. This has the impact that any cookies in your users browsers from before the upgrade, will have been encrypted with the old key, which Gangway no longer has. Therefore when they browse to your Gangway url they will get an error when they attempt to login. The only solution to that issue is to have the user delete all the gangway cookies from their browser. You have been warned! 99 | 100 | ### Specifying Values 101 | 102 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 103 | 104 | ```console 105 | $ helm upgrade --install --wait my-release \ 106 | --set ingress.enabled=true \ 107 | stable/gangway 108 | ``` 109 | 110 | Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, 111 | 112 | ```console 113 | $ helm upgrade --install --wait my-release stable/gangway -f values.yaml 114 | ``` 115 | 116 | > **Tip**: You can copy the default [values.yaml](values.yaml) and make any required edits in there 117 | 118 | [gangway]: https://github.com/heptiolabs/gangway 119 | [gangway docs]: https://github.com/heptiolabs/gangway/tree/master/docs 120 | [Traefik]: https://docs.traefik.io/user-guide/kubernetes/ 121 | [Gorilla Secure Cookie]: https://github.com/gorilla/securecookie 122 | 123 | ## SSL Configuration 124 | 125 | 1. Edit `values.yaml` 126 | 1. Set `gangway.serveTLS` to `true`. 127 | 1. Set `livenessProbe.scheme` and `readinessProbe.scheme` to `HTTPS`. 128 | 2. Pass the TLS configuration to Gangway: 129 | - Either by pasting the certificate and private key in the `values.yaml` like: 130 | 131 | ```yaml 132 | tls: 133 | certData: | 134 | -----BEGIN CERTIFICATE----- 135 | ... 136 | -----END CERTIFICATE----- 137 | keyData: | 138 | -----BEGIN ENCRYPTED PRIVATE KEY----- 139 | ... 140 | -----END ENCRYPTED PRIVATE KEY----- 141 | ``` 142 | 143 | - Or by specifying an existing secret in the `values.yaml` like: 144 | 145 | ```yaml 146 | ... 147 | tls: 148 | existingSecret: my-tls-secret 149 | ... 150 | ``` 151 | 152 | > NB: The secret _must_ contain two entries, `tls.crt` and `tls.key`; 153 | > it will be mounted into `/etc/gangway/tls/` and e.g. 154 | > `/etc/gangway/tls/tls.crt` is the default path for `gangway.certFile`. 155 | > Otherwise adjust `gangway.certFile` and `gangway.keyFile` accordingly. 156 | -------------------------------------------------------------------------------- /charts/gangway/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range .Values.ingress.hosts }} 4 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "gangway.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get svc -w {{ include "gangway.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "gangway.fullname" . }}svc -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 14 | echo http://$SERVICE_IP:{{ .Values.service.port }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "gangway.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | echo "Visit http://127.0.0.1:8080 to use your application" 18 | kubectl port-forward $POD_NAME 8080:80 19 | {{- end }} -------------------------------------------------------------------------------- /charts/gangway/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "gangway.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "gangway.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "gangway.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /charts/gangway/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ include "gangway.fullname" . }} 5 | labels: 6 | app.kubernetes.io/name: {{ include "gangway.name" . }} 7 | helm.sh/chart: {{ include "gangway.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | data: 11 | gangway.yaml: | 12 | {{- .Values.gangway | toYaml | nindent 4 }} 13 | {{- if .Values.trustedCACert }} 14 | trustedCAPath: /gangway/rootca.crt 15 | rootca.crt: | 16 | {{- .Values.trustedCACert | nindent 4}} 17 | {{ end }} 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /charts/gangway/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "gangway.fullname" . }} 5 | labels: 6 | app.kubernetes.io/name: {{ include "gangway.name" . }} 7 | helm.sh/chart: {{ include "gangway.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | selector: 13 | matchLabels: 14 | app.kubernetes.io/name: {{ include "gangway.name" . }} 15 | app.kubernetes.io/instance: {{ .Release.Name }} 16 | template: 17 | metadata: 18 | labels: 19 | app.kubernetes.io/name: {{ include "gangway.name" . }} 20 | app.kubernetes.io/instance: {{ .Release.Name }} 21 | annotations: 22 | check/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} 23 | check/values: {{ .Files.Get "../values.yaml" | sha256sum }} 24 | spec: 25 | {{- if .Values.image.pullSecrets }} 26 | imagePullSecrets: 27 | {{ toYaml .Values.image.pullSecrets | indent 8 }} 28 | {{- end }} 29 | containers: 30 | - name: {{ .Chart.Name }} 31 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 32 | imagePullPolicy: {{ .Values.image.pullPolicy }} 33 | command: 34 | - gangway 35 | - -config 36 | - /gangway/gangway.yaml 37 | env: 38 | - name: GANGWAY_SESSION_SECURITY_KEY 39 | valueFrom: 40 | secretKeyRef: 41 | key: sessionkey 42 | name: {{ include "gangway.fullname" . }}-key 43 | ports: 44 | - name: http 45 | containerPort: {{ .Values.gangway.port }} 46 | protocol: TCP 47 | volumeMounts: 48 | - name: gangway 49 | mountPath: /gangway/ 50 | {{- if or (and .Values.tls.certData .Values.tls.keyData) .Values.tls.existingSecret }} 51 | - name: gangway-tls 52 | mountPath: /etc/gangway/tls/ 53 | readOnly: true 54 | {{ end }} 55 | {{- if .Values.extraVolumeMounts }} 56 | {{ toYaml .Values.extraVolumeMounts | trim | indent 8 }} 57 | {{- end }} 58 | livenessProbe: 59 | failureThreshold: 3 60 | httpGet: 61 | path: {{ .Values.gangway.httpPath }} 62 | port: {{ .Values.gangway.port }} 63 | scheme: {{ .Values.livenessProbe.scheme }} 64 | initialDelaySeconds: 20 65 | periodSeconds: 60 66 | successThreshold: 1 67 | timeoutSeconds: 1 68 | readinessProbe: 69 | failureThreshold: 3 70 | httpGet: 71 | path: {{ .Values.gangway.httpPath }} 72 | port: {{ .Values.gangway.port }} 73 | scheme: {{ .Values.readinessProbe.scheme }} 74 | periodSeconds: 10 75 | successThreshold: 1 76 | timeoutSeconds: 1 77 | resources: 78 | {{ toYaml .Values.resources | indent 10 }} 79 | {{- with .Values.nodeSelector }} 80 | nodeSelector: 81 | {{ toYaml . | indent 8 }} 82 | {{- end }} 83 | {{- with .Values.affinity }} 84 | affinity: 85 | {{ toYaml . | indent 8 }} 86 | {{- end }} 87 | {{- with .Values.tolerations }} 88 | tolerations: 89 | {{ toYaml . | indent 8 }} 90 | {{- end }} 91 | volumes: 92 | - name: gangway 93 | configMap: 94 | name: {{ include "gangway.fullname" . }} 95 | {{- if and .Values.tls.certData .Values.tls.keyData }} 96 | - name: gangway-tls 97 | secret: 98 | secretName: {{ include "gangway.fullname" . }}-tls 99 | {{ else if .Values.tls.existingSecret }} 100 | - name: gangway-tls 101 | secret: 102 | secretName: {{ .Values.tls.existingSecret }} 103 | {{ end -}} 104 | {{- if .Values.extraVolumes }} 105 | {{ toYaml .Values.extraVolumes | trim | indent 6 }} 106 | {{- end }} 107 | -------------------------------------------------------------------------------- /charts/gangway/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "gangway.fullname" . -}} 3 | {{- $ingressPath := .Values.ingress.path -}} 4 | {{- if $.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- else }} 7 | apiVersion: extensions/v1beta1 8 | {{- end }} 9 | kind: Ingress 10 | metadata: 11 | name: {{ $fullName }} 12 | labels: 13 | app.kubernetes.io/name: {{ include "gangway.name" . }} 14 | helm.sh/chart: {{ include "gangway.chart" . }} 15 | app.kubernetes.io/instance: {{ .Release.Name }} 16 | app.kubernetes.io/managed-by: {{ .Release.Service }} 17 | {{- with .Values.ingress.annotations }} 18 | annotations: 19 | {{ toYaml . | indent 4 }} 20 | {{- end }} 21 | spec: 22 | {{- if .Values.ingress.tls }} 23 | tls: 24 | {{- range .Values.ingress.tls }} 25 | - hosts: 26 | {{- range .hosts }} 27 | - {{ . | quote }} 28 | {{- end }} 29 | secretName: {{ .secretName }} 30 | {{- end }} 31 | {{- end }} 32 | rules: 33 | {{- range .Values.ingress.hosts }} 34 | - host: {{ . | quote }} 35 | http: 36 | paths: 37 | - path: {{ $ingressPath }} 38 | backend: 39 | serviceName: {{ $fullName }}svc 40 | servicePort: http 41 | {{- end }} 42 | {{- end }} 43 | -------------------------------------------------------------------------------- /charts/gangway/templates/key.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ include "gangway.fullname" . }}-key 5 | labels: 6 | app.kubernetes.io/name: {{ include "gangway.name" . }} 7 | helm.sh/chart: {{ include "gangway.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | type: Opaque 11 | data: 12 | sessionkey: {{ ( default ( randAlphaNum 32 ) .Values.gangway.sessionKey ) | b64enc | quote }} -------------------------------------------------------------------------------- /charts/gangway/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | # Need to append "svc" here because otherwise Kube will make an env var 5 | # called GANGWAY_PORT with something like "tcp://100.67.143.54:80" as a value. 6 | # The gangway binary then interprets this as a config variable and expects it 7 | # to hold the int for the port to listen on. Result = bang! 8 | name: {{ include "gangway.fullname" . }}svc 9 | labels: 10 | app.kubernetes.io/name: {{ include "gangway.name" . }} 11 | helm.sh/chart: {{ include "gangway.chart" . }} 12 | app.kubernetes.io/instance: {{ .Release.Name }} 13 | app.kubernetes.io/managed-by: {{ .Release.Service }} 14 | spec: 15 | type: {{ .Values.service.type }} 16 | ports: 17 | - port: {{ .Values.service.port }} 18 | targetPort: {{ .Values.gangway.port }} 19 | protocol: TCP 20 | name: http 21 | {{- if and (eq "LoadBalancer" $.Values.service.type) (.Values.service.loadBalancerIP) }} 22 | loadBalancerIP: {{ .Values.service.loadBalancerIP }} 23 | {{- end}} 24 | selector: 25 | app.kubernetes.io/name: {{ include "gangway.name" . }} 26 | app.kubernetes.io/instance: {{ .Release.Name }} 27 | -------------------------------------------------------------------------------- /charts/gangway/templates/ssl.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.tls.certData .Values.tls.keyData -}} 2 | apiVersion: v1 3 | type: kubernetes.io/tls 4 | kind: Secret 5 | metadata: 6 | name: {{ include "gangway.fullname" . }}-tls 7 | labels: 8 | app.kubernetes.io/name: {{ include "gangway.name" . }} 9 | helm.sh/chart: {{ include "gangway.chart" . }} 10 | app.kubernetes.io/instance: {{ .Release.Name }} 11 | app.kubernetes.io/managed-by: {{ .Release.Service }} 12 | data: 13 | tls.crt: {{ .Values.tls.certData | b64enc }} 14 | tls.key: {{ .Values.tls.keyData | b64enc }} 15 | {{- end -}} 16 | -------------------------------------------------------------------------------- /charts/gangway/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | 3 | image: 4 | repository: gcr.io/heptio-images/gangway 5 | tag: v3.2.0 6 | pullPolicy: IfNotPresent 7 | ## Optional array of imagePullSecrets containing private registry credentials 8 | ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ 9 | pullSecrets: [] 10 | # - name: secretName 11 | 12 | nameOverride: "" 13 | fullnameOverride: "" 14 | 15 | # Specify a CA cert to trust for self signed certificates at the Oauth2 URLs. Be careful to indent one level beyond the 16 | # trustedCACert key: 17 | # trustedCACert: |- 18 | # -----BEGIN CERTIFICATE----- 19 | # ... 20 | # -----END CERTIFICATE----- 21 | 22 | gangway: 23 | # The address to listen on. Defaults to 0.0.0.0 to listen on all interfaces. 24 | # Env var: GANGWAY_HOST 25 | # host: 0.0.0.0 26 | 27 | # The port to listen on. Defaults to 8080. 28 | # Env var: GANGWAY_PORT 29 | port: 8080 30 | 31 | # Should Gangway serve TLS vs. plain HTTP? Default: false 32 | # Env var: GANGWAY_SERVE_TLS 33 | # serveTLS: false 34 | 35 | # The public cert file (including root and intermediates) to use when serving TLS. 36 | # Env var: GANGWAY_CERT_FILE 37 | # certFile: /etc/gangway/tls/tls.crt 38 | 39 | # The private key file when serving TLS. 40 | # Env var: GANGWAY_KEY_FILE 41 | # keyFile: /etc/gangway/tls/tls.key 42 | 43 | # The cluster name. Used in UI and kubectl config instructions. 44 | # Env var: GANGWAY_CLUSTER_NAME 45 | clusterName: "${GANGWAY_CLUSTER_NAME}" 46 | 47 | # OAuth2 URL to start authorization flow. 48 | # Env var: GANGWAY_AUTHORIZE_URL 49 | authorizeURL: "https://${DNS_NAME}/authorize" 50 | 51 | # OAuth2 URL to obtain access tokens. 52 | # Env var: GANGWAY_TOKEN_URL 53 | tokenURL: "https://${DNS_NAME}/oauth/token" 54 | 55 | # Endpoint that provides user profile information [optional]. Not all providers 56 | # will require this. 57 | # Env var: GANGWAY_AUDIENCE 58 | audience: "https://${DNS_NAME}/userinfo" 59 | 60 | # Used to specify the scope of the requested Oauth authorization. 61 | scopes: ["openid", "profile", "email", "offline_access"] 62 | 63 | # Where to redirect back to. This should be a URL where gangway is reachable. 64 | # Typically this also needs to be registered as part of the oauth application 65 | # with the oAuth provider. 66 | # Env var: GANGWAY_REDIRECT_URL 67 | redirectURL: "https://${GANGWAY_REDIRECT_URL}/callback" 68 | 69 | # API client ID as indicated by the identity provider 70 | # Env var: GANGWAY_CLIENT_ID 71 | clientID: "${GANGWAY_CLIENT_ID}" 72 | 73 | # API client secret as indicated by the identity provider 74 | # Env var: GANGWAY_CLIENT_SECRET 75 | clientSecret: "${GANGWAY_CLIENT_SECRET}" 76 | 77 | # Some identity providers accept an empty client secret, this 78 | # is not generally considered a good idea. If you have to use an 79 | # empty secret and accept the risks that come with that then you can 80 | # set this to true. 81 | # allowEmptyClientSecret: false 82 | 83 | # The JWT claim to use as the username. This is used in UI. 84 | # Default is "nickname". This is combined with the clusterName 85 | # for the "user" portion of the kubeconfig. 86 | # Env var: GANGWAY_USERNAME_CLAIM 87 | usernameClaim: "sub" 88 | 89 | # The API server endpoint used to configure kubectl 90 | # Env var: GANGWAY_APISERVER_URL 91 | apiServerURL: "https://${GANGWAY_APISERVER_URL}" 92 | 93 | # The path to find the CA bundle for the API server. Used to configure kubectl. 94 | # This is typically mounted into the default location for workloads running on 95 | # a Kubernetes cluster and doesn't need to be set. 96 | # Env var: GANGWAY_CLUSTER_CA_PATH 97 | # cluster_ca_path: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" 98 | 99 | 100 | # The path gangway uses to create urls (defaults to "") 101 | # Env var: GANGWAY_HTTP_PATH 102 | # httpPath: "https://${GANGWAY_HTTP_PATH}" 103 | 104 | # The key to use when encrypting the contents of cookies. 105 | # You can leave this blank and the chart will generate a random key, however 106 | # you must use that with caution. Subsequent upgrades to the deployment will 107 | # regenerate this key which will cause Gangway to error when attempting to 108 | # decrypt cookies stored in users' browsers which were encrypted with the old 109 | # key. 110 | # TL;DR: Safe to use the auto generation in test environments, provide your 111 | # own in procution. 112 | # sessionKey: 113 | 114 | tls: {} 115 | # certData: | 116 | # -----BEGIN CERTIFICATE----- 117 | # ... 118 | # -----END CERTIFICATE----- 119 | # keyData: | 120 | # -----BEGIN ENCRYPTED PRIVATE KEY----- 121 | # ... 122 | # -----END ENCRYPTED PRIVATE KEY----- 123 | 124 | # Name of an existing secret containing `tls.cert` and `tls.key`. 125 | # Mounted on the default tls path `/etc/gangway/tls` 126 | # existingSecret: "" 127 | 128 | extraVolumes: [] 129 | 130 | extraVolumeMounts: [] 131 | 132 | livenessProbe: 133 | # HTTP or HTTPS 134 | scheme: HTTP 135 | 136 | readinessProbe: 137 | # HTTP or HTTPS 138 | scheme: HTTP 139 | 140 | service: 141 | type: ClusterIP 142 | port: 80 143 | # Specifies a loadBalancerIP when using LoadBalancer service type 144 | # loadBalancerIP: 192.168.0.51 145 | 146 | ingress: 147 | enabled: false 148 | annotations: {} 149 | # kubernetes.io/ingress.class: nginx 150 | # kubernetes.io/tls-acme: "true" 151 | path: / 152 | hosts: 153 | - chart-example.local 154 | tls: [] 155 | # - secretName: chart-example-tls 156 | # hosts: 157 | # - chart-example.local 158 | 159 | resources: {} 160 | # We usually recommend not to specify default resources and to leave this as a conscious 161 | # choice for the user. This also increases chances charts run on environments with little 162 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 163 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 164 | # limits: 165 | # cpu: 100m 166 | # memory: 128Mi 167 | # requests: 168 | # cpu: 100m 169 | # memory: 128Mi 170 | 171 | nodeSelector: {} 172 | 173 | tolerations: [] 174 | 175 | affinity: {} 176 | -------------------------------------------------------------------------------- /charts/grafana/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | persistence: 2 | enabled: true 3 | 4 | {{- if .Values._.ingress.enabled }} 5 | ingress: 6 | enabled: true 7 | hosts: [{{ env "GRAFANA_DNS" }}] 8 | tls: 9 | - secretName: grafana-tls 10 | hosts: 11 | - {{ env "GRAFANA_DNS" }} 12 | annotations: 13 | kubernetes.io/ingress.class: 'nginx' 14 | ingress.kubernetes.io/ssl-redirect: 'true' 15 | cert-manager.io/cluster-issuer: 'letsencrypt-prod' 16 | cert-manager.io/acme-challenge-type: 'dns01' 17 | cert-manager.io/acme-dns01-provider: 'prod-clouddns' 18 | kubernetes.io/tls-acme: 'true' 19 | nginx.ingress.kubernetes.io/proxy-buffer-size: "64k" 20 | {{- end }} 21 | 22 | adminPassword: {{ requiredEnv "GRAFANA_ADMIN_PASSWORD" }} 23 | 24 | grafana.ini: 25 | server: 26 | root_url: {{ env "GRAFANA_URL" }} 27 | {{- if eq (env "AUTH_TYPE") "uaa" }} 28 | auth.generic_oauth: 29 | name: uaa 30 | enabled: true 31 | scopes: openid profile email 32 | client_id: {{ env "GRAFANA_OIDC_CLIENT_ID" }} 33 | client_secret: {{ env "GRAFANA_OIDC_CLIENT_SECRET" }} 34 | auth_url: {{ env "GRAFANA_OIDC_AUTH_URL" }} 35 | token_url: {{ env "GRAFANA_OIDC_TOKEN_URL" }} 36 | api_url: {{ env "GRAFANA_OIDC_USERINFO_URL" }} 37 | {{- end }} 38 | 39 | datasources: 40 | datasources.yaml: 41 | apiVersion: 1 42 | datasources: 43 | - name: {{ env "ENV_NAME" }}-prometheus 44 | type: prometheus 45 | url: http://prometheus-server.{{ .Values.charts.prometheus.namespace }} 46 | access: proxy 47 | isDefault: true 48 | {{- if .Values.charts.loki.enabled }} 49 | - name: {{ env "ENV_NAME" }}-loki 50 | type: loki 51 | url: http://loki.{{ .Values.charts.loki.namespace }}:3100 52 | access: proxy 53 | {{- end }} 54 | dashboardProviders: 55 | dashboardproviders.yaml: 56 | apiVersion: 1 57 | providers: 58 | - name: 'default' 59 | orgId: 1 60 | folder: '' 61 | type: file 62 | disableDeletion: false 63 | editable: true 64 | options: 65 | path: /var/lib/grafana/dashboards/default 66 | 67 | dashboards: 68 | default: 69 | prometheus-stats: 70 | gnetId: 2 71 | revision: 2 72 | datasource: {{ env "ENV_NAME" }}-prometheus 73 | pks-stats: 74 | gnetId: 10000 75 | revision: 1 76 | datasource: {{ env "ENV_NAME" }}-prometheus 77 | spring-jvm-actuator: 78 | gnetId: 4701 79 | revision: 80 | datasource: {{ env "ENV_NAME" }}-prometheus 81 | loki-promtail: 82 | gnetId: 10880 83 | datasource: {{ env "ENV_NAME" }}-prometheus -------------------------------------------------------------------------------- /charts/harbor/helmfile/secrets.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | manifests: 2 | - metadata: 3 | name: harbor-extra-config 4 | apiVersion: v1 5 | kind: ConfigMap 6 | data: 7 | {{- if not .Values._.ingress.enabled }} 8 | - metadata: 9 | name: harbor-certs 10 | apiVersion: v1 11 | kind: Secret 12 | data: 13 | ca.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM5VENDQWQyZ0F3SUJBZ0lSQU1FaXBpK0VFSS9vN3NYQkNqU0dSQVV3RFFZSktvWklodmNOQVFFTEJRQXcKRkRFU01CQUdBMVVFQXhNSmFHRnlZbTl5TFdOaE1CNFhEVEU1TVRJd05USXdNRFF3TWxvWERUSXdNVEl3TkRJdwpNRFF3TWxvd0ZERVNNQkFHQTFVRUF4TUphR0Z5WW05eUxXTmhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DCkFROEFNSUlCQ2dLQ0FRRUF2bzRXU1lqRnFlcnZoSXJ3VGhQOXlrZUJqbHE0NVdvME1XS29ueEZmVDJoRk0zUG8KanhJQ1RQQkQxUXJxNFVZRW1pODVzMk8ydlhVN3p3S0VlT3FHZUhWQnVWMWxHVHdyRkN6Z2JHYjJRL1lhdnIraAppM3lHcmVJNkxLUmNSaWJxM2dUMEpSVEVtUVpTMDU5QnV2bzhuTWhOMVlnUmk4WE80WE55UHlkSUFYV0U3VW9kCmMrbmdTUmcyc1ZhRnZ5amUzdzFybVhLVytlbmNlblp0QVQwRmRmM3hDSVE3blBhbmJCUDVrb0Z0c2owME0vSkoKNzgzYXBWMEQvSm5sZmtXSEpvUi96ckdTUEZha0pjczlZM3lLVmlmRjUyalRMcHo0c2xHY1lUWVNjcUpuRkZjegpXQWdTanhGd1F4bDFMU1J2N0xJM0RYY2ozdlNmMDFZZ2RpYjNTd0lEQVFBQm8wSXdRREFPQmdOVkhROEJBZjhFCkJBTUNBcVF3SFFZRFZSMGxCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUYKTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS3liZ0EyNFpFN1phVlkwcGQ4eWxlaDFaR3VaYUd0Swp3a2FucXp0WjY2ZjRMMkZSRSt3NkN3SkNaKzF6cjVraDVUbWwwWXBCbDB6QTVjUVdEUE1jbzB5bU5UbDN4Z2R2CkdBOUNsMHM5eFc3bW5saUZ0eklIZlBITFNpWTZ6M3NiTUlaSjJxY0J5Wk5HcFlnd0FvVG1RSlp5TlZBcmIvVUcKcXU1Z3Q5VGNjaTBWVlZES2ZQc3VtMlB5UEZYVnhLOU4rc3I3UEdydVBZenlFZitHYjMvczZZUDd1Wnl4ZkFTSwpEV2dHVEgzN00vQzNWOHZBU1BWZ0VFRVBIUHhoanBxa0xEZnFUUUNhUjdleW5iczMzSWRtYUF3NjRDKy9mc0tOCnM3bjYwaFA1QkdNeVNLamlLckdOU1RpYmZXaVpZUURNelRVc3Q1VG9ZTFNJZjhVbFJrUDM5Mjg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" 14 | tls.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBVENDQWVtZ0F3SUJBZ0lRQ253cC9MOG15MjdxczJYc1pBandGVEFOQmdrcWhraUc5dzBCQVFzRkFEQVUKTVJJd0VBWURWUVFERXdsb1lYSmliM0l0WTJFd0hoY05NVGt4TWpBMU1qQXdOREF6V2hjTk1qQXhNakEwTWpBdwpOREF6V2pBUk1ROHdEUVlEVlFRREV3Wm9ZWEppYjNJd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3CmdnRUtBb0lCQVFEWUcxNUtlT3FmVmJzelAzWm95OUlhdXVJZDAvRGpMTERjMGZoajJPSU9KVXNzaHhKS1hmb0sKS0IvYVVMeWVzOEZYSFVwMzZsUmdZeEdnN3B0aUUrUHI2dEVTa2wwUE1sbjRvZjF4NW1JM2l4b0pLNE9QT0pMagp5SjQ5ZWt4bldkaFBqbko1cXFKVm9MS0tJSDJzZW8vSXFvNThsV0JwcUVHREp3TjZReWVNeitab3Y5ZVN1VDhFClZ4L1pVVTd1WjBlbk9BWC9pNWM0SkU1bzJYYmJUTldVRXVsa3J3RGl3VW5qcG0vN3FoTDFVZDNpYnRvaDk4ZWsKcTZwQUkzSlZxWDJMTFpXclhKR2R4NmR5bzdvR2xlZEZpUVJzTGNBYkZzd3AraTNPSUwzVkVQNDBBMFo1eUEwNQpmL0N6RU1jTlZhY0s3ZE9PQmY2N2ZoSE5Nd1p3bWVZbkFnTUJBQUdqVWpCUU1BNEdBMVVkRHdFQi93UUVBd0lGCm9EQWRCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0RBUVlJS3dZQkJRVUhBd0l3REFZRFZSMFRBUUgvQkFJd0FEQVIKQmdOVkhSRUVDakFJZ2dab1lYSmliM0l3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUpCVi83SngxY0RhTmo1QwpjLzdLNmJBcUEvWjk3ZnRXY1k4d3Z1Y29RcjVKS092cXRpUzhxRUVjanNEY1RGV0VMZWtYSDZXRHBDRHB4MmpsClJITnhPTkdEQ1FQQ28yMWc1eTFZcncvVktnSXRyUUorMFVIai9TVWFhcmdIWUhtUkxZemJpSE1ORllBK0VUQ0EKelpuQ3dNL1B1VDlLVmVKU0hXYUFxckd6QjVveXNQRHJaandXanFjbC9SZnJTZ0Vka29HK0tSaVJqeHdabGF0cApaamdGSTZtQTJxcG45c2lZbkF3bnBDYjBnR2paczlBbVptVUh2bkxncDZVRmZtRThGbkJFM1kxN2E1U2RnWlV6Ci83dE51ZTd0WnhiTnE2VXFoQjdUWmRuTytTc0IyZm9PMGxERisya1lydWxRUlVaME81ak00S0NnRGxWWTRHM0oKT1AyMjM5Yz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" 15 | tls.key: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBMkJ0ZVNuanFuMVc3TXo5MmFNdlNHcnJpSGRQdzR5eXczTkg0WTlqaURpVkxMSWNTClNsMzZDaWdmMmxDOG5yUEJWeDFLZCtwVVlHTVJvTzZiWWhQajYrclJFcEpkRHpKWitLSDljZVppTjRzYUNTdUQKanppUzQ4aWVQWHBNWjFuWVQ0NXllYXFpVmFDeWlpQjlySHFQeUtxT2ZKVmdhYWhCZ3ljRGVrTW5qTS9tYUwvWAprcmsvQkZjZjJWRk83bWRIcHpnRi80dVhPQ1JPYU5sMjIwelZsQkxwWks4QTRzRko0Nlp2KzZvUzlWSGQ0bTdhCklmZkhwS3VxUUNOeVZhbDlpeTJWcTF5Um5jZW5jcU82QnBYblJZa0ViQzNBR3hiTUtmb3R6aUM5MVJEK05BTkcKZWNnTk9YL3dzeERIRFZXbkN1M1RqZ1grdTM0UnpUTUdjSm5tSndJREFRQUJBb0lCQURqVFVZTUJzcWc5TWVGeQo4Wjd5NFllWDFyZURNSmQ3Ky9IRTRLellyZkNNUyswa2cyRzh2bkFIUndEd00va0RTWGF2eEJJdU13dTVZVHhSCklkaXpaRDUzMjR3bm9vTEplYkVRWDRXZ3ovak5BZ2FoUTVIWWpYK0tGRm9VRzUwZG1leXBoMTZJeVBEOU5aVnUKbjcxSDZTRWFBQ2V3Vzg3TXFKVmxIOXY1WnAvMjIyZCtLNmNlKzV5MXJCeFJuT3FLUXdhcmVUUFlLRDVEdk1MNgpxcWozWm9ualJsbmZuREtVTTFrMGtBTTBFamg1aU90VDE4NTVDUUJDRWd3RWVjV3AwdWtZNjJxajF3NXI2QWlnCk1Lem5nNUpoLzNYdld6WE5tQXduNnE4MDAwQnh5MThhbzNsTGxuN1B2ZS9TanFkY3I4bDRVelZLTXdXUFhGN2QKVFRZZVlSa0NnWUVBNTNWYWs3NUpwMXR3WHVlSlFZanJObzhEY0lTVDlXVUd0djFTZVFkRzRaa0I3SFJEMEJCRgpvcC9nb005c0Y4TjZPSkFQeEtXMUx3TDBzalhPY3IxdUVEOXh0SHVzU3R6NWVLdTh2QS9ubHY5dzA4dS9JZlpiCk9EQVhmR05mc010d29HK2hrenFibnlDWVdmQmd6bjlPM2RnbWZicld4SmxUUlFaakZ2bEt5ME1DZ1lFQTd3VlIKT1IxcEFDdTZJWnVGYy9DU1NDSllGdnZCdUtMU1VkZW03NE5qWW9kcjFzbnFJS1JkMHo2NUpqNGtNM3psQW5kTwpGbXFrNm5iNXBrTFZZVjZoTFRuNE5zSkdyTldXb2Q0SFVBSHdPQmRPazhWNzFqUm9hN1VUb09WcndxTi9BUkp5CkYzMmppdFlSUnNHNnRFUThUcHhhWUlMMTBtY3R5VzVMZkRLNmdVMENnWUJuUC9kMjNyVFdmampEYlQvU1J6UzkKOHRBUyttRlNYNDIrUllUcnptNDFKdDh2enJHTmVDVElKYys3akt2b2NkL3NxWDhQTnVoN0h6TnU2QWUvTVhlTwpzZTZVRjNORk5ndm5ZNXpldTYyUXMwUnVobjR0dFVyOTVwNGpjK1QwNWR2SkJlTXEzVU1jbWhxOFREbXpCQ0YzClh2dlVyR3N2NmtHMkVlSlVGa0xpSndLQmdHbnkxM0FUdzBsYUdLVnhCSlRCM0hXeEU0OE1oWEJNYkNIdkQ0WTMKblVROWR1VzhsdFZsUmxtdkFlOGJ1SHhDTGxrTGZVZWVlZitjUVVrYmN1NDRQZ1dJSHFoWE1YREhOSUFIcFFJbgorYzFETjRkMUVGR0E1WkJvc1l5dVpUZmZ0UnBLak53d3l0OXR5RGF2QlEyRytaeDIzZkROM0IwcHN6Z0lkZGxWCnV5bzVBb0dBQkdTZ3IxN1ZhZXJBdDNiWjM5b1FDNDFORDAxUlhEQmJlZEJyTTdlOXI0VXpLWE9sNkdtK212Q3cKbmRBTy9uSnZ3MlQzTWVseTc3YUM0VDZiOW9WSFRzOCs0bjQzTVJ2OEYzaE5jMVhpNTJXcmxTcG5MS0Z4Q1JWQwpqZW4wLzEwM21ZV084dS8yVlpLVUxsejYvcG13cVlOZXVaTFkrcDdDR3l3RTF4Q1RqZGc9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==" 16 | {{- end }} 17 | {{- if env "UAA_ROOT_CA_CERT" }} 18 | - metadata: 19 | name: uaa-ca-cert 20 | apiVersion: v1 21 | kind: Secret 22 | data: 23 | ca.crt: {{ env "UAA_ROOT_CA_CERT" | b64enc }} 24 | {{- end }} -------------------------------------------------------------------------------- /charts/harbor/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | nameOverride: harbor 2 | fullnameOverride: harbor 3 | 4 | expose: 5 | {{- if .Values._.ingress.enabled }} 6 | type: ingress 7 | tls: 8 | enabled: true 9 | secretName: harbor-certs 10 | notarySecretName: "notary-secret" 11 | ingress: 12 | hosts: 13 | core: {{ requiredEnv "HARBOR_DNS" }} 14 | notary: {{ env "HARBOR_DNS" }} 15 | annotations: 16 | ingress.kubernetes.io/ssl-redirect: 'true' 17 | ingress.kubernetes.io/proxy-body-size: '0' 18 | kubernetes.io/ingress.class: nginx 19 | certmanager.k8s.io/cluster-issuer: letsencrypt-prod 20 | certmanager.k8s.io/acme-challenge-type: dns01 21 | certmanager.k8s.io/acme-dns01-provider: prod-clouddns 22 | kubernetes.io/tls-acme: 'true' 23 | externalURL: https://{{ env "HARBOR_DNS" }} 24 | {{- else }} 25 | type: clusterIP 26 | tls: 27 | enabled: true 28 | commonName: harbor 29 | secretName: harbor-certs 30 | 31 | externalURL: https://harbor:8443 32 | {{- end }} 33 | 34 | 35 | persistence: 36 | enabled: true 37 | persistentVolumeClaim: 38 | database: 39 | size: 10Gi 40 | redis: 41 | size: 10Gi 42 | imageChartStorage: 43 | {{- if not (env "CLOUD_PROVIDER") }} 44 | disableredirect: true 45 | type: s3 46 | s3: 47 | accesskey: {{ requiredEnv "MINIO_ACCESS_KEY" }} 48 | secretkey: {{ requiredEnv "MINIO_SECRET_KEY" }} 49 | regionendpoint: http://minio.minio.svc.cluster.local:9000 50 | bucket: harbor 51 | {{- else if eq (env "CLOUD_PROVIDER") "gcp" }} 52 | disableredirect: false 53 | type: gcs 54 | gcs: 55 | bucket: {{ requiredEnv "ENV_NAME" }}-harbor 56 | encodedkey: {{ env "HARBOR_GCP_CREDENTIALS" }} 57 | {{- end }} 58 | 59 | harborAdminPassword: {{ requiredEnv "HARBOR_ADMIN_PASSWORD" }} 60 | secretKey: {{ requiredEnv "HARBOR_SECRET_KEY" }} 61 | notary: 62 | enabled: false 63 | secretName: notary-certs 64 | database: 65 | internal: 66 | password: {{ requiredEnv "HARBOR_DATABASE_PASSWORD" }} 67 | 68 | {{- if and (eq (env "AUTH_TYPE") "uaa") (env "UAA_ROOT_CA_CERT") }} 69 | uaaSecretName: uaa-ca-cert 70 | {{- end }} 71 | 72 | userSettings: 73 | self_registration: "false" 74 | {{- if eq (env "AUTH_TYPE") "uaa" }} 75 | auth_mode: uaa_auth 76 | uaa_client_id: {{ requiredEnv "HARBOR_OIDC_CLIENT_ID" }} 77 | uaa_client_secret: {{ requiredEnv "HARBOR_OIDC_CLIENT_SECRET" }} 78 | uaa_endpoint: {{ requiredEnv "UAA_URL" }} 79 | {{- end }} 80 | core: 81 | secret: {{ requiredEnv "HARBOR_INTERNAL_SECRET" }} 82 | {{- if env "HARBOR_XSRFKEY" }} 83 | xsrfKey: {{ env "HARBOR_XSRFKEY" }} 84 | {{- end }} 85 | jobservice: 86 | secret: {{ requiredEnv "HARBOR_INTERNAL_SECRET" }} 87 | registry: 88 | secret: {{ requiredEnv "HARBOR_INTERNAL_SECRET" }} -------------------------------------------------------------------------------- /charts/ingress/helmfile/base.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | controller: 2 | kind: DaemonSet 3 | publishService: 4 | enabled: true -------------------------------------------------------------------------------- /charts/kibana/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | nameOverride: kibana 2 | fullnameOverride: kibana 3 | 4 | elasticsearchHosts: https://elasticsearch-master.{{ .Values.elasticsearch.namespace }}:9200 5 | replicas: 1 6 | 7 | protocol: http 8 | 9 | extraEnvs: 10 | {{- if env "ELASTICSEARCH_PASSWORD" }} 11 | - name: ELASTICSEARCH_USERNAME 12 | value: {{ requiredEnv "ELASTICSEARCH_USERNAME" }} 13 | - name: ELASTICSEARCH_PASSWORD 14 | valueFrom: 15 | secretKeyRef: 16 | name: elasticsearch-credentials 17 | key: password 18 | {{- end }} 19 | 20 | kibanaConfig: 21 | kibana.yml: | 22 | server.ssl: 23 | enabled: false 24 | #key: /usr/share/kibana/config/certs/tls.key 25 | #certificate: /usr/share/kibana/config/certs/tls.crt 26 | elasticsearch.ssl: 27 | certificateAuthorities: /usr/share/kibana/config/certs/ca.crt 28 | verificationMode: certificate 29 | {{- if eq "uaa" (env "AUTH_TYPE") }} 30 | xpack.security.authc.providers: [oidc, basic] 31 | xpack.security.authc.oidc.realm: "oidc1" 32 | xpack.security.enabled: true 33 | server.xsrf.whitelist: [/api/security/v1/oidc] 34 | {{- end }} 35 | 36 | secretMounts: 37 | - name: elastic-certificates 38 | secretName: elastic-certificates 39 | path: /usr/share/kibana/config/certs 40 | 41 | {{- if .Values.ingress.enabled }} 42 | ingress: 43 | enabled: true 44 | hosts: [{{ env "KIBANA_DNS" }}] 45 | tls: 46 | - secretName: concourse-tls 47 | hosts: 48 | - {{ env "KIBANA_DNS" }} 49 | annotations: 50 | kubernetes.io/ingress.class: 'nginx' 51 | ingress.kubernetes.io/ssl-redirect: 'true' 52 | cert-manager.io/cluster-issuer: 'letsencrypt-prod' 53 | cert-manager.io/acme-challenge-type: 'dns01' 54 | cert-manager.io/acme-dns01-provider: 'prod-clouddns' 55 | kubernetes.io/tls-acme: 'true' 56 | {{- end }} -------------------------------------------------------------------------------- /charts/kubeapps/helmfile/oidc.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | authProxy: 2 | enabled: true 3 | provider: oidc 4 | clientID: "{{ requiredEnv "KUBEAPPS_OIDC_CLIENT_ID" }}" 5 | clientSecret: "" 6 | cookieSecret: "{{ requiredEnv "KUBEAPPS_COOKIE_SECRET" | b64enc }}" 7 | additionalFlags: 8 | - "--cookie-secure=true" 9 | - "--cookie-httponly=false" 10 | - "-oidc-issuer-url={{ requiredEnv "KUBEAPPS_OIDC_URL"}}/oauth/token" 11 | - "-redirect-url={{ env "KUBEAPPS_URL" }}/oauth2/callback" 12 | - "--insecure-oidc-allow-unverified-email" 13 | -------------------------------------------------------------------------------- /charts/kubeapps/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | useHelm3: {{ env "IS_HELM3" | default false }} 2 | 3 | {{- if .Values._.ingress.enabled }} 4 | ingress: 5 | enabled: true 6 | hostname: {{ env "KUBEAPPS_DNS" | default "kubeapps.local" }} 7 | {{- if .Values.charts.certManager.enabled }} 8 | tls: true 9 | annotations: 10 | nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" 11 | kubernetes.io/ingress.class: 'nginx' 12 | ingress.kubernetes.io/ssl-redirect: 'true' 13 | kubernetes.io/tls-acme: "true" 14 | cert-manager.io/cluster-issuer: 'letsencrypt-prod' 15 | cert-manager.io/acme-challenge-type: 'dns01' 16 | cert-manager.io/acme-dns01-provider: 'prod-clouddns' 17 | {{- end }} 18 | {{- end }} 19 | -------------------------------------------------------------------------------- /charts/loki/helmfile/raw.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | manifests: 2 | - metadata: 3 | name: loki-extra-config 4 | apiVersion: v1 5 | kind: ConfigMap 6 | {{- if eq (env "CLOUD_PROVIDER") "gcp" }} 7 | - metadata: 8 | name: loki-secrets 9 | apiVersion: v1 10 | kind: Secret 11 | data: 12 | gcs-key.json: {{ env "LOKI_GCS_CREDENTIALS" }} 13 | {{- end }} -------------------------------------------------------------------------------- /charts/loki/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | persistence: 2 | enabled: true 3 | 4 | {{- if eq (env "CLOUD_PROVIDER") "gcp" }} 5 | config: 6 | schema_config: 7 | configs: 8 | - from: 2018-04-15 9 | store: boltdb 10 | object_store: gcs 11 | schema: v9 12 | index: 13 | prefix: index_ 14 | period: 168h 15 | 16 | storage_config: 17 | gcs: 18 | bucket_name: {{ requiredEnv "LOKI_GCS_BUCKET" }} 19 | {{- end }} 20 | 21 | {{- if eq (env "CLOUD_PROVIDER") "gcp" }} 22 | extraVolumes: 23 | - name: loki-secrets 24 | secret: 25 | secretName: loki-secrets 26 | 27 | extraVolumeMounts: 28 | - name: loki-secrets 29 | mountPath: /secrets 30 | readOnly: true 31 | 32 | env: 33 | - name: GOOGLE_APPLICATION_CREDENTIALS 34 | value: "/secrets/gcs-key.json" 35 | {{- end }} 36 | -------------------------------------------------------------------------------- /charts/minio/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | nameOverride: minio 2 | fullnameOverride: minio 3 | 4 | persistence: 5 | size: 20Gi 6 | 7 | accessKey: 8 | password: {{ requiredEnv "MINIO_ACCESS_KEY" }} 9 | 10 | secretKey: 11 | password: {{ requiredEnv "MINIO_SECRET_KEY" }} 12 | 13 | disableWebUI: false 14 | 15 | mode: standalone 16 | 17 | defaultBuckets: harbor,spinnaker 18 | 19 | podAnnotations: 20 | prometheus.io/scrape: "true" 21 | prometheus.io/path: "/minio/prometheus/metrics" 22 | prometheus.io/port: "9000" -------------------------------------------------------------------------------- /charts/mystique/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /charts/mystique/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A helm chart for masquerading as misc helm resources. 4 | name: mystique 5 | version: 0.1.0 6 | source: 7 | - https://github.com/paulczar/charts 8 | home: https://tech.paulcz.net/charts 9 | maintainers: 10 | - email: username.taken@gmail.com 11 | name: paulczar 12 | -------------------------------------------------------------------------------- /charts/mystique/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The Mystique Chart has deployed the following resources: 2 | 3 | {{- $name := include "mystique.fullname" . }} 4 | {{- $namespace := .Release.Namespace }} 5 | {{- range .Values.manifests }} 6 | - $ kubectl -n {{ default $namespace .namespace }} get {{ .kind | lower }} {{ .name }} 7 | {{- end }} -------------------------------------------------------------------------------- /charts/mystique/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "mystique.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "mystique.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "mystique.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "mystique.labels" -}} 38 | app.kubernetes.io/name: {{ include "mystique.name" . }} 39 | helm.sh/chart: {{ include "mystique.chart" . }} 40 | app.kubernetes.io/instance: {{ .Release.Name }} 41 | {{- if .Chart.AppVersion }} 42 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 43 | {{- end }} 44 | app.kubernetes.io/managed-by: {{ .Release.Service }} 45 | {{- end -}} 46 | -------------------------------------------------------------------------------- /charts/mystique/templates/mystique.yaml: -------------------------------------------------------------------------------- 1 | {{- $name := include "mystique.fullname" . }} 2 | {{- $labels := ( include "mystique.labels" . | indent 4 ) }} 3 | {{- $namespace := .Release.Namespace }} 4 | {{- range .Values.manifests }} 5 | --- 6 | apiVersion: {{ .apiVersion }} 7 | kind: {{ .kind }} 8 | metadata: 9 | name: {{ .name }} 10 | namespace: {{ default $namespace .namespace }} 11 | labels: 12 | {{ $labels }} 13 | {{- with .labels }} 14 | {{ tpl (toYaml .) $ | indent 4 }} 15 | {{- end }} 16 | {{- if .annotations }} 17 | annotations: 18 | {{- with .annotations }} 19 | {{ tpl (toYaml .) $ | indent 4 }} 20 | {{- end }} 21 | {{- end }} 22 | {{- if .spec }} 23 | spec: 24 | {{ tpl (toYaml .spec) $ | indent 2 }} 25 | {{- end }} 26 | {{- if .body }} 27 | {{ tpl (toYaml .body) $ }} 28 | {{- end }} 29 | {{- end }} -------------------------------------------------------------------------------- /charts/mystique/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for mystique. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | manifests: 5 | - name: mystique 6 | apiVersion: v1 7 | kind: Service 8 | annotations: 9 | marvel.mutant.name: mystique 10 | labels: 11 | xwoman: mystique 12 | spec: 13 | externalName: "{{ .Values.url }}" 14 | body: {} 15 | 16 | url: www.marvel.com -------------------------------------------------------------------------------- /charts/prometheus/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | alertmanager: 2 | enabled: false 3 | 4 | server: 5 | persistentVolume: 6 | enabled: true 7 | size: 50Gi 8 | statefulSet: 9 | enabled: true 10 | -------------------------------------------------------------------------------- /charts/promtail/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | loki: 2 | serviceName: loki 3 | 4 | {{- if eq (default (env "CLUSTER_TYPE") "") "pks" }} 5 | volumes: 6 | - name: docker 7 | hostPath: 8 | path: /var/vcap/store/docker/docker/containers 9 | - name: pods 10 | hostPath: 11 | path: /var/log/pods 12 | - hostPath: 13 | path: /var/vcap/store 14 | name: varvcapstore 15 | - hostPath: 16 | path: /var/vcap/data 17 | name: varvcapdata 18 | 19 | volumeMounts: 20 | - name: docker 21 | mountPath: /var/lib/docker/containers 22 | readOnly: true 23 | - name: pods 24 | mountPath: /var/log/pods 25 | readOnly: true 26 | - mountPath: /var/vcap/store 27 | name: varvcapstore 28 | readOnly: true 29 | - mountPath: /var/vcap/data 30 | name: varvcapdata 31 | readOnly: true 32 | {{- else }} 33 | volumes: 34 | - name: docker 35 | hostPath: 36 | path: /var/lib/docker/containers 37 | - name: pods 38 | hostPath: 39 | path: /var/log/pods 40 | 41 | volumeMounts: 42 | - name: docker 43 | mountPath: /var/lib/docker/containers 44 | readOnly: true 45 | - name: pods 46 | mountPath: /var/log/pods 47 | readOnly: true 48 | {{- end }} -------------------------------------------------------------------------------- /charts/raw/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /charts/raw/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A helm chart for deploying raw manifests 4 | name: raw 5 | version: 1.0.0 6 | source: 7 | - https://github.com/paulczar/charts 8 | home: https://tech.paulcz.net/charts 9 | maintainers: 10 | - email: username.taken@gmail.com 11 | name: paulczar 12 | -------------------------------------------------------------------------------- /charts/raw/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The Raw Chart has deployed the following resources: 2 | 3 | {{- $name := include "raw.fullname" . }} 4 | {{- $namespace := .Release.Namespace }} 5 | {{- range .Values.manifests }} 6 | - $ kubectl -n {{ default $namespace .namespace }} get {{ .kind | lower }} {{ .name }} 7 | {{- end }} -------------------------------------------------------------------------------- /charts/raw/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "raw.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "raw.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "raw.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "raw.metadata" -}} 38 | metadata: 39 | name: {{ include "raw.fullname" . }} 40 | namespace: {{ .Release.Namespace }} 41 | annotations: {} 42 | labels: 43 | app.kubernetes.io/name: {{ include "raw.name" . }} 44 | helm.sh/chart: {{ include "raw.chart" . }} 45 | app.kubernetes.io/instance: {{ .Release.Name }} 46 | {{- if .Chart.AppVersion }} 47 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 48 | {{- end }} 49 | app.kubernetes.io/managed-by: {{ .Release.Service }} 50 | {{- end -}} 51 | -------------------------------------------------------------------------------- /charts/raw/templates/manifests.yaml: -------------------------------------------------------------------------------- 1 | {{- $template := fromYaml (include "raw.metadata" .) -}} 2 | {{- range .Values.manifests -}} 3 | --- 4 | {{ toYaml (merge . $template) }} 5 | {{- end }} -------------------------------------------------------------------------------- /charts/raw/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for mystique. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | manifests: 5 | - metadata: 6 | name: raw-configmap 7 | annotations: 8 | this-is-an-annotation: "true" 9 | labels: 10 | this-is-an-label: "true" 11 | apiVersion: v1 12 | kind: ConfigMap 13 | data: 14 | this: is a key value pair 15 | -------------------------------------------------------------------------------- /charts/spinnaker/helmfile/secrets.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | manifests: 2 | - metadata: 3 | name: spinnaker-additional-secrets 4 | apiVersion: v1 5 | kind: Secret 6 | data: 7 | {{- if env "SPINNAKER_OIDC_CLIENT_SECRET" }} 8 | oauth2_client_secret: {{ env "SPINNAKER_OIDC_CLIENT_SECRET" | b64enc }} 9 | {{- end }} 10 | {{- if eq "gcp" (env "CLOUD_PROVIDER") }} 11 | - metadata: 12 | name: gcs-creds 13 | apiVersion: v1 14 | kind: Secret 15 | data: 16 | key.json: {{ env "SPINNAKER_GCS_CREDENTIALS" }} 17 | {{- end }} 18 | {{- if "SPINNAKER_REGISTRY_PASSWORD" }} 19 | - metadata: 20 | name: registry-secret 21 | apiVersion: v1 22 | kind: Secret 23 | data: 24 | dockerhub: {{ env "SPINNAKER_REGISTRY_PASSWORD" | b64enc }} 25 | {{- end }} -------------------------------------------------------------------------------- /charts/spinnaker/helmfile/uaa.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | {{- if eq (env "AUTH_TYPE") "uaa" }} 2 | halyard: 3 | {{- if env "UAA_ROOT_CA_CERT" }} 4 | additionalServiceSettings: 5 | gate.yml: 6 | kubernetes: 7 | volumes: 8 | - id: java-ca-certs 9 | mountPath: /etc/ssl/certs/java 10 | type: secret 11 | {{- end }} 12 | 13 | additionalScripts: 14 | create: true 15 | data: 16 | configure_oauth.sh: | 17 | source /opt/halyard/additionalConfigMaps/config.src 18 | 19 | OAUTH2_CLIENT_SECRET="$( cat "$OAUTH2_CLIENT_SECRET_FILE" )" 20 | 21 | $HAL_COMMAND config security authn oauth2 edit \ 22 | --client-authentication-scheme header \ 23 | --client-id ${OAUTH2_CLIENT_ID} \ 24 | --client-secret ${OAUTH2_CLIENT_SECRET} \ 25 | --provider other \ 26 | --scope openid,uaa.user,uaa.resource \ 27 | --user-info-mapping-username user_name \ 28 | --user-info-mapping-email email \ 29 | --user-info-mapping-first-name given_name \ 30 | --user-info-mapping-last-name family_name \ 31 | --user-authorization-uri=${OAUTH2_URL}/oauth/authorize \ 32 | --access-token-uri=${OAUTH2_URL}/oauth/token \ 33 | --user-info-uri=${OAUTH2_URL}/userinfo 34 | 35 | $HAL_COMMAND config security authn oauth2 enable 36 | 37 | $HAL_COMMAND config security ui edit --override-base-url "$DECK_URL" 38 | $HAL_COMMAND config security api edit --override-base-url "$GATE_URL" 39 | additionalConfigMaps: 40 | create: true 41 | data: 42 | config.src: |- 43 | OAUTH2_CLIENT_ID={{ requiredEnv "SPINNAKER_OIDC_CLIENT_ID" }} 44 | OAUTH2_CLIENT_SECRET_FILE=/opt/halyard/additionalSecrets/oauth2_client_secret 45 | GITHUB_TOKEN_FILE=/opt/halyard/additionalSecrets/github-token 46 | OAUTH2_URL={{ requiredEnv "UAA_URL"}} 47 | GATE_URL=https://{{ requiredEnv "SPINNAKER_GATE_DNS" }} 48 | DECK_URL=https://{{ requiredEnv "SPINNAKER_DNS" }} 49 | 50 | additionalSecrets: 51 | create: false 52 | name: spinnaker-additional-secrets 53 | {{- end }} -------------------------------------------------------------------------------- /charts/spinnaker/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | # Configure your Docker registries here 2 | dockerRegistries: 3 | - name: dockerhub 4 | address: https://index.docker.io 5 | repositories: 6 | - paulczar/spring-helloworld 7 | username: ~ 8 | password: ~ 9 | 10 | kubeConfig: 11 | omittedNameSpaces: 12 | - kube-system 13 | - kube-public 14 | onlySpinnakerManaged: 15 | enabled: true 16 | 17 | # Redis password to use for the in-cluster redis service 18 | # Redis is not exposed publically 19 | redis: 20 | password: bad-redis-password 21 | nodeSelector: {} 22 | cluster: 23 | enabled: false 24 | master: 25 | persistence: 26 | enabled: true 27 | 28 | minio: 29 | enabled: false 30 | 31 | halyard: 32 | spinnakerVersion: 1.16.2 33 | image: 34 | tag: 1.28.0 35 | 36 | {{- if .Values._.ingress.enabled }} 37 | additionalProfileConfigMaps: 38 | create: true 39 | data: 40 | gate-local.yml: |- 41 | server: 42 | tomcat: 43 | protocolHeader: X-Forwarded-Proto 44 | remoteIpHeader: X-Forwarded-For 45 | internalProxies: .* 46 | httpsServerPort: X-Forwarded-Port 47 | {{- end }} 48 | {{- if eq (env "CLOUD_PROVIDER") "gcp" }} 49 | gcs: 50 | enabled: true 51 | secretName: gcs-creds 52 | project: {{ requiredEnv "SPINNAKER_GCS_PROJECT" }} 53 | bucket: {{ requiredEnv "SPINNAKER_GCS_BUCKET"}} 54 | {{- else }} 55 | # existing minio is used to store artifacts 56 | s3: 57 | enabled: true 58 | bucket: "spinnaker" 59 | endpoint: http://minio.minio.svc.cluster.local:9000 60 | accessKey: "{{ requiredEnv "MINIO_ACCESS_KEY" }}" 61 | secretKey: "{{ requiredEnv "MINIO_SECRET_KEY" }}" 62 | extraArgs: 63 | - "--path-style-access true" 64 | {{- end }} 65 | 66 | {{- if .Values._.ingress.enabled }} 67 | ingress: 68 | enabled: true 69 | host: {{ requiredEnv "SPINNAKER_DNS" }} 70 | tls: 71 | - secretName: spin-deck-cert 72 | hosts: 73 | - {{ requiredEnv "SPINNAKER_DNS" }} 74 | annotations: 75 | kubernetes.io/ingress.class: nginx 76 | ingress.kubernetes.io/ssl-redirect: 'true' 77 | cert-manager.io/cluster-issuer: letsencrypt-prod 78 | cert-manager.io/acme-challenge-type: dns01 79 | cert-manager.io/acme-dns01-provider: prod-clouddns 80 | kubernetes.io/tls-acme: 'true' 81 | 82 | ingressGate: 83 | enabled: true 84 | host: {{ requiredEnv "SPINNAKER_GATE_DNS" }} 85 | tls: 86 | - secretName: spin-gate-cert 87 | hosts: 88 | - {{ requiredEnv "SPINNAKER_GATE_DNS" }} 89 | annotations: 90 | kubernetes.io/ingress.class: nginx 91 | ingress.kubernetes.io/ssl-redirect: 'true' 92 | cert-manager.io/cluster-issuer: letsencrypt-prod 93 | cert-manager.io/acme-challenge-type: dns01 94 | cert-manager.io/acme-dns01-provider: prod-clouddns 95 | kubernetes.io/tls-acme: 'true' 96 | {{- else }} 97 | ingress: 98 | enabled: false 99 | 100 | ingressGate: 101 | enabled: false 102 | {{- end }} 103 | 104 | spinnakerFeatureFlags: 105 | - artifacts -------------------------------------------------------------------------------- /charts/wavefront/helmfile/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | wavefront: 2 | url: {{ requiredEnv "WAVEFRONT_URL" }} 3 | token: {{ requiredEnv "WAVEFRONT_TOKEN" }} 4 | 5 | clusterName: {{ requiredEnv "WAVEFRONT_CLUSTER_NAME" }} 6 | -------------------------------------------------------------------------------- /docs/default/concourse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulczar/platform-operations-on-kubernetes/3d523659497d9c7aae9cf34860e0448ddea0fc47/docs/default/concourse.png -------------------------------------------------------------------------------- /docs/default/grafana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulczar/platform-operations-on-kubernetes/3d523659497d9c7aae9cf34860e0448ddea0fc47/docs/default/grafana.png -------------------------------------------------------------------------------- /docs/default/harbor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulczar/platform-operations-on-kubernetes/3d523659497d9c7aae9cf34860e0448ddea0fc47/docs/default/harbor.png -------------------------------------------------------------------------------- /docs/default/install.md: -------------------------------------------------------------------------------- 1 | # Installing the default implementation of Platform Operations on Kubernetes 2 | 3 | The default example installs components with their default authentication methods, because of this we do not expose services via `NodePort` or `LoadBalancer` and instead rely on the user running `kubectl port-forward`. 4 | 5 | The following components are installed in the default environment: 6 | 7 | * Grafana 8 | * Prometheus 9 | * Loki / Promtail 10 | * Concourse 11 | * Harbor 12 | * Spinnaker 13 | * Minio (for Spinnaker and Harbor artifacts) 14 | 15 | 16 | ## Create Kubernetes Cluster 17 | 18 | If you don't already have a Kubernetes cluster you should use PKS or GKE to create one. 19 | 20 | Wait for cluster to be ready... 21 | 22 | Ensure kubectl is working 23 | 24 | ```bash 25 | $ kubectl get nodes 26 | NAME STATUS ROLES AGE VERSION 27 | vm-5ca56981-6249-4d31-613e-7d84821b245e Ready 46m v1.13.5 28 | vm-5fb78083-d502-43b3-4e01-d664fdb147dc Ready 42m v1.13.5 29 | vm-b451253c-e485-4d99-7bb4-1cfe222bf4ac Ready 39m v1.13.5 30 | ``` 31 | 32 | ## Prepare Helm 33 | 34 | ### Helm 2 35 | 36 | Install the helm diff and tillerless plugins: 37 | 38 | ```bash 39 | helm init --client-only 40 | 41 | helm plugin install https://github.com/databus23/helm-diff 42 | 43 | helm plugin install https://github.com/rimusz/helm-tiller 44 | 45 | helm tiller install 46 | ``` 47 | 48 | ### Helm 3 49 | 50 | ```bash 51 | helm plugin install https://github.com/databus23/helm-diff 52 | ``` 53 | 54 | 55 | ## Fill out envs.sh 56 | 57 | If you want to customize your deployment copy the contents of `/envs/default` to another location and modify `envs.sh` and `values.yaml` accordingly. 58 | 59 | If you're using PKS make sure you set the env variable `PKS=true`. This will help configure the correct paths etc for host mounts. 60 | 61 | ## Load environment 62 | 63 | > Note: If you changed the location of your environment you'll need to modify this command. 64 | 65 | ```bash 66 | . ./envs/default/envs.sh 67 | ``` 68 | 69 | ## Create namespaces 70 | 71 | > Note: If you're using helm2 you can skip this step 72 | 73 | ```bash 74 | scripts/check-namespaces.sh -c 75 | ``` 76 | 77 | ## Install using helmfile 78 | 79 | ```bash 80 | helmfile apply 81 | ``` 82 | 83 | ## Check services 84 | 85 | ### Grafana 86 | 87 | ```bash 88 | kubectl -n metrics port-forward svc/grafana 3000:80 89 | ``` 90 | 91 | Point your web browser at `http://localhost:3000` and then browse to the `cluster-monitoring-for-kubernetes` dashboard. 92 | 93 | ![grafana dashboard](./grafana.png) 94 | 95 | You should also be able to explore the Logs from Loki via the Explore icon on the left hand menu. 96 | 97 | ![loki logs](./loki.png) 98 | 99 | ### Harbor 100 | 101 | > Note: You should add an `/etc/hosts` record for `127.0.0.1 harbor` 102 | 103 | Forward a port for harbor 104 | 105 | ```console 106 | kubectl -n harbor port-forward svc/harbor 8443:443 107 | ``` 108 | 109 | Save harbor's CA cert to your local docker config: 110 | 111 | ```console 112 | sudo su - 113 | mkdir /etc/docker/certs.d/harbor 114 | curl -k https://harbor:8443/api/systeminfo/getcert > /etc/docker/certs.d/harbor/ca.cert 115 | ``` 116 | 117 | Log into registry and push an image: 118 | 119 | ```console 120 | $ docker login https://harbor:8443 121 | Username: admin 122 | Password: ****** 123 | Login Succeeded 124 | ``` 125 | 126 | ```console 127 | docker pull alpine:latest 128 | docker tag alpine:latest harbor:8443/library/alpine:latest 129 | docker push harbor:8443/library/alpine:latest 130 | ``` 131 | 132 | Browse to [http://harbor:8443](http://harbor:8443) in your web browser and login using `admin` and `change-me-please` (although you should have changed that password in envs.sh). 133 | 134 | You should be able to see your recently pushed alpine image at [https://harbor:8443/harbor/projects/1/repositories](https://harbor:8443/harbor/projects/1/repositories). 135 | 136 | ![harbor](./harbor.png) 137 | 138 | 139 | ### Concourse 140 | 141 | Forward a port for concourse 142 | 143 | ```console 144 | kubectl -n concourse port-forward svc/concourse-web 8080 145 | ``` 146 | 147 | Browse to [http://localhost:8080](http://localhost:8080) in your web browser and login using `admin` and `change-me-please` (although you should have changed that password in envs.sh). 148 | 149 | ![Concourse](./concourse.png) 150 | 151 | ### Spinnaker 152 | 153 | Forward a port for Spinnaker 154 | 155 | ```console 156 | kubectl -n spinnaker port-forward svc/spin-deck 9000 157 | ``` 158 | 159 | Browse to [http://localhost:9000](http://localhost:9000) in your web browser. 160 | 161 | ![Spinnaker](./spinnaker.png) 162 | -------------------------------------------------------------------------------- /docs/default/kibana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulczar/platform-operations-on-kubernetes/3d523659497d9c7aae9cf34860e0448ddea0fc47/docs/default/kibana.png -------------------------------------------------------------------------------- /docs/default/loki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulczar/platform-operations-on-kubernetes/3d523659497d9c7aae9cf34860e0448ddea0fc47/docs/default/loki.png -------------------------------------------------------------------------------- /docs/default/spinnaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulczar/platform-operations-on-kubernetes/3d523659497d9c7aae9cf34860e0448ddea0fc47/docs/default/spinnaker.png -------------------------------------------------------------------------------- /docs/gcp-uaa-openid/install.md: -------------------------------------------------------------------------------- 1 | # Platform Operations on Kubernetes on GCP with UAA / OpenID auth 2 | 3 | This example demonstrates running on a cluster running inside of Google Cloud with access to a UAA server for authentication for all services. It should work with most openid providers with minimal change. 4 | 5 | With OpenID auth in place all services will be made available to the public internet via an nginx ingress controller and secured with `cert-manager` and `external-dns`. These will be installed into a `cluster-admin` namespace. 6 | 7 | The following components are installed in the default environment: 8 | 9 | * Grafana 10 | * Prometheus 11 | * Loki / Promtail 12 | * Concourse 13 | * Harbor 14 | * Spinnaker 15 | 16 | ## Prepare GCP resources account 17 | 18 | ### Envs 19 | 20 | Copy `envs/gcp-uaa-openid`: 21 | 22 | ```console 23 | mkdir -p ../cluster-envs/example-gcp-openid 24 | cp -r envs/gcp-uaa-openid/* ../cluster-envs/example-gcp-openid 25 | ``` 26 | 27 | edit ../cluster-envs/example-gcp-openid/envs.sh` and set the following: 28 | 29 | * `ENV_NAME=example-gcp-openid` 30 | * `EXTERNAL_DNS_DOMAIN=` - the DNS zone you wish to use for a google managed DNS 31 | * `ENV_DIR="./envs/${ENV_NAME}/"` 32 | * `GOOGLE_PROJECT_ID=` - your GCP project ID 33 | * `CERT_MANAGER_EMAIL` - your email to receive cert expiry notifications 34 | * `GOOGLE_APPLICATION_CREDENTIALS_FILE` - path to which you want to download your google credentials to. 35 | * `UAA_URL` the URL of your UAA server 36 | * `UAA_ROOT_CA_CERT` the CA cert for your UAA server if self signed. 37 | 38 | Look for variables with `OIDC` or `UAA` and modify them to suit. 39 | 40 | Load the modified envs file: 41 | 42 | ```console 43 | . ../cluster-envs/example-gcp-openid/envs.sh 44 | ``` 45 | 46 | ### Create a DNS Zone 47 | 48 | ```console 49 | gcloud dns managed-zones create pook-$ENV_NAME \ 50 | --dns-name $EXTERNAL_DNS_DOMAIN \ 51 | --description "managed zone for POOK $ENV_NAME" 52 | ``` 53 | 54 | ### Create a GCP service account for DNS management and Cloud Storage 55 | 56 | Create service account: 57 | 58 | ```console 59 | gcloud iam service-accounts create \ 60 | pook-${ENV_NAME} --display-name "POOK service account" 61 | ``` 62 | 63 | Assign permissions: 64 | 65 | ```console 66 | EMAIL=pook-${ENV_NAME}@$GOOGLE_PROJECT_ID.iam.gserviceaccount.com 67 | 68 | gcloud projects add-iam-policy-binding $GOOGLE_PROJECT_ID \ 69 | --member serviceAccount:$EMAIL --role roles/dns.admin 70 | 71 | gcloud projects add-iam-policy-binding $GOOGLE_PROJECT_ID \ 72 | --member serviceAccount:$EMAIL --role roles/storage.admin 73 | ``` 74 | 75 | Download a google credentials file into your new envs directory: 76 | 77 | ```console 78 | gcloud iam service-accounts keys create \ 79 | ../cluster-envs/key.json --iam-account=$EMAIL 80 | ``` 81 | 82 | Load your envs file again to pick up this key: 83 | 84 | ```console 85 | . ../cluster-envs/example-gcp-openid/envs.sh 86 | ``` 87 | 88 | ## Create Kubernetes Cluster 89 | 90 | If you don't already have a Kubernetes cluster you should use PKS or GKE to create one. 91 | 92 | Wait for cluster to be ready... 93 | 94 | Ensure kubectl is working 95 | 96 | ```bash 97 | $ kubectl get nodes 98 | NAME STATUS ROLES AGE VERSION 99 | vm-5ca56981-6249-4d31-613e-7d84821b245e Ready 46m v1.13.5 100 | vm-5fb78083-d502-43b3-4e01-d664fdb147dc Ready 42m v1.13.5 101 | vm-b451253c-e485-4d99-7bb4-1cfe222bf4ac Ready 39m v1.13.5 102 | ``` 103 | 104 | ### Helm 2 105 | 106 | Install the helm diff and tillerless plugins: 107 | 108 | ```bash 109 | helm init --client-only 110 | 111 | helm plugin install https://github.com/databus23/helm-diff 112 | 113 | helm plugin install https://github.com/rimusz/helm-tiller 114 | 115 | helm tiller install 116 | ``` 117 | 118 | ### Helm 3 119 | 120 | ```bash 121 | helm plugin install https://github.com/databus23/helm-diff 122 | ``` 123 | 124 | 125 | ## Fill out envs.sh 126 | 127 | If you want to customize your deployment copy the contents of `/envs/default` to another location and modify `envs.sh` and `values.yaml` accordingly. 128 | 129 | ## Load environment 130 | 131 | > Note: If you changed the location of your environment you'll need to modify this command. 132 | 133 | ```bash 134 | . ./envs/default/envs.sh 135 | 136 | ``` 137 | 138 | ## Create namespaces 139 | 140 | > Note: If you're using helm2 you can skip this step 141 | 142 | ```bash 143 | scripts/check-namespaces.sh -c 144 | ``` 145 | 146 | ## Create CRDs for certmanager 147 | 148 | ```bash 149 | kubectl apply --validate=false \ 150 | -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml 151 | ``` 152 | 153 | ## Create UAA/OIDC clients 154 | 155 | > Note: You can skip manually creating the clients by running the script `./scripts/uaa-clients.sh create`. 156 | 157 | Install the UAA CLI (ruby): 158 | 159 | ```bash 160 | sudo gem install cf-uaac 161 | ``` 162 | 163 | Log into UAA: 164 | 165 | ```bash 166 | uaac target $UAA_URL 167 | uaac token client get admin -s "" 168 | ``` 169 | 170 | If you need to create additional UAA users you can do it like so: 171 | 172 | ```bash 173 | uaac user add test -p testfred1234 --emails test@here.com 174 | ``` 175 | 176 | ### Concourse 177 | 178 | Create UAA Client: 179 | 180 | ```bash 181 | uaac client add ${CONCOURSE_OIDC_CLIENT_ID} --scope openid,roles,uaa.user \ 182 | --authorized_grant_types refresh_token,password,authorization_code \ 183 | --redirect_uri "https://${CONCOURSE_DNS}/sky/issuer/callback" \ 184 | --authorities clients.read,clients.secret,uaa.resource,scim.write,openid,scim.read \ 185 | --secret "${CONCOURSE_OIDC_CLIENT_SECRET}" 186 | ``` 187 | 188 | ### Harbor 189 | 190 | Create storage bucket: 191 | 192 | ```bash 193 | gsutil mb -p $GOOGLE_PROJECT_ID -l us-central1 gs://$ENV_NAME-harbor/ 194 | ``` 195 | 196 | Create UAA Client: 197 | 198 | ```bash 199 | uaac client add ${HARBOR_OIDC_CLIENT_ID} --scope openid \ 200 | --authorized_grant_types client_credentials,password,refresh_token \ 201 | --redirect_uri "https://${HARBOR_DNS} https://${HARBOR_DNS}/*" \ 202 | --secret "${HARBOR_OIDC_CLIENT_SECRET}" \ 203 | --authorities clients.read,clients.secret,uaa.resource,scim.write,openid,scim.read 204 | ``` 205 | 206 | ### Spinnaker 207 | 208 | If you have a self signed certificate for your UAA server you'll need to load up a secret with it: 209 | 210 | > Note: this example was performed on a linux machine. OSX/Windows may need modifications 211 | 212 | ```bash 213 | cp /etc/ssl/certs/java/cacerts /tmp/cacerts 214 | echo "changeit" | keytool -importcert -alias uaa-ca \ 215 | -keystore /tmp/cacerts -noprompt -file $UAA_ROOT_CA_FILE 216 | kubectl create namespace spinnaker 217 | kubectl -n spinnaker create secret generic \ 218 | java-ca-certs --from-file /tmp/cacerts 219 | ``` 220 | 221 | Create a UAA Client for Spinnaker 222 | 223 | ```bash 224 | uaac client add "${SPINNAKER_OIDC_CLIENT_ID}" \ 225 | --scope openid,uaa.user,uaa.resource \ 226 | --authorized_grant_types password,refresh_token,authorization_code,client_credentials \ 227 | --redirect_uri "https://${SPINNAKER_GATE_DNS}/login" \ 228 | --secret "${SPINNAKER_OIDC_CLIENT_SECRET}" \ 229 | --authorities uaa.resource 230 | ``` 231 | 232 | ### Grafana 233 | 234 | Create a UAA Client for Grafana 235 | 236 | ```bash 237 | uaac client add "${GRAFANA_OIDC_CLIENT_ID}" \ 238 | --scope openid,profile,email \ 239 | --authorized_grant_types password,refresh_token,authorization_code,client_credentials \ 240 | --redirect_uri "${GRAFANA_URL}/login/generic_oauth" \ 241 | --secret "${GRAFANA_OIDC_CLIENT_SECRET}" \ 242 | --authorities uaa.resource 243 | ``` 244 | 245 | ## Install using helmfile 246 | 247 | ```bash 248 | helmfile apply 249 | ``` 250 | 251 | ## Check services 252 | 253 | Check that your ingress resources are up and have DNS and an IP address: 254 | 255 | ```bash 256 | $ kubectl get ingress --all-namespaces 257 | NAMESPACE NAME HOSTS ADDRESS PORTS AGE 258 | concourse concourse-web concourse.example.com 55.66.33.22 80, 443 47h 259 | gangway gangway gangway.example.com 55.66.33.22 80, 443 20h 260 | harbor harbor-harbor-ingress harbor.example.com 55.66.33.22 80, 443 47h 261 | metrics grafana grafana.example.com 55.66.33.22 80, 443 47h 262 | spinnaker spinnaker-spinnaker-deck spinnaker.example.com 55.66.33.22 80, 443 47h 263 | spinnaker spinnaker-spinnaker-gate api.spinnaker.example.com 55.66.33.22 80, 443 47h 264 | ``` 265 | 266 | ### Grafana 267 | 268 | Point your web browser at `https://$GRAFANA_DNS`, log in via OIDC and then browse to the `cluster-monitoring-for-kubernetes` dashboard. 269 | 270 | ![grafana dashboard](./grafana.png) 271 | 272 | You should also be able to explore the Logs from Loki via the Explore icon on the left hand menu. 273 | 274 | ![loki logs](./loki.png) 275 | 276 | 277 | ### Harbor 278 | 279 | ``` 280 | 281 | Once deployed you need to tell the API to use the provided UAA authentication: 282 | 283 | ```bash 284 | curl -i -X PUT -u "admin:$HARBOR_ADMIN_PASSWORD" \ 285 | -H "Content-Type: application/json" \ 286 | https://$HARBOR_DNS/api/configurations \ 287 | -d $HARBOR_USER_SETTINGS_JSON 288 | ``` 289 | 290 | Log into registry and push an image: 291 | 292 | > Note: we're using the pre-defined harbor admin user/pass here to avoid having to manually create a repository first. 293 | 294 | ```console 295 | $ docker login $HARBOR_DNS 296 | Username: admin 297 | Password: ****** 298 | Login Succeeded 299 | ``` 300 | 301 | ```console 302 | docker pull alpine:latest 303 | docker tag alpine:latest $HARBOR_DNS/library/alpine:latest 304 | docker push $HARBOR_DNS/library/alpine:latest 305 | ``` 306 | 307 | Browse to [https://$HARBOR_DNS](https://$HARBOR_DNS) in your web browser and login using your UAA credentials. 308 | 309 | ```console 310 | firefox https://$HARBOR_DNS 311 | ``` 312 | 313 | You should be able to see your recently pushed alpine image at [https://$HARBOR_DNS/harbor/projects/1/repositories](https://harbor:8443/harbor/projects/1/repositories). 314 | 315 | ![harbor](./harbor.png) 316 | 317 | ### Concourse 318 | 319 | Browse to [$CONCOURSE_URL]($CONCOURSE_URL) in your web browser and login using your UAA creds. 320 | 321 | ```console 322 | firefox $CONCOURSE_URL 323 | ``` 324 | 325 | ![Concourse](./concourse.png) 326 | 327 | ### Spinnaker 328 | 329 | Browse to [$SPINNAKER_URL](SPINNAKER_URL) in your web browser. 330 | 331 | ```console 332 | firefox $SPINNAKER_URL 333 | ``` 334 | 335 | ![Spinnaker](./spinnaker.png) 336 | -------------------------------------------------------------------------------- /envs/.gitignore: -------------------------------------------------------------------------------- 1 | *.json 2 | -------------------------------------------------------------------------------- /envs/default/charts.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | charts: 2 | ## Cluster Operations 3 | clusterSystem: 4 | enabled: true 5 | 6 | ingress: 7 | enabled: false 8 | 9 | certManager: 10 | enabled: false 11 | 12 | externalDNS: 13 | enabled: false 14 | 15 | ## CI/CD 16 | spinnaker: 17 | enabled: true 18 | 19 | concourse: 20 | enabled: false 21 | 22 | ## Artifact Storage 23 | 24 | minio: 25 | enabled: true 26 | 27 | harbor: 28 | enabled: true 29 | 30 | ## Metrics 31 | grafana: 32 | enabled: true 33 | 34 | prometheus: 35 | enabled: true 36 | 37 | ## Logging 38 | ## Generally speaking you'll only enable one set of either Loki+Promtail, or ELK 39 | loki: 40 | enabled: true 41 | 42 | promtail: 43 | enabled: true 44 | 45 | kubeapps: 46 | enabled: true 47 | -------------------------------------------------------------------------------- /envs/default/envs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # name of environment 4 | export ENV_NAME=default 5 | 6 | export ENV_DIR="./envs/${ENV_NAME}/" 7 | 8 | ## General 9 | # cloud provider (currently only supports gcp, leave blank to use minio for local object storage) 10 | export CLOUD_PROVIDER= #gcp 11 | 12 | 13 | ## PKS 14 | # Uncomment this if the cluster is build with PKS 15 | # export PKS=true 16 | 17 | ## Auth Type, leave blank or `uaa` 18 | export AUTH_TYPE= #uaa 19 | 20 | ## external-dns 21 | # pre-created secret containing your GCP creds. gcp-lb-tags chart creates a secret 22 | # we can use here. 23 | export EXTERNAL_DNS_SECRET="google-credentials" 24 | # DNS domain for external-dns controller to manage 25 | export EXTERNAL_DNS_DOMAIN="demo.example.com" 26 | 27 | ## concourse 28 | # hostname to register in DNS 29 | export CONCOURSE_DNS=localhost 30 | # password for concourse admin user 31 | export CONCOURSE_ADMIN_PASSWORD=change-me-please 32 | # external url for concourse 33 | export CONCOURSE_URL=http://${CONCOURSE_DNS}:8080 34 | 35 | ## harbor 36 | # hostname to register in DNS 37 | export HARBOR_DNS=harbor.${EXTERNAL_DNS_DOMAIN} 38 | # A bunch of passwords and secrets that you should change 39 | export HARBOR_ADMIN_PASSWORD=change-me-please 40 | export HARBOR_SECRET_KEY=not-a-secure-key 41 | export HARBOR_DATABASE_PASSWORD=database-password 42 | export HARBOR_INTERNAL_SECRET=safDhgbrtresDF23 43 | 44 | ## Spinnaker 45 | # UAA/OIDC client settings for Spinnaker 46 | export SPINNAKER_DNS=spinnaker.${EXTERNAL_DNS_DOMAIN} 47 | export SPINNAKER_GATE_DNS=gate.${SPINNAKER_DNS} 48 | export SPINNAKER_REGISTRY_PASSWORD=vBtAq5UmBvexvOQz3ZDk 49 | 50 | ## Grafana 51 | export GRAFANA_ADMIN_PASSWORD=password 52 | 53 | ## Elasticsearch 54 | export ELASTICSEARCH_USERNAME=elastic 55 | export ELASTICSEARCH_PASSWORD= 56 | 57 | ## Minio 58 | export MINIO_ACCESS_KEY=minio-access-key 59 | export MINIO_SECRET_KEY=minio-secret-key 60 | 61 | ## kubeapps 62 | # hostname to register in DNS 63 | export KUBEAPPS_DNS=kubeapps.${EXTERNAL_DNS_DOMAIN} 64 | # external url for kubeapps 65 | export KUBEAPPS_URL=https://${KUBEAPPS_DNS} 66 | # base64 cookie secret for when using auth proxy 67 | ## use `python -c 'import os,base64; print base64.urlsafe_b64encode(os.urandom(16))'` 68 | export KUBEAPPS_COOKIE_SECRET="not-good-secret" 69 | # mongodb password 70 | export KUBEAPPS_MONGODB_PASSWORD="bad-password" 71 | export KUBEAPPS_MONGODB_ROOT_PASSWORD="bad-root-password" 72 | ## kubeapps UAA/OIDC support 73 | # client id and secret for kubeapps to auth against UAA 74 | export KUBEAPPS_OIDC_CLIENT_ID= 75 | export KUBEAPPS_OIDC_CLIENT_SECRET= 76 | export KUBEAPPS_OIDC_URL="${UAA_URL}" 77 | 78 | ## wavefront 79 | export WAVEFRONT_URL="https://.wavefront.com/" 80 | export WAVEFRONT_TOKEN="" 81 | export WAVEFRONT_CLUSTER_NAME="${ENV_NAME}" 82 | -------------------------------------------------------------------------------- /envs/default/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | _: 2 | ingress: 3 | enabled: false -------------------------------------------------------------------------------- /envs/gcp-uaa-openid/charts.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | charts: 2 | clusterSystem: 3 | enabled: true 4 | 5 | ingress: 6 | enabled: true 7 | 8 | certManager: 9 | enabled: true 10 | 11 | externalDNS: 12 | enabled: true 13 | 14 | ## CI/CD 15 | spinnaker: 16 | enabled: true 17 | values: 18 | - charts/spinnaker/helmfile/values.yaml.gotmpl 19 | - charts/spinnaker/helmfile/uaa.yaml.gotmpl 20 | raw: 21 | - charts/spinnaker/helmfile/secrets.yaml.gotmpl 22 | 23 | concourse: 24 | enabled: true 25 | 26 | ## Artifact Storage 27 | 28 | harbor: 29 | enabled: true 30 | 31 | ## Metrics 32 | grafana: 33 | enabled: true 34 | 35 | prometheus: 36 | enabled: true 37 | 38 | ## Logging 39 | loki: 40 | enabled: true 41 | 42 | promtail: 43 | enabled: true 44 | 45 | elasticsearch: 46 | enabled: false 47 | 48 | kibana: 49 | enabled: false 50 | 51 | fluentbit: 52 | enabled: false 53 | 54 | # misc 55 | kubeapps: 56 | enabled: false 57 | 58 | minio: 59 | enabled: false 60 | -------------------------------------------------------------------------------- /envs/gcp-uaa-openid/envs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # name of environment 4 | export ENV_NAME=gcp-uaa-openid 5 | 6 | # relative or absolute path of your envs directory, effectively where the directory 7 | # containing this script sits relative to the helmfile dir. 8 | export ENV_DIR="./envs/${ENV_NAME}/" 9 | 10 | ## General 11 | # cloud provider (currently only supports gcp, leave blank to use minio for local object storage) 12 | export CLOUD_PROVIDER=gcp 13 | 14 | ## PKS 15 | # Uncomment this if the cluster is build with PKS 16 | # export PKS=true 17 | 18 | ## Google 19 | export GOOGLE_PROJECT_ID= 20 | 21 | ## external-dns and cert-manager need access to a service account with DNS management 22 | ## Given a downloaded creds json file this will load it into a secret. 23 | export GOOGLE_APPLICATION_CREDENTIALS_FILE="../cluster-envs/key.json" 24 | if [[ -e $GOOGLE_APPLICATION_CREDENTIALS_FILE ]]; then 25 | export GOOGLE_APPLICATION_CREDENTIALS_SECRET=$(cat ${GOOGLE_APPLICATION_CREDENTIALS_FILE} | base64 -w0) 26 | fi 27 | 28 | ## external-dns 29 | # pre-created secret containing your GCP creds. This is created from the above 30 | export EXTERNAL_DNS_SECRET="google-credentials" 31 | # DNS domain for external-dns controller to manage should be a google dns 32 | # managed zone 33 | export EXTERNAL_DNS_DOMAIN= 34 | 35 | ## cert-manager 36 | export CERT_MANAGER_EMAIL= 37 | 38 | export AUTH_TYPE=uaa 39 | 40 | ## UAA/OIDC 41 | ## the endpoint $UAA_URL/.well-known/openid-configuration should 42 | ## help you fill out UAA/OIDC fields for services below 43 | export UAA_URL=https://pks.${EXTERNAL_DNS_DOMAIN}:8443 44 | export UAA_ROOT_CA_CERT= #$(cat ~/Downloads/root_ca_certificate) 45 | 46 | 47 | ## concourse 48 | # hostname to register in DNS 49 | export CONCOURSE_DNS=concourse.${EXTERNAL_DNS_DOMAIN} 50 | # password for concourse admin user 51 | export CONCOURSE_ADMIN_PASSWORD=change-me-please 52 | # external url for concourse 53 | export CONCOURSE_URL=https://${CONCOURSE_DNS} 54 | ## concourse UAA/OIDC support 55 | # The UAA/OIDC user to add to 'main' group in concourse. 56 | export CONCOURSE_OIDC_USER=pksadmin 57 | # client id and secret for concourse to auth against UAA 58 | export CONCOURSE_OIDC_CLIENT_ID=concourse 59 | export CONCOURSE_OIDC_CLIENT_SECRET=a-bad-client-secret 60 | 61 | 62 | ## harbor 63 | # hostname to register in DNS 64 | export HARBOR_DNS=harbor.${EXTERNAL_DNS_DOMAIN} 65 | # A bunch of passwords and secrets that you should change 66 | export HARBOR_ADMIN_PASSWORD=change-me-please 67 | export HARBOR_SECRET_KEY=not-a-secure-key 68 | export HARBOR_DATABASE_PASSWORD=database-password 69 | export HARBOR_INTERNAL_SECRET=safDhgbrtresDF23 70 | export HARBOR_XSRFKEY=FDh8cR9Xh7F72FLUx9K4Z4ijO62DA1XIxctp0K8V 71 | ## harbor UAA auth 72 | # UAA/OIDC client id/secret to use to auth against UAA 73 | export HARBOR_OIDC_CLIENT_ID=harbor 74 | export HARBOR_OIDC_CLIENT_SECRET=a-bad-client-secret 75 | IFS='' read -r -d '' HARBOR_USER_SETTINGS_JSON </dev/null >/dev/null; then 4 | echo "Please install yq and try again" 5 | echo "https://mikefarah.gitbook.io/yq/#install" 6 | exit 1 7 | fi 8 | 9 | while getopts "hcdx" arg; do 10 | case $arg in 11 | h) 12 | echo "usage check-namespaces.sh [options]" 13 | echo "-h help" 14 | echo "-c create missing namespaces" 15 | exit 0 16 | ;; 17 | c) 18 | CREATE_NS=true 19 | ;; 20 | d) 21 | DEBUG=true 22 | ;; 23 | x) 24 | DELETE_NS=true 25 | ;; 26 | esac 27 | done 28 | 29 | # [[ -n $DEBUG ]] && set -x 30 | 31 | if [[ -n ${CREATE_NS} && -n ${DELETE_NS} ]]; then 32 | echo "-c and -x are exclusive" 33 | exit 1 34 | fi 35 | 36 | MERGE="m ${ENV_DIR}/charts.yaml.gotmpl charts.yaml" 37 | 38 | [[ -n $DEBUG ]] && echo "==> Calculating list of releases" 39 | RELEASES=$(yq ${MERGE} | yq r - --printMode p "charts.*" | sed 's/^charts\.//') 40 | 41 | [[ -n $DEBUG ]] && echo "----> releases: `echo $RELEASES | xargs`" 42 | for release in $RELEASES; do 43 | [[ -n $DEBUG ]] && echo "==> Checking release $release" 44 | ENABLED=$(yq ${MERGE} | yq r - "charts.${release}.enabled") 45 | if [[ "${ENABLED}" =~ ^(true|yes|1|TRUE|YES)$ ]]; then 46 | [[ -n $DEBUG ]] && echo "----> release $release is enabled" 47 | NS=$(yq ${MERGE} | yq r - "charts.${release}.namespace") 48 | if ! kubectl get namespace ${NS} 2>/dev/null >/dev/null; then 49 | [[ -n $DEBUG ]] && echo "----> namespace $NS is missing" 50 | if [[ ${CREATE_NS} == "true" ]]; then 51 | [[ -n $DEBUG ]] && echo "----> creating namespace $NS" 52 | kubectl create namespace ${NS} 53 | sleep 5 54 | continue 55 | fi 56 | elif [[ ${DELETE_NS} == "true" ]]; then 57 | [[ -n $DEBUG ]] && echo "----> deleting namespace $NS" 58 | kubectl delete namespace ${NS} 59 | sleep 5 60 | continue 61 | fi 62 | else 63 | [[ -n $DEBUG ]] && echo "----> release $release is disabled" 64 | continue 65 | fi 66 | [[ -n $DEBUG ]] && echo "----> namespace $NS exists" 67 | 68 | done -------------------------------------------------------------------------------- /scripts/create-namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -z "$1" ]]; then 4 | echo "Usage: ./scripts/create-namespace.sh " 5 | exit 1 6 | fi 7 | 8 | echo "====> Checking namespace $1" 9 | if ! kubectl get ns $1; then 10 | echo "====> creating namespace $1" 11 | kubectl create ns $1 12 | while ! kubectl get ns $1 > /dev/null ;do 13 | sleep 5 14 | done 15 | fi -------------------------------------------------------------------------------- /scripts/fileExists: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # hack until: https://github.com/roboll/helmfile/issues/766 3 | if [ ! -f "$1" ]; then 4 | echo -n 'false' 5 | else 6 | echo -n 'true' 7 | fi -------------------------------------------------------------------------------- /scripts/uaa-clients.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$1" == "create" ]]; then 4 | 5 | uaac client add ${CONCOURSE_OIDC_CLIENT_ID} --scope openid,roles,uaa.user \ 6 | --authorized_grant_types refresh_token,password,authorization_code \ 7 | --redirect_uri "https://${CONCOURSE_DNS}/sky/issuer/callback" \ 8 | --authorities clients.read,clients.secret,uaa.resource,scim.write,openid,scim.read \ 9 | --secret "${CONCOURSE_OIDC_CLIENT_SECRET}" 10 | 11 | uaac client add ${HARBOR_OIDC_CLIENT_ID} --scope openid \ 12 | --authorized_grant_types client_credentials,password,refresh_token \ 13 | --redirect_uri "https://${HARBOR_DNS} https://${HARBOR_DNS}/*" \ 14 | --secret "${HARBOR_OIDC_CLIENT_SECRET}" \ 15 | --authorities clients.read,clients.secret,uaa.resource,scim.write,openid,scim.read 16 | 17 | uaac client add "${SPINNAKER_OIDC_CLIENT_ID}" \ 18 | --scope openid,uaa.user,uaa.resource \ 19 | --authorized_grant_types password,refresh_token,authorization_code,client_credentials \ 20 | --redirect_uri "https://${SPINNAKER_GATE_DNS}/login" \ 21 | --secret "${SPINNAKER_OIDC_CLIENT_SECRET}" \ 22 | --authorities uaa.resource 23 | 24 | uaac client add "${GRAFANA_OIDC_CLIENT_ID}" \ 25 | --scope openid,profile,email \ 26 | --authorized_grant_types password,refresh_token,authorization_code,client_credentials \ 27 | --redirect_uri "${GRAFANA_URL}/login/generic_oauth" \ 28 | --secret "${GRAFANA_OIDC_CLIENT_SECRET}" \ 29 | --authorities uaa.resource 30 | 31 | uaac client add "${ELASTICSEARCH_OIDC_CLIENT_ID}" \ 32 | --scope openid,profile,email \ 33 | --authorized_grant_types password,refresh_token,authorization_code,client_credentials \ 34 | --redirect_uri "${KIBANA_URL}/api/security/v1/oidc" \ 35 | --secret "${ELASTICSEARCH_OIDC_CLIENT_SECRET}" \ 36 | --authorities uaa.resource 37 | exit 0 38 | fi 39 | 40 | if [[ "$1" == "destroy" || "$1" == "delete" ]]; then 41 | 42 | uaac client delete ${CONCOURSE_OIDC_CLIENT_ID} 43 | uaac client delete ${HARBOR_OIDC_CLIENT_ID} 44 | uaac client delete ${SPINNAKER_OIDC_CLIENT_ID} 45 | uaac client delete ${GRAFANA_OIDC_CLIENT_ID} 46 | uaac client delete ${ELASTICSEARCH_OIDC_CLIENT_ID} 47 | 48 | exit 0 49 | fi 50 | 51 | echo "Usage: ./scripts/uaa-clients.sh [create|destroy]" 52 | exit 1 -------------------------------------------------------------------------------- /scripts/yamlsplit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Will split a multiline YAML file into individual 4 | # files if created by helm it will name the files 5 | # based on the `# Source:` comment in the YAML. 6 | 7 | # Usage: helm template . | yamlsplit 8 | # Usage: . envs/default && helmfile template . | yamlsplit 9 | 10 | # Copyright 2019 Paul Czarkowski 11 | 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | 24 | 25 | count=0 26 | file_size=0 27 | file_number=0 28 | file_content=() 29 | regex='# Source: (.*)' 30 | 31 | OUTDIR=${1} 32 | 33 | if [[ "${OUTDIR}" == "" ]]; then 34 | echo "Usage ./split.sh " 35 | exit 1 36 | fi 37 | 38 | if [[ ! -d "${OUTDIR}" ]]; then 39 | echo "Usage ./split.sh " 40 | echo "${OUTDIR} is not a directory" 41 | exit 1 42 | fi 43 | 44 | while IFS= read -r line; do 45 | let count+=1 46 | if [[ "${line}" != "---" ]]; then 47 | if [[ "${line}" =~ $regex ]]; then 48 | file_name="${BASH_REMATCH[1]//\//_}" 49 | fi 50 | file_content+=("${line}") 51 | let file_size+=1 52 | else # if [[ "${line}" == "---" ]] 53 | count=0 54 | if [[ ${file_size} -eq 0 ]]; then 55 | continue 56 | else 57 | if [[ "${file_name}" == "" ]]; then 58 | file_name="file-${file_number}.yaml" 59 | fi 60 | echo "--> Writing ${OUTDIR}/${file_name}" 61 | printf "%s\n" "${file_content[@]}" > ${OUTDIR}/${file_name} 62 | fi 63 | file_size=0 64 | file_content=() 65 | file_name="" 66 | let file_number+=1 67 | fi 68 | done 69 | -------------------------------------------------------------------------------- /values.yaml: -------------------------------------------------------------------------------- 1 | ## default values to be rendered into helmfile 2 | ## templates go here. They are namespaced under 3 | ## the `_` key to ensure they don't interfere 4 | ## with the values for the actual helm charts. 5 | 6 | _: 7 | ingress: 8 | enabled: false 9 | -------------------------------------------------------------------------------- /values/gangway/values.yaml.gotmpl: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | 3 | image: 4 | repository: paulczar/gangway 5 | tag: workshop 6 | pullPolicy: IfNotPresent 7 | 8 | nameOverride: gangway 9 | fullnameOverride: gangway 10 | 11 | # Specify a CA cert to trust for self signed certificates at the Oauth2 URLs. Be careful to indent one level beyond the 12 | # trustedCACert key: 13 | # trustedCACert: |- 14 | # -----BEGIN CERTIFICATE----- 15 | # ... 16 | # -----END CERTIFICATE----- 17 | 18 | gangway: 19 | # The address to listen on. Defaults to 0.0.0.0 to listen on all interfaces. 20 | # Env var: GANGWAY_HOST 21 | # host: 0.0.0.0 22 | 23 | # The port to listen on. Defaults to 8080. 24 | # Env var: GANGWAY_PORT 25 | port: 8080 26 | 27 | # Should Gangway serve TLS vs. plain HTTP? Default: false 28 | # Env var: GANGWAY_SERVE_TLS 29 | # serveTLS: false 30 | 31 | # The public cert file (including root and intermediates) to use when serving TLS. 32 | # Env var: GANGWAY_CERT_FILE 33 | # certFile: /etc/gangway/tls/tls.crt 34 | 35 | # The private key file when serving TLS. 36 | # Env var: GANGWAY_KEY_FILE 37 | # keyFile: /etc/gangway/tls/tls.key 38 | 39 | clusterName: "{{ env "ENV_NAME" }}" 40 | authorizeURL: {{ env "GANGWAY_OIDC_AUTH_URL"}} 41 | tokenURL: {{ env "GANGWAY_OIDC_TOKEN_URL" }} 42 | audience: {{ env "GANGWAY_OIDC_USERINFO_URL" }} 43 | scopes: ["openid","uaa.user", "roles"] 44 | redirectURL: "{{ env "GANGWAY_URL" }}/callback" 45 | clientID: {{ env "GANGWAY_OIDC_CLIENT_ID" }} 46 | clientSecret: "{{ env "GANGWAY_OIDC_CLIENT_SECRET" }}" 47 | allowEmptyClientSecret: true 48 | usernameClaim: "user_name" 49 | namespaceClaim: "user_name" 50 | emailClaim: "user_name" 51 | 52 | apiServerURL: {{ requiredEnv "K8S_API_URL" }} 53 | 54 | sessionKey: {{ requiredEnv "GANGWAY_SESSION_KEY" }} 55 | 56 | tls: {} 57 | # certData: | 58 | # -----BEGIN CERTIFICATE----- 59 | # ... 60 | # -----END CERTIFICATE----- 61 | # keyData: | 62 | # -----BEGIN ENCRYPTED PRIVATE KEY----- 63 | # ... 64 | # -----END ENCRYPTED PRIVATE KEY----- 65 | 66 | # Name of an existing secret containing `tls.cert` and `tls.key`. 67 | # Mounted on the default tls path `/etc/gangway/tls` 68 | # existingSecret: "" 69 | 70 | extraVolumes: [] 71 | 72 | extraVolumeMounts: [] 73 | 74 | livenessProbe: 75 | # HTTP or HTTPS 76 | scheme: HTTP 77 | 78 | readinessProbe: 79 | # HTTP or HTTPS 80 | scheme: HTTP 81 | 82 | service: 83 | type: ClusterIP 84 | port: 80 85 | # Specifies a loadBalancerIP when using LoadBalancer service type 86 | # loadBalancerIP: 192.168.0.51 87 | 88 | {{- if .Values.ingress.enabled }} 89 | ingress: 90 | enabled: true 91 | hosts: [{{ env "GANGWAY_DNS" }}] 92 | tls: 93 | - secretName: gangway-tls 94 | hosts: 95 | - {{ env "GANGWAY_DNS" }} 96 | annotations: 97 | kubernetes.io/ingress.class: 'nginx' 98 | ingress.kubernetes.io/ssl-redirect: 'true' 99 | cert-manager.io/cluster-issuer: 'letsencrypt-prod' 100 | cert-manager.io/acme-challenge-type: 'dns01' 101 | cert-manager.io/acme-dns01-provider: 'prod-clouddns' 102 | kubernetes.io/tls-acme: 'true' 103 | nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" 104 | {{- end }} 105 | 106 | resources: 107 | cpu: 100m 108 | memory: 128Mi 109 | requests: 110 | cpu: 100m 111 | memory: 128Mi 112 | --------------------------------------------------------------------------------