Helmfile: In a helmfile, how do I load .Environment.Values from a base file.

Created on 24 Oct 2019  ·  4Comments  ·  Source: roboll/helmfile

I am having troubles keeping my helmfiles DRY using the bases property, and
am sure I'm misunderstanding something.

I have a helmfile project with following directory structure.

.
├── environments.yaml
├── helmfile.yaml
└── helmfiles
    ├── 00.cluster-utils.yaml
    └── 01.api-server.yaml

My top-level helmfile.yaml simply defines the sub-helmfiles, which need AWS
configuration, loaded from environment variables.

# helmfile.yaml
helmfiles:
  - helmfiles/00.cluster-utils.yaml
  - helmfiles/01.api-server.yaml

My helmfiles/00.cluster-utils.yaml uses the environments.yaml

# 00.cluster-utils.yaml
helmDefaults:
  wait: true

bases:
  - ../environments.yaml

releases:
  - chart: stable/external-dns
    name: external-dns
    namespace: kube-system
    values:
      - aws:
          accessKey: {{ .Environment.Values.aws.client.access_key_id }}
          secretKey: {{ .Environment.Values.aws.client.secret_access_key }}
          region:    {{ .Environment.Values.aws.client.region }}
        rbac:
          create: true
    # ... remainder of release configuration using values defined in `environments.yaml` base

My environments.yaml base defines the default environment configuration in
terms of environment variables.

# environments.yaml
environments:
  default:
    values:
    - aws:
      account_id: {{ requiredEnv "AWS_ACCOUNT_ID" }}
      client:
        region: {{ requiredEnv "AWS_REGION" }}
        access_key_id: {{ requiredEnv "AWS_ACCESS_KEY_ID" }}
        secret_access_key: {{ requiredEnv "AWS_SECRET_ACCESS_KEY" }}
    # ... more configuration

When I run helmfile diff I get the following error:

$ helmfile diff
in ./helmfile.yaml: in .helmfiles[0]: in helmfiles/00.cluster-utils.yaml: error during 00.cluster-utils.yaml.part.0 parsing: template: stringTemplate:34:44: executing "stringTemplate" at <.Environment.Values.aws.client.access_key_id>: map has no entry for key "aws"

I'm sure this must be user error on my part. What am I missing here? Is this the correct approach to defining shared .Environment.values that can be used in multiple helmfiles?

Many thanks in advance!

question

All 4 comments

@mojochao Hey! Thanks for using Helmfile.

Unfortunately, what you're trying to seems to be impossible in a straight-forward manner.

The reason is that in order to evaluate go tmpl expressions like {{ .Environment.Values.aws.client.access_key_id }} in helmfiles/00.cluster-utils.yaml, you need to load ../environments.yaml, which requires the go tmpl expressions to be already rendered. This is a kind of chicken-and-egg problem.

There's a feature called "double rendering" to make it mostly work, but not always.

The workaround can be to use release templates instead.

That is, try escaping the tmpl expressions with:

{{` ... `}}

So that your config looks like:

    values:
      - aws:
          accessKey: {{`{{ .Environment.Values.aws.client.access_key_id }}`}}
          secretKey: {{`{{ .Environment.Values.aws.client.secret_access_key }}`}}
          region:    {{`{{ .Environment.Values.aws.client.region }}`}}

This way, Helmfile would "defer" rendering those expressions at the time of processing each release, which would fix the issue.

I ran into similar issues. I ended up dropping bases and passing in the environment to the sub helmfiles like below.

# helmfile.yaml

helmfiles:
  - path: helmfiles/00.cluster-utils.yaml
    values:
      - {{ toYaml .Environment.Values | nindent 8 }}
  - path: helmfiles/01.api-server.yaml
    values:
      - {{ toYaml .Environment.Values | nindent 8 }}

Thanks to you both! @tiagomeireles, I ended up using your approach and it worked like a charm. Much appreciated. Closing this ticket now.

@mumoshu @tiagomeireles @mojochao sorry to comment on the closed issue , but May I please ask if anyone can confirm me if I can use the {{` ... `}} with if else conditionals too ?

Was this page helpful?
0 / 5 - 0 ratings