roboll / helmfile

Deploy Kubernetes Helm Charts
MIT License
4.03k stars 567 forks source link

environment values file matching does not exist #2135

Closed tomassatka closed 2 years ago

tomassatka commented 2 years ago

helmfile version v0.144.0

When i refer values file release.yaml from environments.yaml file i get error that file could not be found: err: failed to read helmfile\bases\environments.yaml: environment values file matching "../../environments/ocp3/dev/release.yaml" does not exist in "."

No matter where i place the file, even if that is next to environments.yaml i get the same error.

My goal is to read the versions of all charts from external file that can be modified later by PRs.

  1. Any idea what do i do wrong that i get the error or any suggestion on how to achieve the goal?
  2. Could the release.yaml be iterated by range in combination with template to populate labels and potential values enabling additional subcharts to be installed?

i have following structure:

C:.
│   helmfile.yaml
│
└───helmfile
    ├───bases
    │       environments.yaml
    │       helmDefaults.yaml
    │
    ├───environments
    │   └───ocp3
    │       └───dev
    │               release.yaml
    │
    └───releases
        └───services
                helmfile.yaml
                issues.values.yaml.gotmpl
                jira-metrics.values.yaml.gotmpl

root helmfile.yaml:

bases:
  - "helmfile/bases/helmDefaults.yaml"
  - "helmfile/bases/environments.yaml"

helmfiles:
  - "helmfile/releases/services/helmfile.yaml"

missingFileHandler: Error

helmfile in services dir:

---
bases:
  - "../../bases/helmDefaults.yaml"
  - "../../bases/environments.yaml"

---
repositories:
  - name: foo
    url: {{ .Values | getOrNil "bitnami_helm_repo_url" }}

templates:
  common: &common
    namespace: {{ required "Namespace is required" .Values | getOrNil "namespace" }}
    chart: foo/{{`{{ .Release.Name }}`}}
    values:
      - "{{`{{ .Release.Name }}`}}.values.yaml.gotmpl"

releases:
  - name: jira-metrics
    <<: *common
    version: {{ .Environment.Values | get "jira-metrics.version" }}
    labels:
      tier: app
      domain: services

  - name: issues
    <<: *common
    version: {{ .Environment.Values | get "issues.version" }}
    labels:
      tier: app
      domain: services
    values: 
      - something.enabled: true

environments.yaml:

---
# !!IMPORTANT!!
# All false boolean values should be quoted due to https://github.com/helm/helm/issues/3308
# Because of YAML merging, all true boolean values should be quoted as well
environments:

  default:
    values:
      - strimzi:
          installed: "false"
        microcks:
          installed: "false"
        bitnami_helm_repo_url: https://charts.bitnami.com/bitnami

  # This is a dummy environment used for base values that can
  # be merged into other environments.
  __base:
    values:
      # These services are only installed in the
      # regional cluster, so we disable them for
      # all zonal clusters, regardless of the environment.
      - &artifactory_helm_repos
        bitnami_helm_repo_url: https://artifactory.net/artifactory/foo-helm-release-virtual
      - &aks_helm_repos
        bitnami_helm_repo_url: https://artifactory.net/artifactory/foo-helm-release-virtual

  #### Begin environments #####
  ocp4:
    values:
      - <<: *artifactory_helm_repos
      - microcks:
          installed: "true"
  ocp3-dev:
    values:
      - ../../environments/ocp3/dev/release.yaml
      - namespace: foo-dev
      - <<: *artifactory_helm_repos
      - microcks:
          installed: "false"
  ocp3-int:
    values:
      - namespace: foo-int
      - <<: *artifactory_helm_repos
      - microcks:
          installed: "false"

content of release.yaml:

jira-metrics:
  version: 0.1.0

issues:
  version: 0.1.0
mumoshu commented 2 years ago

@tomassatka Hey. Are you're on Windows? We don't have CI for Windows so not sure how it behaves there. At glance, the problem seems like coming from the fact that you're using / as the path separator whereas in Windows you should use \

tomassatka commented 2 years ago

Hi @mumoshu I found the rootcause of the issue. It is not related to OS. Providing git repo to showcase the issue: https://github.com/tomassatka/helmfile-2135

In repo is non-working and working dir where i applied ugly fix.

Would like to describe the nature of the problem.

In the project i defined root helmfile that uses bases pointing to environments.yaml and pointing to nested helmfile:

bases:
  - "helmfile/bases/helmDefaults.yaml"
  - "helmfile/bases/environments.yaml"

helmfiles:
  - "helmfile/releases/services/helmfile.yaml"

missingFileHandler: Error

now the nested helmfile.yaml also uses bases:

---
bases:
  - "../../bases/helmDefaults.yaml"
  - "../../bases/environments.yaml"

Thats intentional that the environment is defined only in 1 file and all files refer to it. The problem is then when helmfile goes over rendering different helmfiles.. the path is relative to helmfile not to environments therefore the path for release.yaml is relative to 2 different helmfile in 2 different directories hence for one of them it wont be able to find the release and prints the error.

Now the ugly solution is to write environemnts section into each helmfile but that causes a duplication and potential issues. Do you have any other suggestion? :)

thx

mumoshu commented 2 years ago

@tomassatka Hey. Ah, that makes sense. Each helmfile and sub-helmfile evaluates relative paths based on the paths of helmfile.yaml files, whereas paths in a base file is evaluated based on the path of the helmfile loading it. I thought I made that design choice to make base.yaml useful for sharing the structure of the helmfile.yaml.

In your case, why do you need to define the whole environments in the top-level helmfile.yaml? To me, the only thing you need in the top-level helmfile.yaml is a list of environments names without their values, and the helmfiles section to call individual sub-helmfiles with their own environments sections.

Can't you make the root helmfile.yaml look like the below? So that the only thing you need to repeat is the names of environments. Every service helmfile.yaml can share the same base file that is specifically tailored for service helmfiles.

environments:
  default:
  dev:
  int:

helmfiles:
  - "helmfile/releases/services/helmfile.yaml"
tomassatka commented 2 years ago

hi @mumoshu Thanks for proposal. Yes that is an acceptable solution. I was not aware that the path is always relative to helmfile that is being executed. This gives me a thought if in future will be useful to have variable like maven has ${basedir}.

tomassatka commented 2 years ago

hi @mumoshu Thanks for proposal. Yes that is an acceptable solution. I was not aware that the path is always relative to helmfile that is being executed. This gives me a thought if in future will be useful to have variable like maven has ${basedir}.