Running SonarCloud scanning of Helm .yaml files in an Azure DevOps .yaml pipeline
I’m seeing errors on several of the .yaml files. The actual error simply says: “Template evaluation failed”
Turning on verbose logging gives more detail, but confusingly the extra detail is referencing a different .yaml file!
The ‘other’ .yaml file gives the following (DEBUG) messages just before and after the ERROR message occurs in the logs.
The extra DEBUG messages mention this other .yaml file. No extra detail is provided about the file that actually errored!!
DEBUG: [sonar-helm-for-iac] Failed to read input: error reading content: strconv.Atoi: parsing "<other .yaml file>": invalid syntax
DEBUG: [sonar-helm-for-iac] Writing 110 bytes to stdout
**ERROR: Failed to evaluate Helm file Docker/helm/enterprise/templates/Config/<erroring .yaml file>: Template evaluation failed**
DEBUG: The pipe has been ended
DEBUG: org.sonar.iac.common.extension.ParseException: Failed to evaluate Helm file Docker/helm/enterprise/templates/Config/<erroring .yaml file>: Template evaluation failed
Any help that can get us to the point where our Helm .yaml files can be scanned without errors would be greatly appreciated!
More complete logs providing full context and call stack:
2024-04-17T18:01:09.8145357Z 18:01:09.813 DEBUG: Helm content detected in file 'Docker/helm/enterprise/templates/Config/serv-web-config.yaml'
2024-04-17T18:01:09.8195182Z 18:01:09.819 DEBUG: Executing: [C:\a\1\s\.scannerwork\.sonartmp\9999754383023744101\sonar-helm-for-iac-windows-amd64]
2024-04-17T18:01:09.8632895Z 18:01:09.862 DEBUG: [sonar-helm-for-iac] Reading 48 lines of file templates/Config/serv-web-config.yaml from stdin
2024-04-17T18:01:09.8633435Z 18:01:09.862 DEBUG: [sonar-helm-for-iac] Reading 69 lines of file templates/Deployment/serv-app-deployment.yaml from stdin
2024-04-17T18:01:09.8634192Z 18:01:09.862 DEBUG: [sonar-helm-for-iac] Failed to read input: error reading content: strconv.Atoi: parsing "templates/Deployment/serv-web-deployment.yaml": invalid syntax
2024-04-17T18:01:09.8635619Z 18:01:09.862 DEBUG: [sonar-helm-for-iac] Writing 110 bytes to stdout
2024-04-17T18:01:09.8693220Z ##[error]18:01:09.864 ERROR: Failed to evaluate Helm file Docker/helm/enterprise/templates/Config/serv-web-config.yaml: Template evaluation failed
2024-04-17T18:01:09.8694390Z 18:01:09.864 ERROR: Failed to evaluate Helm file Docker/helm/enterprise/templates/Config/serv-web-config.yaml: Template evaluation failed
2024-04-17T18:01:09.8694695Z 18:01:09.864 DEBUG: The pipe has been ended
2024-04-17T18:01:09.8695936Z 18:01:09.864 DEBUG: org.sonar.iac.common.extension.ParseException: Failed to evaluate Helm file Docker/helm/enterprise/templates/Config/serv-web-config.yaml: Template evaluation failed
2024-04-17T18:01:09.8696715Z at org.sonar.iac.kubernetes.plugin.HelmProcessor.parseExceptionFor(HelmProcessor.java:143)
2024-04-17T18:01:09.8697360Z at org.sonar.iac.kubernetes.plugin.HelmProcessor.evaluateHelmTemplate(HelmProcessor.java:138)
2024-04-17T18:01:09.8697617Z at org.sonar.iac.kubernetes.plugin.HelmProcessor.processHelmTemplate(HelmProcessor.java:95)
2024-04-17T18:01:09.8698154Z at org.sonar.iac.kubernetes.plugin.HelmProcessor.process(HelmProcessor.java:74)
2024-04-17T18:01:09.8698359Z at org.sonar.iac.kubernetes.plugin.KubernetesParser.evaluateAndParseHelmFile(KubernetesParser.java:148)
2024-04-17T18:01:09.8698697Z at org.sonar.iac.kubernetes.plugin.KubernetesParser.parseHelmFile(KubernetesParser.java:84)
2024-04-17T18:01:09.8698898Z at org.sonar.iac.kubernetes.plugin.KubernetesParser.lambda$parse$1(KubernetesParser.java:62)
2024-04-17T18:01:09.8699110Z at org.sonar.iac.kubernetes.plugin.KubernetesParserStatistics.recordHelmFile(KubernetesParserStatistics.java:43)
2024-04-17T18:01:09.8699318Z at org.sonar.iac.kubernetes.plugin.KubernetesParser.parse(KubernetesParser.java:62)
2024-04-17T18:01:09.8699506Z at org.sonar.iac.kubernetes.plugin.KubernetesParser.parse(KubernetesParser.java:38)
2024-04-17T18:01:09.8699699Z at org.sonar.iac.common.extension.IacSensor$Analyzer.lambda$analyseFile$0(IacSensor.java:217)
2024-04-17T18:01:09.8700206Z at org.sonar.iac.common.extension.DurationStatistics.time(DurationStatistics.java:75)
2024-04-17T18:01:09.8700412Z at org.sonar.iac.common.extension.IacSensor$Analyzer.analyseFile(IacSensor.java:215)
2024-04-17T18:01:09.8700606Z at org.sonar.iac.common.extension.IacSensor$Analyzer.analyseFiles(IacSensor.java:192)
2024-04-17T18:01:09.8700792Z at org.sonar.iac.common.extension.IacSensor.execute(IacSensor.java:111)
2024-04-17T18:01:09.8700972Z at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:62)
2024-04-17T18:01:09.8701168Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:75)
2024-04-17T18:01:09.8701374Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:48)
2024-04-17T18:01:09.8701586Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:66)
2024-04-17T18:01:09.8701788Z at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:48)
2024-04-17T18:01:09.8702368Z at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:64)
2024-04-17T18:01:09.8702574Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2024-04-17T18:01:09.8702776Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2024-04-17T18:01:09.8702968Z at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:192)
2024-04-17T18:01:09.8703164Z at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:188)
2024-04-17T18:01:09.8703710Z at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:159)
2024-04-17T18:01:09.8703902Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2024-04-17T18:01:09.8704100Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2024-04-17T18:01:09.8704294Z at org.sonar.scanner.bootstrap.ScannerContainer.doAfterStart(ScannerContainer.java:397)
2024-04-17T18:01:09.8704491Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2024-04-17T18:01:09.8704688Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2024-04-17T18:01:09.8704872Z at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:125)
2024-04-17T18:01:09.8705066Z at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
2024-04-17T18:01:09.8705325Z at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
2024-04-17T18:01:09.8705778Z at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:57)
2024-04-17T18:01:09.8706214Z at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:51)
2024-04-17T18:01:09.8706661Z at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
2024-04-17T18:01:09.8706878Z at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
2024-04-17T18:01:09.8707063Z at java.base/java.lang.reflect.Method.invoke(Method.java:580)
2024-04-17T18:01:09.8707559Z at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
2024-04-17T18:01:09.8707771Z at jdk.proxy1/jdk.proxy1.$Proxy0.execute(Unknown Source)
2024-04-17T18:01:09.8708202Z at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
2024-04-17T18:01:09.8708671Z at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
2024-04-17T18:01:09.8708849Z at org.sonarsource.scanner.cli.Main.execute(Main.java:126)
2024-04-17T18:01:09.8709003Z at org.sonarsource.scanner.cli.Main.execute(Main.java:81)
2024-04-17T18:01:09.8709156Z at org.sonarsource.scanner.cli.Main.main(Main.java:62)
And here is the content of the 2 .yaml files in question:
serv-web-config (the file that is erroring):
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-servicing-app
namespace: default
labels:
app: {{ .Release.Name }}-servicing-app
data:
{{- if .Values.servicingAppIdentifier -}}
IDENTIFIER: {{ .Values.servicing | quote }}
{{ else }}
IDENTIFIER: {{ print .Values.identifierPrefix "_ServicingApp" | quote }}
{{ end -}}
{{- if or .Values.servicingRemotePath .Values.remotePath -}}
{{ if .Values.servicingRemotePath -}}
REMOTE_PATH: {{ .Values.servicingRemotePath | quote }}
{{ else }}
REMOTE_PATH: {{ print .Values.remotePath "\\Servicing" | squote }}
{{ end }}
{{- end }}
CERTIFICATE_FILENAME: {{ coalesce (.Values.certs).appFileName (.Values.certs).filename | quote }}
CERTIFICATE_PASSWORD: {{ coalesce (.Values.certs).appPassword (.Values.certs).password | quote }}
CERTIFICATE_THUMBPRINT: {{ coalesce (.Values.certs).appThumbprint (.Values.certs).thumbprint | quote }}
SERVICING_APP_SERVER_MACHINE_KEY: {{ (.Values.machineKeys).servicingApp | quote }}
DB_ADMIN_USERID: {{ coalesce ((.Values.dbConnections).servicing).adminUserName (.Values.dbConnections).adminUserName | quote }}
DB_ADMIN_PASSWORD: {{ coalesce ((.Values.dbConnections).servicing).adminPassword (.Values.dbConnections).adminPassword | quote }}
{{- if or ((.Values.dbConnections).servicing).saPassword (.Values.dbConnections).saPassword }}
DB_SA_PASSWORD: {{ coalesce ((.Values.dbConnections).servicing).saPassword (.Values.dbConnections).saPassword | quote }}
{{- end }}
{{- if (.Values.dbConnections).aspState }}
ASP_STATE_SERVER: {{ coalesce (((.Values.dbConnections).aspState).servicingApp).server (((.Values.dbConnections).aspState).app).server (((.Values.dbConnections).aspState).servicing).server ((.Values.dbConnections).aspState).server (.Values.dbConnections).dbServer | quote }}
{{- $instance := coalesce (((.Values.dbConnections).aspState).servicingApp).instance (((.Values.dbConnections).aspState).app).instance (((.Values.dbConnections).aspState).servicing).instance ((.Values.dbConnections).aspState).instance }}
{{- if $instance }}
ASP_STATE_INSTANCE: {{ $instance | quote }}
{{- end }}
ASP_STATE_DB_NAME: {{ coalesce (((.Values.dbConnections).aspState).servicingApp).dbName (((.Values.dbConnections).aspState).app).dbName (((.Values.dbConnections).aspState).servicing).dbName ((.Values.dbConnections).aspState).dbName | quote }}
ASP_STATE_USERNAME: {{ coalesce (((.Values.dbConnections).aspState).servicingApp).userName (((.Values.dbConnections).aspState).app).userName (((.Values.dbConnections).aspState).servicing).userName ((.Values.dbConnections).aspState).userName | quote }}
ASP_STATE_PASSWORD: {{ coalesce (((.Values.dbConnections).aspState).servicingApp).password (((.Values.dbConnections).aspState).app).password (((.Values.dbConnections).aspState).servicing).password ((.Values.dbConnections).aspState).password | quote }}
{{- end }}
{{- if and (.Values.dbConnections).seedData (coalesce (((.Values.dbConnections).seedData).servicing).enabled ((.Values.dbConnections).seedData).enabled) }}
SEED_DATA_SERVICING_CONNECTION_STRING: {{ coalesce (((.Values.dbConnections).seedData).servicing).connectionString ((.Values.dbConnections).seedData).connectionString | quote }}
{{- if or (((.Values.dbConnections).seedData).servicing).tag ((.Values.dbConnections).seedData).tag }}
SEED_DATA_SERVICING_TAG: {{ coalesce (((.Values.dbConnections).seedData).servicing).tag ((.Values.dbConnections).seedData).tag | quote }}
{{- end }}
{{- if or (((.Values.dbConnections).seedData).servicing).instanceType ((.Values.dbConnections).seedData).instanceType }}
SEED_DATA_SERVICING_INSTANCE_TYPE: {{ coalesce (((.Values.dbConnections).seedData).servicing).instanceType ((.Values.dbConnections).seedData).instanceType | quote }}
{{- end }}
{{- end -}}
{{- if and .Values.dprEnvVars .Values.dprEnvVars.servicing }}
{{ range $key, $val := .Values.dprEnvVars.servicing }}
VAR_SETTING_{{ $key }}: {{ $val | quote }}
{{- end -}}
{{- end }}
{{- if and .Values.dprEnvVars .Values.dprEnvVars.app }}
{{ range $key, $val := .Values.dprEnvVars.app }}
VAR_SETTING_{{ $key }}: {{ $val | quote }}
{{- end -}}
{{- end }}
{{- if and .Values.dprEnvVars .Values.dprEnvVars.servicingApp }}
{{ range $key, $val := .Values.dprEnvVars.servicingApp }}
VAR_SETTING_{{ $key }}: {{ $val | quote }}
{{- end -}}
{{- end }}
serv-web-deployment (the other file mentioned in the verbose logs):
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Release.Name }}-servicing-web
name: {{ .Release.Name }}-servicing-web
namespace: default
spec:
replicas: {{ coalesce (.Values.replicas).servicingWeb (.Values.replicas).all }}
selector:
matchLabels:
app: {{ .Release.Name }}-servicing-web
template:
metadata:
labels:
app: {{ .Release.Name }}-servicing-web
spec:
securityContext:
windowsOptions:
gmsaCredentialSpecName: aks-gmsa-spec
containers:
- name: {{ .Release.Name }}-servicing-web
{{- if (.Values.image).servicingWebFull }}
image: {{ (.Values.image).servicingWebFull }}
{{ else }}
image: {{ print (.Values.image).repo "/" (.Values.image).name "_servicing-frontend:" (.Values.image).version }}
{{ end -}}
imagePullPolicy: Always
resources:
limits:
memory: "25288Mi"
cpu: "2"
requests:
memory: "2168Mi"
cpu: "1"
envFrom:
- configMapRef:
name: {{ .Release.Name }}-common
optional: false
- configMapRef:
name: {{ .Release.Name }}-servicing-web
optional: false
volumeMounts:
- name: azurefile
mountPath: "Z:"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: appType
operator: In
values:
- {{ .Values.affinity }}
tolerations:
- key: "kubernetes.azure.com/scalesetpriority"
operator: "Equal"
value: "spot"
effect: "NoSchedule"
volumes:
- name: azurefile
csi:
driver: file.csi.azure.com
volumeAttributes:
secretName: dpr-disk-secret # required
shareName: dprshares # required
mountOptions: "dir_mode=0777,file_mode=0777,cache=strict,actimeo=30" # optional
nodeSelector:
kubernetes.io/os: windows