Dynamic Formation YAML Multiline String (Multiple Lines) Blocks (Edited)

I am creating a universal CI/CD pipeline that should use a variable group whose name depends on the pipeline definition’s name. To achieve this, I attempted to set the group name dynamically.

For example:

		
group: $(Pipeline.DefName).Prod

Or another variant using template syntax:

		
group: {{ variables.pipelineDefName }}.Prod

However, neither of these approaches works.

The only method that succeeded was using a parameter:

		
group: ${{ parameters.pipelineID }}.Prod

But it is inconvenient to pass the parameter each time the pipeline is run.

At the same time, my YAML file contains long string blocks for which preserving formatting (line breaks, indentation, etc.) is important. For example, a block like:

		
description: | Line A Line B Line C

Here the literal style preserves the multiple lines and newlines exactly as written—including every newline and keeping the indent intact. Moreover, it is necessary to control both the leading and trailing line breaks (using block chomping operators “|+” or “|-”). This way, you can control the end of the string and maintain overall readability. Such an approach ensures that if the text should not fold into a single paragraph, the YAML parser will interpret the block to indicate exactly how each newline (or even a folded style option, where each newline is replaced by a space character) should behave.

Question:
How can the problem of dynamically forming a variable group name (without explicitly specifying the parameter at every run) be solved, while simultaneously ensuring the correct preservation of multi-line string formatting in YAML?

Atlas Demetriadis

4 months ago

5 answers

123 views

Rating

00
Answer

Answers

Adam Kowalski

5 months ago

Edited

Rating

00

Solution for Dynamically Forming the Variable Group Name (string in yaml over multiple lines)

Here is my perspective on the problem.

Using Predefined Variables of the CI/CD Platform (literal style, block scalar)

In certain systems, such as Azure DevOps, there are predefined variables that contain the pipeline’s name. For example, in Azure DevOps:

		
group: ${{ variables['Build.DefinitionName'] }}.Prod

Why It Works:

Build.DefinitionName is a predefined variable that automatically contains the pipeline definition’s name.

The syntax $${{ ... }} is processed at the YAML compilation stage, enabling dynamic formation of the group name. This method ensures that the proper string value is interpreted and denoted over multiple lines.

Combining with Default Parameters (multi-line strings)

If the predefined variable is insufficient, you can define a parameter with a default value:

		
parameters: - name: pipelineID type: string default: ${{ variables['Build.DefinitionName'] }} variables: - group: ${{ parameters.pipelineID }}.Prod

Why It Works:

The pipelineID parameter automatically takes the value of Build.DefinitionName if it isn’t explicitly provided. This ensures that the YAML interpreter correctly reads the default and denotes the intended string spanning several lines in the configuration.

Multiline YAML Block Formatting (folded style, multiple lines, indentation indicator)

Use block scalar operators to format multiline strings:

		
description: |+ # Preserves all line breaks, including trailing newlines at the end of the string Line A Line B Line C config: |- # Removes the last newline but keeps intermediate newlines intact Line 1 Line 2 script: | # Preserves newlines while trimming unneeded empty lines for the desired format echo "Hello" echo "World"

Why It Works:

The operators |+, |-, and | control how newlines are handled in accordance with the YAML standard. You can also choose a folded style (>) when you want to fold the multiline string into a single line by replacing each newline with a space character. This flexibility helps break a string in yaml while preserving the intended indentation and overall format.

Final Example (long string format with proper break a string in yaml):

		
parameters: - name: env type: string default: ${{ variables['Build.DefinitionName'] }} jobs: - job: Deploy variables: - group: ${{ parameters.env }}.Prod # Dynamic group name automatically parsed and denoted correctly. steps: - script: | echo "Multiline script:" echo "Line 1" echo "Line 2" displayName: "Script Example" - task: Bash@3 inputs: targetType: inline script: | echo "Configuration:" echo "${{ variables['system.config'] }}"

In this final example, the YAML is written as a long string over multiple lines. The use of block scalars ensures that the multiline string maintains its indentation and correctly breaks a string in yaml as needed.

Advantages of This Approach (ensuring readability)

Does not require manual parameter passing (uses a default value).

Works at the YAML compilation stage, ensuring predictability.

Applicable in systems that support this syntax (e.g., Azure DevOps).

The method guarantees that the string in yaml over multiple lines is handled correctly, maintaining the natural clarity of the file.

Recommendations (maintaining format and indentation)

Verify your CI/CD system’s documentation to confirm the names of predefined variables.

For runtime logic, use scripts (e.g., PowerShell/Bash) to generate dynamic values.

Reply

Stephan Rainer

5 months ago

1 comment

Rating

00

I can offer an alternative approach – isolating part of the pipeline into a template, where both the dynamic variable group and the multi-line text formatting are defined through parameters. This allows for centralized management of variables and avoids having to pass them in with every run.

Example Template (deploy-template.yml):

		
parameters: - name: environment type: string default: "Prod" jobs: - deployment: DeployTask variables: - group: "Project_${{ parameters.environment }}" steps: - script: | echo "Configuration start" echo "Configuration loaded successfully" echo "Configuration complete"

Explanation:

  • The parameter environment specifies the target environment (e.g., Prod, Test, Dev) and is used to dynamically form the variable group name – in this case resulting in “Project_Prod”. Notice how the system automatically parses the parameter and indicates the environment without additional manual input.
  • For the script, the literal style (using the “|” operator) is employed so that the output preserves the newlines and indent exactly as written. This ensures that the multi-line script remains exactly as designed, keeping its original multiple lines intact. If a more compact representation is needed, you can use the folded style, which will fold the block, replacing each newline with a space character, though this may affect clarity.

This approach minimizes duplication and centralizes parameter management while guaranteeing that multi-line values are correctly preserved or folded as desired.

Reply

    Bruno Cesar

    5 months ago

    Edited

    Rating

    00

    This approach is excellent for scaling and reducing code duplication. The use of templates means that multi-line and dynamic values are managed centrally, which helps the YAML parser to parse and indicate variables automatically.

    Pros:

    Scaling Simplification:

    Templates offer centralized control over pipeline logic and reduce code duplication, especially when handling multi-line YAML blocks with proper indent and preservation of newlines.

    Parameters with Default Values:

    Defining a parameter (e.g., environment) with a default value allows pipelines to run without manual intervention, ensuring that the parser correctly indicates and manages the multiple lines without unwanted folding—unless a folded style is explicitly desired.

    Cons:

    Extra Setup for Simple Cases:

    In simpler pipelines, configuring and maintaining templates may be seen as unnecessarily complex, potentially impacting clarity.

    Parameter Automation:

    The example does not show how to pass parameter values automatically (for instance, via environment variables or pipeline settings), which is important when you need the system to parse and fold text automatically under different circumstances.

    Reply

Emmerich Lothar

5 months ago

1 comment

Edited

Rating

00

Solution:

The issue is that directly using pipeline variables in the variable group definition is not supported. One approach is to use a predefined variable that is accessible via the variables object with the correct notation. For example, if the pipeline already has a variable named Pipeline.Definition (which can be set in the pipeline settings), you can do as follows:

		
group: ${{ variables['Pipeline.Definition'] }}.Prod

In this case, the platform will substitute the variable’s value, and the suffix “.Prod” will be appended during YAML compilation. The YAML system will evaluate the expression and indicate the proper value from the predefined variable.

Multiline Formatting:

To preserve line breaks in YAML for long descriptions or configuration fragments, use the literal style. For example, consider the following YAML:

		
config: |- First configuration line Second configuration line Third configuration line

The “|-” symbol ensures that extra empty lines at the end of the string are removed, while the newlines inside the block are preserved exactly, keeping the multi-line format and indent intact for optimal readability. Alternatively, if you need to fold the lines, you can use the folded style (using >), where each newline is replaced by spaces — this approach merges the multiple lines into one, though it may affect visual clarity when the output is later interpreted.

Reply

    Bruno Cesar

    5 months ago

    Edited

    Rating

    01

    I appreciate that the syntax $${{ variables[...] }} is used correctly to access the necessary values and that the explanation of how YAML blocks work with “|” and “|-” is clear. The solution explains how to learn how to break the block, as the YAML parser interprets it and indicates the correct newlines and indent properties.

    Pros:

    Correct Use of Syntax:

    Using the $${{ variables[...] }} construct is indeed the proper way to reference predefined variables at the YAML compilation stage. The system will evaluate the expression and indicate the intended value, ensuring that the variable group name is generated dynamically.

    Clear Explanation of YAML Block Behavior:

    The description of the literal style shows how it preserves multiple lines and newlines while removing extra empty lines at the end of the string. This is critical to keep the multi-line configuration blocks correctly formatted and with proper indent.

    Cons:

    Dependence on a Specific Variable:

    The proposed approach relies on the presence of the variable Pipeline.Definition (or its equivalent, such as Build.DefinitionName in Azure DevOps). If such a variable is not defined or a different naming convention is used, the solution becomes inapplicable. This can be a limitation if the YAML parser does not parse a variable that indicate the expected value.

    Compilation Stage Only:

    This solution works only at the YAML compilation stage, not at runtime. If dynamic logic is needed during execution, this method may not allow you to fold or adjust multiple lines dynamically.

    Reply

FAQ

Can't find an answer to your question? Ask us and we'll tall you!

How do I create a multi-line comment in YAML?

YAML does not provide a special syntax for multi‑line comments, so out of the box there’s no block‑comment sugar. For comments that span multiple lines, you must begin each line with the # symbol—think of it as commenting line‑by‑line in a shell script. This approach ensures that every line of the comment is correctly marked, maintaining proper indentation and clarity, which keeps your config lint‑friendly. Note that this method is different from how you create multiline strings in YAML when you want to use multiline content in your configuration: comments live outside the data model, whereas block scalars ship alongside your runtime payload.

What is a block chomping indicator?

A block chomping indicator is a key character in YAML used with the pipe character (|) to control how trailing newline characters are handled in strings that span several lines. It dictates whether YAML should preserve the line breaks exactly as written or remove them. This feature is essential when defining yaml strings for configurations where formatting matters. If you want to break the default behavior of preserving unwanted trailing new lines, or if you need to break extra blank lines from your output, a block chomping indicator provides a clear way to break the output formatting. It even enables you to control your YAML strings spanning several lines exactly as required.
  • Clip (default): Without an explicit indicator, YAML preserves a single trailing new line but removes any additional ones.
  • Strip (|-): This variant tells YAML to remove all trailing new line characters, which can be useful when you don't want extra blank lines at the end of the string.
  • Keep (|+): This version instructs YAML to retain all trailing new line characters, preserving every break exactly as seen in the source, thereby maintaining all the original formatting.

How do I create multi-line strings in YAML?

When you need to spin up multi-line strings in YAML without wrestling with whitespace gremlins, lean on one of two block scalar styles: literal or folded.
  • Literal style (using the pipe character |) preserves every new line exactly as written—your string keeps its multiple lines, spot‑on indentation, and hard breaks. It’s the go‑to when you need to preserve the line breaks for human‑readable docs, config snippets, or preformatted blobs.
  • Folded style ( using the greater (>) sign, i.e. using yaml folded ) folds each physical newline into a space, collapsing your text into a single paragraph. This approach is perfect when you want to break up text for readability without littering your CI diffs with extra blank lines—especially when the string should be written with the folded style.
Pick literal when you need bare‑metal formatting, folded when you just want a clean, single‑paragraph string. Easy YAML multiline magic—no regex yak‑shaving required.

What does the colon (:) symbol mean in YAML?

In YAML, it is a special character that plays a crucial role in the YAML syntax. It is used to separate keys from their corresponding values in a data serialization format and is fundamental for representing configuration files and data. Essentially, when you write YAML—used to write configuration files—every key is followed by a colon to clearly denote that what follows is the value for that key. Think of the colon as the glue in your KV pairs or the traffic cop directing payload into the right slot. It guarantees that your YAML engine doesn’t choke on ambiguous constructs and helps you sidestep parsing pitfalls.  For example, consider this YAML snippet: 
name: Otto Grotewohl 
age: 31 

Here, the colon after name indicates that "Otto Grotewohl" is the value associated with the key name, and the colon after age denotes that 31 is the value for the key age. This colon placement ensures the content is correctly interpreted, and even if there is a newline at the end of a line, it maintains the integrity of the document. Proper punctuation here prevents regression bugs or weird diffs down the road. Moreover, being sure to use consistent indentation and avoiding extra spaces helps prevent issues that could lead to parsing errors. Following these best practices is one of the features of YAML that improve the clarity and maintainability of your configuration files and data. Nail these basics, and you’ll keep whitespace gremlins out of your CI/CD pipelines.

How does YAML represent strings in configuration files for data serialization?

YAML offers a few slick tricks to serialize string values in your config files for data marshalling:
  • Single quotes: Wrapping a value in '…' acts as an escape hatch so special characters (colons, hashes, etc.) don’t get munched by the parser.
  • Literal blocks (|): Use this when you need to preserve every hard return and indentation—dump several lines of text directly within the string without yak‑shaving around concatenation hacks.
  • Folded blocks (>): When you’d rather collapse physical newlines into spaces, this style folds your content into a tight, single‑paragraph payload while you still author it on multiple lines.
These approaches tame whitespace gremlins, keep your CI diffs lean, and ultimately improve the readability and maintainability of your configuration data—no regex gymnastics required.

Why is consistent indentation important in YAML documents?

YAML is highly sensitive to whitespace, so it's essential to use consistent indentation throughout. Typically, this means setting a fixed number of spaces for each indentation level. If content is more-indented than necessary or if there are extra spaces, the YAML interpreter might misinterpret the structure, potentially leading to errors. Following these guidelines when writing configuration files for data serialization not only preserves clarity but also improve the clarity and maintainability of your documents.

How do I create multiline strings in YAML and control newline characters, especially at the end of a line, using literal and folded styles?

YAML also supports representing strings into multiple lines using block scalar styles, a feature that really shines in formats used to write configuration files. When you want to preserve the line exactly as written—including that trailing newline—you reach for the literal style (|), which locks in every hard break and keeps whitespace gremlins at bay. If you’d rather swap newline characters for spaces, the folded style (>) merges your text into a single‑paragraph blob to make it easier to read; it’s a low‑ceremony way to tame CI diffs and skip the regex yak‑shaving. Between these two modes, you get pinpoint control over newline characters without any extra hacks.