I have a terraform code as given below
locals {
file_path = format("%s-%s", var.test1, var.test2)
test_decode = yamldecode((data.github_repository_file.test.content))
}
data "github_repository_file" "test" {
repository = "test-repo"
branch = "develop"
file = "${local.file_path}/local/test.yaml"
}
test_encode = ${yamlencode(local.test_decode.spec.names)}
This is working fine when a ".spec.names" attribute present in the test.yaml file. Since we are selecting the test.yaml based on local.file_path some times attribute .spec.names might not present in the test.yaml and the plan failing with "Error: Unsupported attribute". How to check ".spec.names" attribute present in the test.yaml?
Updating the question to add yaml example
Yaml with names attribute
apiVersion: helm.toolkit.gitops.io/v2beta1
kind: HelmRelease
metadata:
name: "test"
namespace: "test-system"
spec:
chart:
spec:
chart: "test-environment"
version: "0.1.10"
names:
key1: "value1"
key2: "value2"
key3: "value3"
key4: "value4"
YAML without names attribute
apiVersion: helm.toolkit.gitops.io/v2beta1
kind: HelmRelease
metadata:
name: "test"
namespace: "test-system"
spec:
chart:
spec:
chart: "test-environment"
version: "0.1.10"
You can use try:
test_encode = yamlencode(try(local.test_decode.spec.names, "some_default_value"))
I don't know if a more elegant way exists, but you can check if a property exists like this:
contains([for k, v in local.test_decode : k], "spec")
chaining this to check if the spec and the names exists like this did not work for me as the second condition was still evaluated even if the first condition failed:
contains([for k, v in local.test_decode : k], "spec") && contains([for k, v in local.test_decode.spec : k], "names")
this does the trick, but I don't like it, because I consider it to be quite hacky:
contains([for k, v in local.test_decode : k], "spec") ? contains([for k, v in local.test_decode.spec : k], "names") : false
Related
I have the following code in groovy:
void call(Closure closure) {
pod_template_maven_image = ...
pod_template_maven_m2 = ...
pod_template_nodejs_image = ...
pod_template_sonar_image = ...
toleration_condition = true
def yaml_config = ""
if(toleration_condition){
yaml_config = """
spec:
tolerations:
- key: "my_toleration"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
"""
}
podTemplate(containers: ...,
volumes: ...,
etc...,
yaml: yaml_config,
yamlMergeStrategy: merge()) {
node(POD_LABEL) {
closure()
}
}
}
At the moment, when I run the job in jenking nothing happens, the pod is created whitout error. But the yaml is not added in pod.
We want to add the toleration (yaml_config) in podTemplate depending of toleration_condition value.
I'm new in this area and don't now if is possible.
Its is? Whats the best way to do it?
Thanks.
Tip: I see you use the Kubernetes plugin. Have you seen the section of inheritance? Using the declarative pipeline syntax, with inheritFrom, might provide a much cleaner way to achieve the wanted results. Here we also keep the yamlMergeStrategy as default (override()).
I have seen that the indents of the "delta yaml" (yaml_config), provided to yaml:, influences the final outcome (trailing and starting newlines could also have impact). So I would recommend testing with a yaml_config like:
yaml_config = """
spec:
tolerations:
- key: "my_toleration"
operator: "Equal"
value: "value1"
effect: "NoSchedule" """
I'm using vault approle auth method to fetch secrets from vault. Below is my vault agent configmap.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
config-init.hcl: |
"auto_auth" = {
"method" = {
"config" = {
"role" = "test"
"role_id_file_path" = "roleid"
"secret_id_file_path" = "secretid"
"remove_secret_id_file_after_reading" = false
}
"type" = "approle"
}
"sink" = {
"config" = {
"path" = "/home/vault/.token"
}
"type" = "file"
"wrap_ttl" = "30m"
}
}
"vault" = {
"address" = "https://myvault.com"
}
"exit_after_auth" = true
"pid_file" = "/home/vault/.pid"
Then I'm referencing the above configmap in the deployment file.
annotations:
vault.hashicorp.com/agent-inject: 'true'
vault.hashicorp.com/agent-configmap: 'my-configmap'
But I get below error
vault-agent-init 2022-07-20T10:43:13.306Z [ERROR] auth.handler: error getting path or data from method: error="no known role ID" backoff=4m51.03s
Create a secret file in Kubernetes by using the RoleID and SecretID and pass the below annotation
vault.hashicorp.com/extra-secret: "secret-file"
Assume I know the following secret parameters:
"name": "aaa",
"docker-server": "a.b.com",
"docker-username": "aaa",
"docker-password": "aaaa",
"docker-email": "aaa#gmail.com"
Then I want to use client-go to create a pull-image secret
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "pull-image-secret",
Namespace: "aaaaaa",
},
Type: "kubernetes.io/dockerconfigjson",
Data: map[string][]byte{".dockerconfigjson": []byte(secretData)},
}
err = k8sClient.Create(context.Background(), secret)
My question is, how to convert secret parameters into secretData?
From docs:
the data field of the Secret object must contain a .dockerconfigjson key, in which the content for the ~/.docker/config.json file is provided as a base64 encoded string
So if you want to use Data field you need to modify code to base64 encode secret data, something like that should work:
import b64 "encoding/base64"
...
base64EncodedData := make([]byte, b64.StdEncoding.EncodedLen(len(secretData)))
b64.StdEncoding.Encode(base64EncodedData, []byte(secretData))
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "pull-image-secret",
Namespace: "aaaaaa",
},
Type: "kubernetes.io/dockerconfigjson",
Data: map[string][]byte{".dockerconfigjson": base64EncodedData},
}
Otherwise, you can try to use StringData field without base64 encoding:
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "pull-image-secret",
Namespace: "aaaaaa",
},
Type: "kubernetes.io/dockerconfigjson",
StringData: map[string]string{".dockerconfigjson": secretData},
}
I've declared a kubernetes secret in pulumi like:
const tlsSecret = new k8s.core.v1.Secret('tlsSecret', {
metadata: {
name: 'star.builds.qwil.co'
},
data: {
'tls.crt': tlsCert,
'tls.key': tlsKey
}
});
However, I'm finding that when the secret is created only tls.key is present in the secret. When I look at the Diff View from the pulumi deployment on app.pulumi.com I see the following:
tlsSecret (kubernetes:core:Secret)
+ kubernetes:core/v1:Secret (create)
[urn=urn:pulumi:local::ledger::kubernetes:core/v1:Secret::tlsSecret]
apiVersion: "v1"
data : {
tls.key: "[secret]"
}
kind : "Secret"
metadata : {
labels: {
app.kubernetes.io/managed-by: "pulumi"
}
name : "star.builds.qwil.co"
}
Why is only tls.key being picked up even though I've also specified a tls.crt?
Turns out the variable tlsCert was false-y (I was loading it from config with the wrong key for Config.get()). Pulumi was smart and didn't create a secret with an empty string.
I want to choose config section from values.yaml by setting a variable in helm command line.
example part of values.yaml:
aaa:
x1: "az1"
x2: "az2"
bbb:
x1: "bz1"
x2: "bz2"
example part of configmap.yaml
data:
{{ .Values.outsideVal.x1 }}
Expected result should looks like this
data:
az1
Test helm output
helm template --set outsideVal=aaa mychart
And got this error
Error: render error in "./templates/configmap.yaml": template: ./templates/configmap.yaml:21:12: executing "./templates/configmap.yaml" at <.Values.outsideVal.x...>: can't evaluate field x1 in type interface {}
So the question is how get the result as expected?
I suspect you're looking for the text/template index function, which can look up a value in a map by a variable key.
{{ (index .Values .Values.outsideVal).x1 }}