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!
@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 ?