αž€αžΆαžšαžšαŸ€αž”αž…αŸ†αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αž‘αŸ…αž€αžΆαž“αŸ‹αž”αžšαž·αžŸαŸ’αžαžΆαž“ k8s αž…αŸ’αžšαžΎαž“αžŠαŸ„αž™αž”αŸ’αžšαžΎ helmfile

Helmfile - αžšαž»αŸ†αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ αž˜αž½αž€αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αžŠαŸ‚αž›αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž’αŸ’αž“αž€αž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž˜αž½αž€αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αž‡αžΆαž…αŸ’αžšαžΎαž“αž“αŸ…αž€αŸ’αž“αž»αž„αž€αž“αŸ’αž›αŸ‚αž„αžαŸ‚αž˜αž½αž™ αž€αŸ†αžŽαžαŸ‹αžαžΆαžšαžΆαž„αžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž”αžšαž·αžŸαŸ’αžαžΆαž“αž‡αžΆαž…αŸ’αžšαžΎαž“ αž“αž·αž„αž€αŸ†αžŽαžαŸ‹αž›αŸ†αžŠαžΆαž”αŸ‹αž“αŸƒαž€αžΆαžšαžŠαžΆαž€αŸ‹αž±αŸ’αž™αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸαž•αž„αžŠαŸ‚αžšαŸ”

αž’αŸ’αž“αž€αž’αžΆαž…αž’αžΆαž“αž’αŸ†αž–αžΈ Helmfile αžαŸ’αž›αž½αž“αžœαžΆ αž“αž·αž„αž§αž‘αžΆαž αžšαžŽαŸαž“αŸƒαž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αžšαž”αžŸαŸ‹αžœαžΆαž“αŸ…αž€αŸ’αž“αž»αž„ README ΠΈ αž€αžΆαžšαžŽαŸ‚αž“αžΆαŸ†αž›αŸ’αž’αž”αŸ†αž•αž»αž.

αž™αžΎαž„β€‹αž“αžΉαž„β€‹αžŸαŸ’αž‚αžΆαž›αŸ‹β€‹αž–αžΈβ€‹αžœαž·αž’αžΈβ€‹αž˜αž·αž“β€‹αž…αŸ’αž”αžΆαžŸαŸ‹β€‹αž›αžΆαžŸαŸ‹β€‹αž€αŸ’αž“αž»αž„β€‹αž€αžΆαžšβ€‹αž–αž·αž–αžŽαŸŒαž“αžΆβ€‹αž’αŸ†αž–αžΈβ€‹αž€αžΆαžšβ€‹αž…αŸαž‰β€‹αž•αŸ’αžŸαžΆαž™β€‹αž€αŸ’αž“αž»αž„β€‹helmfile

αž…αžΌαžšαž“αž·αž™αžΆαž™αžαžΆαž™αžΎαž„αž˜αžΆαž“αž€αž‰αŸ’αž…αž”αŸ‹αž“αŸƒαžαžΆαžšαžΆαž„αž‡αŸ†αž“αž½αž™ (αž§αž‘αžΆαž αžšαžŽαŸ αž…αžΌαžšαž“αž·αž™αžΆαž™αžαžΆ postgres αž“αž·αž„αž€αž˜αŸ’αž˜αžœαž·αž’αžΈ backend αž˜αž½αž™αž…αŸ†αž“αž½αž“) αž“αž·αž„αž”αžšαž·αžŸαŸ’αžαžΆαž“αž‡αžΆαž…αŸ’αžšαžΎαž“ (αž…αž„αŸ’αž€αŸ„αž˜ kubernetes αž‡αžΆαž…αŸ’αžšαžΎαž“ αž…αž“αŸ’αž›αŸ„αŸ‡αžˆαŸ’αž˜αŸ„αŸ‡αž‡αžΆαž…αŸ’αžšαžΎαž“ αž¬αž‘αžΆαŸ†αž„αž–αžΈαžšαž‘αžΆαŸ†αž„αž–αžΈαžš)αŸ” αž™αžΎαž„αž™αž€αž―αž€αžŸαžΆαžšαž‡αŸ†αž“αž½αž™ αž’αžΆαž“αž―αž€αžŸαžΆαžš αž αžΎαž™αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαž”αžšαž·αžŸαŸ’αžαžΆαž“ αž“αž·αž„αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αžšαž”αžŸαŸ‹αž™αžΎαž„αŸ–

    .
    β”œβ”€β”€ envs
    β”‚   β”œβ”€β”€ devel
    β”‚   β”‚   └── values
    β”‚   β”‚       β”œβ”€β”€ backend.yaml
    β”‚   β”‚       └── postgres.yaml
    β”‚   └── production
    β”‚       └── values
    β”‚           β”œβ”€β”€ backend.yaml
    β”‚           └── postgres.yaml
    └── helmfile.yaml

helmfile.yaml

environments:
  devel:
  production:

releases:
  - name: postgres
    labels:
      app: postgres
    wait: true
    chart: stable/postgresql
    version: 8.4.0
    values:
      - envs/{{ .Environment.Name }}/values/postgres.yaml
  - name: backend
    labels:
      app: backend
    wait: true
    chart: private-helm-repo/backend
    version: 1.0.5
    needs:
      - postgres
    values:
      - envs/{{ .Environment.Name }}/values/backend.yaml

αž™αžΎαž„αž”αžΆαž“αž”αž‰αŸ’αž…αž”αŸ‹αž‡αžΆαž˜αž½αž™αž“αžΉαž„ 2 αž”αžšαž·αžŸαŸ’αžαžΆαž“αŸ– αžŠαŸαž”αŸ‰αžΌ, αž•αž›αž·αžαž€αž˜αŸ’αž˜ β€” αž“αžΈαž˜αž½αž™αŸ—β€‹αž˜αžΆαž“β€‹αžαž˜αŸ’αž›αŸƒβ€‹αž•αŸ’αž‘αžΆαž›αŸ‹β€‹αžαŸ’αž›αž½αž“β€‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹β€‹αžαžΆαžšαžΆαž„β€‹αž…αŸαž‰β€‹αž˜αž½αž€αŸ” αž™αžΎαž„αž“αžΉαž„αžŠαžΆαž€αŸ‹αž±αŸ’αž™αž–αž½αž€αž‚αŸαžŠαžΌαž…αž“αŸαŸ‡αŸ–

helmfile -n <namespace> -e <env> apply

αž€αŸ†αžŽαŸ‚αž•αŸ’αžŸαŸαž„αž‚αŸ’αž“αžΆαž“αŸƒαž‚αŸ†αž“αžΌαžŸαžαžΆαž„αž˜αž½αž€αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αž“αŸ…αž€αŸ’αž“αž»αž„αž”αžšαž·αž™αžΆαž€αžΆαžŸαž•αŸ’αžŸαŸαž„αŸ—αž‚αŸ’αž“αžΆ

αž…αž»αŸ‡β€‹αž”αžΎβ€‹αž™αžΎαž„β€‹αžαŸ’αžšαžΌαžœβ€‹αž€αžΆαžšβ€‹αž…αŸαž‰β€‹αž€αŸ†αžŽαŸ‚β€‹αž•αŸ’αžŸαŸαž„β€‹αž‚αŸ’αž“αžΆβ€‹αž“αŸƒ backend αž‘αŸ…β€‹αž”αžšαž·αžŸαŸ’αžαžΆαž“β€‹αž•αŸ’αžŸαŸαž„β€‹αž‚αŸ’αž“αžΆ? αžαžΎαž’αŸ’αžœαžΎαžŠαžΌαž…αž˜αŸ’αžαŸαž…αžŠαžΎαž˜αŸ’αž”αžΈαž€αŸ†αžŽαžαŸ‹αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαž€αŸ†αžŽαŸ‚αž…αŸαž‰αž•αŸ’αžŸαžΆαž™? αžαž˜αŸ’αž›αŸƒαž”αžšαž·αžŸαŸ’αžαžΆαž“αžŠαŸ‚αž›αž’αžΆαž…αžšαž€αž”αžΆαž“αžαžΆαž˜αžšαž™αŸˆ {{ .Values }}

helmfile.yaml

environments:
  devel:
+   values:
+   - charts:
+       versions:
+         backend: 1.1.0
  production:
+   values:
+   - charts:
+       versions:
+         backend: 1.0.5
...
  - name: backend
    labels:
      app: backend
    wait: true
    chart: private-helm-repo/backend
-   version: 1.0.5
+   version: {{ .Values.charts.versions.backend }}
...

αžŸαŸ†αžŽαž»αŸ†αž•αŸ’αžŸαŸαž„αž‚αŸ’αž“αžΆαž“αŸƒαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž“αŸ…αž€αŸ’αž“αž»αž„αž”αžšαž·αžŸαŸ’αžαžΆαž“αž•αŸ’αžŸαŸαž„αž‚αŸ’αž“αžΆ

αž›αŸ’αž’αžŽαžΆαžŸαŸ‹ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž…αž»αŸ‡αž”αžΎαž™αžΎαž„αž˜αž·αž“αžαŸ’αžšαžΌαžœαž€αžΆαžš production αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜ postgres αž–αžΈαž–αŸ’αžšαŸ„αŸ‡αž™αžΎαž„αžŠαžΉαž„αžαžΆαž™αžΎαž„αž˜αž·αž“αž…αžΆαŸ†αž”αžΆαž…αŸ‹αžšαž»αž‰αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αž‘αŸ…αž‡αžΆ k8s αž αžΎαž™αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž›αž€αŸ‹αž™αžΎαž„αž˜αžΆαž“αž…αž„αŸ’αž€αŸ„αž˜ postgres αžŠαžΆαž…αŸ‹αžŠαŸ„αž™αž‘αŸ‚αž€αžŠαŸαž’αžŸαŸ’αž…αžΆαžšαŸ’αž™? αžŠαžΎαž˜αŸ’αž”αžΈαžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž”αž‰αŸ’αž αžΆαž“αŸαŸ‡ αž™αžΎαž„αž˜αžΆαž“αžŸαŸ’αž›αžΆαž€αžŸαž‰αŸ’αž‰αžΆ

helmfile -n <namespace> -e devel apply
helmfile -n <namespace> -e production -l app=backend apply

αž“αŸαŸ‡αž›αŸ’αž’αžŽαžΆαžŸαŸ‹ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžαŸ’αž‰αž»αŸ†αž…αžΌαž›αž…αž·αžαŸ’αžαž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŽαžΆαž˜αž½αž™αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαžŠαžΆαž€αŸ‹αž±αŸ’αž™αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž€αŸ’αž“αž»αž„αž”αžšαž·αžŸαŸ’αžαžΆαž“αžŠαŸ‚αž›αž˜αž·αž“αž”αŸ’αžšαžΎαž’αžΆαž‚αž»αž™αž˜αŸ‰αž„αŸ‹αž“αŸƒαž€αžΆαžšαž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΆαžšαž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαž”αžšαž·αžŸαŸ’αžαžΆαž“αžαŸ’αž›αž½αž“αž―αž„αŸ” αž’αŸ’αžœαžΈβ€‹αžŠαŸ‚αž›β€‹αžαŸ’αžšαžΌαžœαž’αŸ’αžœαžΎ? αž’αŸ’αž“αž€αž’αžΆαž…αžŠαžΆαž€αŸ‹αž€αžΆαžšαž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž“αŸ…αž€αŸ’αž“αž»αž„αžαžαžŠαžΆαž…αŸ‹αžŠαŸ„αž™αž‘αŸ‚αž€αž˜αž½αž™ αž”αž„αŸ’αž€αžΎαžαž”αž‰αŸ’αž‡αžΈαž“αŸƒαž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž…αžΆαŸ†αž”αžΆαž…αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΆαžšαž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαž”αžšαž·αžŸαŸ’αžαžΆαž“ αž“αž·αž„ "αž™αž€" αžαŸ‚αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž…αžΆαŸ†αž”αžΆαž…αŸ‹αžŠαŸ„αž™αž˜αž·αž“αž’αžΎαž–αžΎαž’αŸ’αžœαžΈαžŠαŸ‚αž›αž“αŸ…αžŸαž›αŸ‹αŸ”

    .
    β”œβ”€β”€ envs
    β”‚   β”œβ”€β”€ devel
    β”‚   β”‚   └── values
    β”‚   β”‚       β”œβ”€β”€ backend.yaml
    β”‚   β”‚       └── postgres.yaml
    β”‚   └── production
    β”‚       └── values
    β”‚           β”œβ”€β”€ backend.yaml
    β”‚           └── postgres.yaml
+   β”œβ”€β”€ releases
+   β”‚   β”œβ”€β”€ backend.yaml
+   β”‚   └── postgres.yaml
    └── helmfile.yaml

helmfile.yaml


  environments:
    devel:
      values:
      - charts:
          versions:
            backend: 1.1.0
      - apps:
        - postgres
        - backend

    production:
      values:
      - charts:
          versions:
            backend: 1.0.5
      - apps:
        - backend

- releases:
-    - name: postgres
-      labels:
-        app: postgres
-      wait: true
-      chart: stable/postgresql
-      version: 8.4.0
-      values:
-        - envs/{{ .Environment.Name }}/values/postgres.yaml
-    - name: backend
-      labels:
-        app: backend
-      wait: true
-      chart: private-helm-repo/backend
-     version: {{ .Values.charts.versions.backend }}
-     needs:
-       - postgres
-     values:
-       - envs/{{ .Environment.Name }}/values/backend.yaml
+ ---
+ bases:
+ {{- range .Values.apps }}
+   - releases/{{ . }}.yaml
+ {{- end }}

releases/postgres.yaml

releases:
  - name: postgres
    labels:
      app: postgres
    wait: true
    chart: stable/postgresql
    version: 8.4.0
    values:
      - envs/{{ .Environment.Name }}/values/postgres.yaml

releases/backend.yaml

releases:
  - name: backend
    labels:
      app: backend
    wait: true
    chart: private-helm-repo/backend
    version: {{ .Values.charts.versions.backend }}
    needs:
      - postgres
    values:
      - envs/{{ .Environment.Name }}/values/backend.yaml

αž€αŸ†αžŽαžαŸ‹αžŸαŸ†αž‚αžΆαž›αŸ‹

αž“αŸ…αž–αŸαž›αž”αŸ’αžšαžΎ bases: αžœαžΆαž…αžΆαŸ†αž”αžΆαž…αŸ‹αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αŸ’αžšαžΎαž§αž”αž€αžšαžŽαŸαž”αŸ†αž”αŸ‚αž€ yaml ---αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž’αŸ’αž“αž€αž’αžΆαž…αž”αž„αŸ’αž€αžΎαžαž‚αŸ†αžšαžΌαž…αŸαž‰αž•αŸ’αžŸαžΆαž™ (αž“αž·αž„αž•αŸ’αž“αŸ‚αž€αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαžŠαžΌαž…αž‡αžΆ helmDefaults) αž‡αžΆαž˜αž½αž™αž“αžΉαž„αžαž˜αŸ’αž›αŸƒαž–αžΈαž”αžšαž·αžŸαŸ’αžαžΆαž“

αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž“αŸαŸ‡ αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™ Postgres αž“αžΉαž„αž˜αž·αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαžΆαž”αŸ‹αž”αž‰αŸ’αž…αžΌαž›αž€αŸ’αž“αž»αž„αž€αžΆαžšαž–αž·αž–αžŽαŸŒαž“αžΆαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž•αž›αž·αžαž“αŸ„αŸ‡αž‘αŸαŸ” αžŸαŸ’αžšαž½αž›αžŽαžΆαžŸαŸ‹!

αžαž˜αŸ’αž›αŸƒαžŸαž€αž›αžŠαŸ‚αž›αž’αžΆαž…αž”αžŠαž·αžŸαŸαž’αž”αžΆαž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™

αž‡αžΆαž€αžΆαžšαž–αž·αžαžŽαžΆαžŸαŸ‹ αžœαžΆαž–αž·αžαž‡αžΆαž›αŸ’αž’αžŽαžΆαžŸαŸ‹αžŠαŸ‚αž›αž’αŸ’αž“αž€αž’αžΆαž…αž€αŸ†αžŽαžαŸ‹αžαž˜αŸ’αž›αŸƒαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‚αŸ†αž“αžΌαžŸαžαžΆαž„αž˜αž½αž€αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž”αžšαž·αžŸαŸ’αžαžΆαž“αž“αžΈαž˜αž½αž™αŸ— αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž…αž»αŸ‡αž™αŸ‰αžΆαž„αžŽαžΆαž”αžΎαž™αžΎαž„αž˜αžΆαž“αž”αžšαž·αžŸαŸ’αžαžΆαž“αž‡αžΆαž…αŸ’αžšαžΎαž“αžŠαŸ‚αž›αž”αžΆαž“αž–αž·αž–αžŽαŸŒαž“αžΆ αž αžΎαž™αž™αžΎαž„αž…αž„αŸ‹αž€αŸ†αžŽαžαŸ‹αžŠαžΌαž…αž‚αŸ’αž“αžΆαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž‚αŸ’αž“αžΆαŸ” affinityαž”αŸ‰αž»αž“αŸ’αžαŸ‚αž™αžΎαž„αž˜αž·αž“αž…αž„αŸ‹αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžœαžΆαžαžΆαž˜αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αž“αŸ…αž€αŸ’αž“αž»αž„αž‚αŸ†αž“αžΌαžŸαžαžΆαž„αžŠαŸ„αž™αžαŸ’αž›αž½αž“αž―αž„αž‘αŸ αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž“αŸ…αž€αŸ’αž“αž»αž„ turnips αŸ”

αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž“αŸαŸ‡ αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž“αžΈαž˜αž½αž™αŸ— αž™αžΎαž„αž’αžΆαž…αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž―αž€αžŸαžΆαžšαž…αŸ†αž“αž½αž“ 2 αž‡αžΆαž˜αž½αž™αž“αžΉαž„αžαž˜αŸ’αž›αŸƒαŸ– αž‘αžΈαž˜αž½αž™αž‡αžΆαž˜αž½αž™αž“αžΉαž„αžαž˜αŸ’αž›αŸƒαž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜ αžŠαŸ‚αž›αž“αžΉαž„αž€αŸ†αžŽαžαŸ‹αžαž˜αŸ’αž›αŸƒαž“αŸƒαž‚αŸ†αž“αžΌαžŸαžαžΆαž„αžαŸ’αž›αž½αž“αžœαžΆ αž“αž·αž„αž‘αžΈαž–αžΈαžšαž‡αžΆαž˜αž½αž™αž“αžΉαž„αžαž˜αŸ’αž›αŸƒαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž”αžšαž·αžŸαŸ’αžαžΆαž“ αžŠαŸ‚αž›αž“αŸ…αž€αŸ’αž“αž»αž„αžœαŸαž“αž“αžΉαž„αž”αžŠαž·αžŸαŸαž’αŸ” αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αŸ”

    .
    β”œβ”€β”€ envs
+   β”‚   β”œβ”€β”€ default
+   β”‚   β”‚   └── values
+   β”‚   β”‚       β”œβ”€β”€ backend.yaml
+   β”‚   β”‚       └── postgres.yaml
    β”‚   β”œβ”€β”€ devel
    β”‚   β”‚   └── values
    β”‚   β”‚       β”œβ”€β”€ backend.yaml
    β”‚   β”‚       └── postgres.yaml
    β”‚   └── production
    β”‚       └── values
    β”‚           β”œβ”€β”€ backend.yaml
    β”‚           └── postgres.yaml
    β”œβ”€β”€ releases
    β”‚   β”œβ”€β”€ backend.yaml
    β”‚   └── postgres.yaml
    └── helmfile.yaml

releases/backend.yaml

releases:
  - name: backend
    labels:
      app: backend
    wait: true
    chart: private-helm-repo/backend
    version: {{ .Values.charts.versions.backend }}
    needs:
      - postgres
    values:
+     - envs/default/values/backend.yaml
      - envs/{{ .Environment.Name }}/values/backend.yaml

envs/default/values/backend.yaml

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app.kubernetes.io/name
            operator: In
            values:
            - backend
        topologyKey: "kubernetes.io/hostname"

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžαž˜αŸ’αž›αŸƒαžŸαž€αž›αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžαžΆαžšαžΆαž„αž˜αž½αž€αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αž“αŸƒαž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸ…αž€αž˜αŸ’αžšαž·αžαž”αžšαž·αžŸαŸ’αžαžΆαž“

αž…αžΌαžšαž“αž·αž™αžΆαž™αžαžΆαž™αžΎαž„αž”αž„αŸ’αž€αžΎαž ingress αž‡αžΆαž…αŸ’αžšαžΎαž“αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž‡αžΆαž…αŸ’αžšαžΎαž“ - αž™αžΎαž„αž’αžΆαž…αž€αŸ†αžŽαžαŸ‹αžŠαŸ„αž™αžŠαŸƒαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžαžΆαžšαžΆαž„αž“αžΈαž˜αž½αž™αŸ— hosts:αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαžšαž”αžŸαŸ‹αž™αžΎαž„ αžŠαŸ‚αž“αž‚αžΊαžŠαžΌαž…αž‚αŸ’αž“αžΆ αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž αŸαžαž»αž’αŸ’αžœαžΈαž”αžΆαž“αž‡αžΆαž˜αž·αž“αžŠαžΆαž€αŸ‹αžœαžΆαž“αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸαžšαžŸαž€αž›αž˜αž½αž™αž…αŸ†αž“αž½αž“ αž αžΎαž™αž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αž‡αŸ†αž“αž½αžŸαžαž˜αŸ’αž›αŸƒαžšαž”αžŸαŸ‹αžœαžΆαž‘αŸ…αž€αŸ’αž“αž»αž„αžαžΆαžšαžΆαž„? αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαžŠαžΌαž…αž“αŸαŸ‡αž―αž€αžŸαžΆαžšαž‘αžΆαŸ†αž„αž“αŸ„αŸ‡αžŠαŸ‚αž›αž˜αžΆαž“αžαž˜αŸ’αž›αŸƒαžŠαŸ‚αž›αž™αžΎαž„αž…αž„αŸ‹αž€αŸ†αžŽαžαŸ‹αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαž“αžΉαž„αžαŸ’αžšαžΌαžœαž˜αžΆαž“αž•αŸ’αž“αŸ‚αž€αž”αž“αŸ’αžαŸ‚αž˜ .gotmplαžŠαžΌαž…αŸ’αž“αŸαŸ‡ helmfile αžŠαžΉαž„αžαžΆαžœαžΆαžαŸ’αžšαžΌαžœαžαŸ‚αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžαžΆαž˜αžšαž™αŸˆαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž‚αŸ†αžšαžΌαŸ”

    .
    β”œβ”€β”€ envs
    β”‚   β”œβ”€β”€ default
    β”‚   β”‚   └── values
-   β”‚   β”‚       β”œβ”€β”€ backend.yaml
-   β”‚   β”‚       β”œβ”€β”€ postgres.yaml
+   β”‚   β”‚       β”œβ”€β”€ backend.yaml.gotmpl
+   β”‚   β”‚       └── postgres.yaml.gotmpl
    β”‚   β”œβ”€β”€ devel
    β”‚   β”‚   └── values
    β”‚   β”‚       β”œβ”€β”€ backend.yaml
    β”‚   β”‚       └── postgres.yaml
    β”‚   └── production
    β”‚       └── values
    β”‚           β”œβ”€β”€ backend.yaml
    β”‚           └── postgres.yaml
    β”œβ”€β”€ releases
    β”‚   β”œβ”€β”€ backend.yaml
    β”‚   └── postgres.yaml
    └── helmfile.yaml

helmfile.yaml

  environments:
    devel:
      values:
      - charts:
          versions:
            backend: 1.1.0
      - apps:
        - postgres
        - backend
+     - global:
+         ingressDomain: k8s.devel.domain

    production:
      values:
      - charts:
          versions:
            backend: 1.0.5
      - apps:
        - backend
+     - global:
+         ingressDomain: production.domain
  ---
  bases:
  {{- range .Values.apps }}
    - releases/{{ . }}.yaml
  {{- end }}

envs/default/values/backend.yaml.gotmpl

ingress:
  enabled: true
  paths:
    - /api
  hosts:
    - {{ .Values.global.ingressDomain }}

envs/default/values/postgres.yaml.gotmpl

ingress:
  enabled: true
  paths:
    - /
  hosts:
    - postgres.{{ .Values.global.ingressDomain }}

αž€αŸ†αžŽαžαŸ‹αžŸαŸ†αž‚αžΆαž›αŸ‹

αž‡αžΆαž€αŸ‹αžŸαŸ’αžαŸ‚αž„ αž€αžΆαžšαž…αžΌαž›αž“αŸ…αž€αŸ’αž“αž»αž„αžαžΆαžšαžΆαž„ postgres αž‚αžΊαž‡αžΆαž’αŸ’αžœαžΈαžŠαŸ‚αž›αž‚αž½αžšαž±αŸ’αž™αžŸαž„αŸ’αžŸαŸαž™αž”αŸ†αž•αž»αž αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž’αžαŸ’αžαž”αž‘αž“αŸαŸ‡αžαŸ’αžšαžΌαžœαž”αžΆαž“αž•αŸ’αžαž›αŸ‹αž±αŸ’αž™αž™αŸ‰αžΆαž„αžŸαžΆαž˜αž‰αŸ’αž‰αž‡αžΆαž§αž‘αžΆαž αžšαžŽαŸαžšαžΆαž„αžŸαŸ’αžœαŸŠαŸ‚αžšαž“αŸ…αž€αŸ’αž“αž»αž„αž€αž“αŸ’αž›αŸ‚αž„αž‘αŸ†αž“αŸαžšαž˜αž½αž™ αž αžΎαž™αžŠαžΎαž˜αŸ’αž”αžΈαž€αž»αŸ†αž±αŸ’αž™αžŽαŸ‚αž“αžΆαŸ†αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αžαŸ’αž˜αžΈαž˜αž½αž™αž…αŸ†αž“αž½αž“αž‘αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸ’αžαž”αž‘αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžαŸ‚αž€αžΆαžšαž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈ ingress αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ”

αž€αžΆαžšαž‡αŸ†αž“αž½αžŸαž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„αž–αžΈαžαž˜αŸ’αž›αŸƒαž”αžšαž·αžŸαŸ’αžαžΆαž“

αžŠαŸ„αž™αž—αžΆαž–αžŸαŸ’αžšαžŠαŸ€αž„αž‚αŸ’αž“αžΆαž‡αžΆαž˜αž½αž™αž§αž‘αžΆαž αžšαžŽαŸαžαžΆαž„αž›αžΎ αž’αŸ’αž“αž€αž’αžΆαž…αž‡αŸ†αž“αž½αžŸαž€αžΆαžšαž’αŸŠαž·αž“αž‚αŸ’αžšαžΈαž”αžŠαŸ„αž™αž”αŸ’αžšαžΎ αž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„αž“αŸƒαž˜αž½αž€αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž– αž’αžαŸ’αžαž“αŸαž™αŸ” αž‡αŸ†αž“αž½αžŸαž±αŸ’αž™αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαž―αž€αžŸαžΆαžšαžŸαž˜αŸ’αž„αžΆαžαŸ‹αž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αžšαž”αžŸαŸ‹αž™αžΎαž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™αž“αžΈαž˜αž½αž™αŸ— αžŠαŸ‚αž›αž™αžΎαž„αž’αžΆαž…αž€αŸ†αžŽαžαŸ‹αžαž˜αŸ’αž›αŸƒαžŠαŸ‚αž›αž”αžΆαž“αž’αŸŠαž·αž“αž‚αŸ’αžšαžΈαž”αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‚αŸ†αž“αžΌαžŸαžαžΆαž„αž“αŸ„αŸ‡ αž™αžΎαž„αž’αžΆαž…αž€αŸ†αžŽαžαŸ‹αž™αŸ‰αžΆαž„αžŸαžΆαž˜αž‰αŸ’αž‰αž€αŸ’αž“αž»αž„αž€αžΆαžšαž…αŸαž‰αž•αŸ’αžŸαžΆαž™ default.yaml.gotmpl αžαž˜αŸ’αž›αŸƒαžŠαŸ‚αž›αž“αžΉαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αž™αž€αž…αŸαž‰αž–αžΈαž’αžαŸαžšαžŠαŸ‚αž›αž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αž“αŸ… αž€αž˜αŸ’αžšαž·αžαž”αžšαž·αžŸαŸ’αžαžΆαž“αŸ” αž αžΎαž™β€‹αžαž˜αŸ’αž›αŸƒβ€‹αžŠαŸ‚αž›β€‹αž™αžΎαž„β€‹αž˜αž·αž“β€‹αžαŸ’αžšαžΌαžœβ€‹αž€αžΆαžšβ€‹αž›αžΆαž€αŸ‹β€‹αž–αžΈβ€‹αž’αŸ’αž“αž€β€‹αžŽαžΆβ€‹αž˜αŸ’αž“αžΆαž€αŸ‹β€‹αž’αžΆαž…β€‹αžαŸ’αžšαžΌαžœβ€‹αž”αžΆαž“β€‹αž€αŸ†αžŽαžαŸ‹β€‹αž‘αžΎαž„β€‹αžœαž·αž‰β€‹αž™αŸ‰αžΆαž„β€‹αž„αžΆαž™β€‹αžŸαŸ’αžšαž½αž›β€‹αž€αŸ’αž“αž»αž„β€‹αžαž˜αŸ’αž›αŸƒβ€‹αž…αŸαž‰β€‹αž€αŸ’αž“αž»αž„β€‹αž”αžšαž·αž™αžΆαž€αžΆαžŸβ€‹αž‡αžΆαž€αŸ‹αž›αžΆαž€αŸ‹αŸ”

    .
    β”œβ”€β”€ envs
    β”‚   β”œβ”€β”€ default
    β”‚   β”‚   └── values
    β”‚   β”‚       β”œβ”€β”€ backend.yaml
    β”‚   β”‚       └── postgres.yaml
    β”‚   β”œβ”€β”€ devel
    β”‚   β”‚   β”œβ”€β”€ values
    β”‚   β”‚   β”‚   β”œβ”€β”€ backend.yaml
    β”‚   β”‚   β”‚   └── postgres.yaml
+   β”‚   β”‚   └── secrets.yaml
    β”‚   └── production
    β”‚       β”œβ”€β”€ values
    β”‚       β”‚   β”œβ”€β”€ backend.yaml
    β”‚       β”‚   └── postgres.yaml
+   β”‚       └── secrets.yaml
    β”œβ”€β”€ releases
    β”‚   β”œβ”€β”€ backend.yaml
    β”‚   └── postgres.yaml
    └── helmfile.yaml

helmfile.yaml

  environments:
    devel:
      values:
      - charts:
          versions:
            backend: 1.1.0
      - apps:
        - postgres
        - backend
      - global:
          ingressDomain: k8s.devel.domain
+     secrets:
+       - envs/devel/secrets.yaml

    production:
      values:
      - charts:
          versions:
            backend: 1.0.5
      - apps:
        - backend
      - global:
          ingressDomain: production.domain
+     secrets:
+       - envs/production/secrets.yaml
  ---
  bases:
  {{- range .Values.apps }}
    - releases/{{ . }}.yaml
  {{- end }}

envs/devel/secrets.yaml

secrets:
    elastic:
        password: ENC[AES256_GCM,data:hjCB,iv:Z1P6/6xBJgJoKLJ0UUVfqZ80o4L84jvZfM+uH9gBelc=,tag:dGqQlCZnLdRAGoJSj63rBQ==,type:int]
...

envs/production/secrets.yaml

secrets:
    elastic:
        password: ENC[AES256_GCM,data:ZB/VpTFk8f0=,iv:EA//oT1Cb5wNFigTDOz3nA80qD9UwTjK5cpUwLnEXjs=,tag:hMdIUaqLRA8zuFBd82bz6A==,type:str]
...

envs/default/values/backend.yaml.gotmpl

elasticsearch:
  host: elasticsearch
  port: 9200
  password: {{ .Values | getOrNil "secrets.elastic.password" | default "password" }}

envs/devel/values/backend.yaml

elasticsearch:
  host: elastic-0.devel.domain

envs/production/values/backend.yaml

elasticsearch:
  host: elastic-0.production.domain

αž€αŸ†αžŽαžαŸ‹αžŸαŸ†αž‚αžΆαž›αŸ‹

αžŠαŸ„αž™αžœαž·αž’αžΈαž“αŸαŸ‡, getOrNil - αž˜αž»αžαž„αžΆαžšαž–αž·αžŸαŸαžŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹ go templates αž“αŸ…αž€αŸ’αž“αž»αž„ Helmfile αžŠαŸ‚αž›αž‘αŸ„αŸ‡αž”αžΈαž‡αžΆ .Values.secrets αž“αžΉαž„αž˜αž·αž“αž˜αžΆαž“, αž“αžΉαž„αž˜αž·αž“αž”αŸ„αŸ‡αž€αŸ†αž αž»αžŸαž˜αž½αž™, αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž“αžΉαž„αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž›αž‘αŸ’αž’αž•αž›αžŠαŸ„αž™αž”αŸ’αžšαžΎαž˜αž»αžαž„αžΆαžš default αž‡αŸ†αž“αž½αžŸαžαž˜αŸ’αž›αŸƒαž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜

αžŸαŸαž…αž€αŸ’αžαžΈαžŸαž“αŸ’αž“αž·αžŠαŸ’αž‹αžΆαž“

αž’αŸ’αžœαžΈβ€‹αžŠαŸ‚αž›β€‹αž”αžΆαž“β€‹αž–αž·αž–αžŽαŸŒαž“αžΆβ€‹αž αžΆαž€αŸ‹β€‹αžŠαžΌαž…β€‹αž‡αžΆβ€‹αž…αŸ’αž”αžΆαžŸαŸ‹β€‹αžŽαžΆαžŸαŸ‹ αž”αŸ‰αž»αž“αŸ’αžαŸ‚β€‹αž–αŸαžαŸŒαž˜αžΆαž“β€‹αž’αŸ†αž–αžΈβ€‹αž€αžΆαžšβ€‹αž–αž·αž–αžŽαŸŒαž“αžΆβ€‹αž„αžΆαž™αžŸαŸ’αžšαž½αž›β€‹αž“αŸƒβ€‹αž€αžΆαžšβ€‹αžŠαžΆαž€αŸ‹β€‹αž–αž„αŸ’αžšαžΆαž™β€‹αž‘αŸ…β€‹αž“αžΉαž„β€‹αž”αžšαž·αžŸαŸ’αžαžΆαž“β€‹αž˜αž½αž™β€‹αž…αŸ†αž“αž½αž“β€‹αžŠαŸ„αž™β€‹αž”αŸ’αžšαžΎ helmfile αž‚αžΊβ€‹αž€αž˜αŸ’αžšβ€‹αžŽαžΆαžŸαŸ‹ αž αžΎαž™β€‹αžαŸ’αž‰αž»αŸ†β€‹αžŸαŸ’αžšαž‘αžΆαž‰αŸ‹ IaC (Infrastructure-as-Code) αž αžΎαž™β€‹αž…αž„αŸ‹β€‹αž˜αžΆαž“β€‹αž€αžΆαžšβ€‹αž–αž·αž–αžŽαŸŒαž“αžΆβ€‹αž…αŸ’αž”αžΆαžŸαŸ‹β€‹αž›αžΆαžŸαŸ‹β€‹αž’αŸ†αž–αžΈβ€‹αžŸαŸ’αžαžΆαž“αž—αžΆαž–β€‹αžŠαžΆαž€αŸ‹β€‹αž–αž„αŸ’αžšαžΆαž™αŸ”

αžŸαžšαž»αž”αžŸαŸαž…αž€αŸ’αžαžΈαž˜αž€ αžαŸ’αž‰αž»αŸ†αž…αž„αŸ‹αž”αž“αŸ’αžαŸ‚αž˜αžαžΆαž’αžαŸαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž”αžšαž·αžŸαŸ’αžαžΆαž“αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αžŠαŸ„αž™αž’αžαŸαžšαž”αžšαž·αžŸαŸ’αžαžΆαž“αž“αŸƒ OS αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžšαžαŸ‹αž‡αžΆαž€αŸ‹αž›αžΆαž€αŸ‹αžŠαŸ‚αž›αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αž“αžΉαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŠαžΆαž€αŸ‹αž±αŸ’αž™αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš αž αžΎαž™αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž‘αž‘αž½αž›αž”αžΆαž“αž”αžšαž·αžŸαŸ’αžαžΆαž“αžαžΆαž˜αžœαž“αŸ’αžαŸ”

helmfile.yaml

environments:
  default:
    values:
    - global:
        clusterDomain: {{ env "CLUSTER_DOMAIN" | default "cluster.local" }}
        ingressDomain: {{ env "INGRESS_DOMAIN" }}

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹