Yaml with vertical line to yamlencode

Hello! I try yamlencode

---
controller:
  componentName: "jenkins-controller"
  image: "jenkins/jenkins"
  tag: "2.346.2-jdk11"
  imagePullPolicy: "IfNotPresent"
  numExecutors: 1

  additionalPlugins:
    - google-login:1.6

  JCasC:
    securityRealm: |-
      googleOAuth2:
        clientId: "xxx-xxx.apps.googleusercontent.com"
        clientSecret: "xxx-xxx"
        domain: ""
    authorizationStrategy: |-
      loggedInUsersCanDoAnything:
        allowAnonymousRead: false

  ingress:
    enabled: true
    ingressClassName: nginx
    paths: []
    apiVersion: networking.k8s.io/v1
    annotations:
      cert-manager.io/cluster-issuer: "letsencrypt-prod"
    tls:
      - secretName: jenkins-tls

My example

    yamlencode({
      controller = {
        componentName     = "jenkins-controller"
        image             = "jenkins/jenkins"
        tag               = "2.346.2-jdk11"
        imagePullPolicy   = "IfNotPresent"
        numExecutors      = 1
        additionalPlugins = ["google-login:1.6"]

        JCasC = {
          "securityRealm" = join("\n", [
            "googleOAuth2:",
          ])
        }
      }

    })

How correct yaml with vertical line to yamlencode ?

When you’re looking to create nested YAML documents, the way to do it is nested yamlencode() calls:

      JCasC = {
        securityRealm = yamlencode({
          googleOAuth2 = {
            clientId     = "xxx-xxx.apps.googleusercontent.com"
            clientSecret = "xxx-xxx"
            domain       = ""
          }
        })

        authorizationStrategy = yamlencode({
          loggedInUsersCanDoAnything = {
            allowAnonymousRead = false
          }
        })
      }

Hi @patsevanton,

The example you’ve shared here includes a document marker, which is part of the YAML syntax for encoding a series of documents into a stream, and can separately be used to avoid some ambiguity that might otherwise arise if a single document contains Directives.

Terraform’s yamlencode function can only produce Bare Documents, because its input is a single data structure which corresponds with a single document in YAML’s terms. yamlencode also never generates YAML Directives, and so there is no risk of the syntax ambiguity that can arise in a single document with directives.

Before getting into ways you might create the effect of multiple documents even though Terraform’s function isn’t designed for that, I want to note that if the system you are sending this message to only requires a single document anyway then it may work to just send the yamlencode function’s output directly, even though it doesn’t include a document marker. The YAML specification does not describe any difference in result for a bare document vs. single Explicit Document, and so lots of YAML-parsing software will accept a single document in both forms.

If you find that the software you’re sending this message to does require an single explicit document, or if you need to generate a YAML Stream containing multiple explicit documents, Terraform does not have any YAML-specific mechanism for doing so but you can get the effect of doing so by inserting the --- sequence explicitly yourself using template syntax. For example:

  yaml_stream = "---\n${yamlencode({
    controller = {
      # ...
    }
  })}"

Thanks!

I found command for transfer yaml code to terraform code

echo 'yamldecode(file("jenkins-values-google-login.yaml"))' | terraform console

My code:


locals {
  jenkins_values_google_login = {
    "controller" = {
      "JCasC" = {
        "authorizationStrategy" = <<-EOT
        loggedInUsersCanDoAnything:
          allowAnonymousRead: false
        EOT
        "configScripts" = {
          "freestyle-jobs" = <<-EOT
          jobs:
            - script: >
                job('ff') {
                  steps {
                    shell('echo $ENV;ls -l')
                  }
                }
            - script: >
                job('gg') {
                  steps {
                    shell('echo $PWD;ls -l')
                  }
                }
          
          EOT
          "jenkins-configuration" = <<-EOT
          jenkins:
            systemMessage: This Jenkins is configured and managed 'as code' by Managed Cloud team.
          
          EOT
        }
        "securityRealm" = <<-EOT
        googleOAuth2:
          clientId: "${var.clientId}"
          clientSecret: "${var.clientSecret}"
          domain: "${var.google_domain}"
        EOT
      }
      "additionalPlugins" = [
        "google-login:1.6",
        "job-dsl:1.81",
        "allure-jenkins-plugin:2.30.2",
      ]
      "imagePullPolicy" = "IfNotPresent"
      "ingress" = {
        "annotations" = {
          "cert-manager.io/cluster-issuer" = "letsencrypt-prod"
        }
        "apiVersion" = "networking.k8s.io/v1"
        "enabled" = true
        "hostName" = "${var.jenkins_dns_name}"
        "ingressClassName" = "nginx"
        "tls" = [
          {
            "hosts" = [
              "${var.jenkins_dns_name}",
            ]
            "secretName" = "jenkins-tls"
          },
        ]
      }
      "numExecutors" = 1
      "tag" = "${var.jenkins_version}"
    }
  }
}

resource "helm_release" "jenkins" {
  namespace  = "jenkins"
  create_namespace = true
  name       = "jenkins"
  repository = "https://charts.jenkins.io"
  chart      = "jenkins"
  wait       = true
  version    = "4.1.17"
  depends_on = [
    yandex_kubernetes_node_group.k8s_node_group
  ]
  values = [
    #file("${path.module}/jenkins-values-google-login.yaml")
    yamlencode(local.jenkins_values_google_login) 
  ]
}