flux2 icon indicating copy to clipboard operation
flux2 copied to clipboard

Integer can not be used in postBuild.substitute variables

Open ruzickap opened this issue 3 years ago • 6 comments

Describe the bug

I would like to us "integer value" for postBuild.substitute variables, but I'm getting the error:

Invalid value: "integer": spec.postBuild.substitute.AWS_ACCOUNT_ID in body must be of type string: "integer"

Steps to reproduce

This is the example of the kustomize.toolkit.fluxcd.io/v1beta1 which is producing the error:

apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
  name: testbase
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: "./apps/${ENVIRONMENT}/base/crossplane"
  prune: true
  validation: client
  postBuild:
    substitute:
      AWS_ACCOUNT_ID: 71111111117

Error:

$ kubectl get kustomizations.kustomize.toolkit.fluxcd.io -A
NAMESPACE     NAME                  READY   STATUS                                                              AGE
flux-system   apps-helmrepository   True    Applied revision: master/2f2f2922db0666f22fa607c2f82f42b50821c559   2m34s
flux-system   flux-system           False   apply failed: The Kustomization "testbase" is invalid: spec.postBuild.substitute.AWS_ACCOUNT_ID: Invalid value: "integer": spec.postBuild.substitute.AWS_ACCOUNT_ID in body must be of type string: "integer"

Expected behavior

Integer values should be allowed in postBuild.substitute variables.

Screenshots and recordings

No response

OS / Distro

MacOS

Flux version

0.17.1

Flux check

► checking prerequisites ✔ kubectl 1.21.1 >=1.18.0-0 ✔ Kubernetes 1.21.2-eks-0389ca3 >=1.16.0-0 ► checking controllers ✔ helm-controller: deployment ready ► ghcr.io/fluxcd/helm-controller:v0.11.2 ✔ kustomize-controller: deployment ready ► ghcr.io/fluxcd/kustomize-controller:v0.14.1 ✔ notification-controller: deployment ready ► ghcr.io/fluxcd/notification-controller:v0.16.0 ✔ source-controller: deployment ready ► ghcr.io/fluxcd/source-controller:v0.15.4 ✔ all checks passed

Git provider

No response

Container Registry provider

No response

Additional context

No response

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct

ruzickap avatar Sep 18 '21 07:09 ruzickap

Even if it's a string, you can still use the value unquoted elsewhere

terrafying avatar Sep 21 '21 13:09 terrafying

Everything must be a string in the Flux Kustomization, if that's what error you got, as Kubernetes APIs which require a string input will not accept boolean or integer types, Flux Kustomization also requires a stringly typed value. I am not certain if this is strictly uniform across all K8s APIs, surely some params are not strings (like replicas, an int), but at least annotations are required to carry only a string type value.

Unfortunately it gets worse. Even if you quote the integer value here, there is a slight chance it can still be converted back to an integer later anyway? Before you read any further, just try quoting the value here, and see if it still causes an error or not. Hopefully no...

But, there is a chance that since the value is actually an integer, that you will also need to ensure it is properly quoted at the point of substitution. As I mentioned above, Kubernetes Annotation values must be represented in a format which remains compatible with the go struct map[string]string and it's plain to see that integers are not strings.

  ...
    example-annotation/account-id: "\"${AWS_ACCOUNT_ID}\""

I hate to add documentation around this because to me, it looks like something that should be fixed, and I remain hopeful that it can be fixed, but for additional context, please refer to this discussion: https://github.com/fluxcd/flux2/discussions/1795

Perhaps we should also add this to the docs somewhere? Thank you for your report, at the very least it also helps us to raise the visibility of this issue.

kingdonb avatar Sep 21 '21 14:09 kingdonb

Thank you...

This helped :-)

ruzickap avatar Sep 21 '21 19:09 ruzickap

This workaround no longer functions in the latest versions of Flux. @ruzickap did you find a solution that can work today?

kingdonb avatar Jul 01 '22 12:07 kingdonb

Here's the horrible hack we're using in production, since the above workaround is broken and we cannot figure out how to force an AWS_ACCOUNT_ID to be a string:

In the HelmRelease: account_id: " ${account_id} " (note spaces inside quotes) In the chart itself: value: {{ .Values.account_id | trim | quote }} (spaces trimmed out)

rmartine-ias avatar Apr 11 '23 00:04 rmartine-ias

Does anyone know why the substitution step is "eating" the quotes? For example:

apiVersion: helm.toolkit.fluxcd.io/v2beta1                                                                                                                                                                                                                                                                                    
kind: HelmRelease 
...
values:
   target_account: "${ACCOUNT_ID}"

I would expect it to render like:

apiVersion: helm.toolkit.fluxcd.io/v2beta1                                                                                                                                                                                                                                                                                    
kind: HelmRelease 
...
values:
   target_account: "12345"

But instead it renders like:

apiVersion: helm.toolkit.fluxcd.io/v2beta1                                                                                                                                                                                                                                                                                    
kind: HelmRelease 
...
values:
   target_account: 12345

From this point forward it makes sense that it is interpreted as an integer, so it is the removal of the quotes during the substitution phase that seems to be the issue. So the issue appears to be somewhere in

https://github.com/fluxcd/pkg/blob/9f8701a7ae598e69047e00b323d5106863c02d5e/kustomize/kustomize_varsub.go#L55-L108

Edit:

I suspect the issue is in the "round-trip" of the YAML in https://github.com/kubernetes-sigs/kustomize/blob/master/api/resource/resource.go#L366-L372. The "unsubstituted value" (ie the literal ${ACCOUNT_ID}) is a string, so when generating the YAML that SubstituteVariables() processes, the quote has been stripped out (because it is not required). The non-quoted YAML is then replaced with a value that is now an integer, and there is where the type confusion occurs.

Edit 2:

I think it is the same issue as https://github.com/kubernetes-sigs/kustomize/issues/4845

logan-hcg avatar Nov 27 '23 01:11 logan-hcg