John David
John David

Reputation: 131

Separating yaml files and passing in variables

Is there any way to separate a YAML file and pass in variables to sub files?

For Example:

Parent yaml file:

Fn::Merge:
  - !Include /templates/first.yaml, variables: {env: staging}
  - !Include /templates/second.yaml, variables: {env: production}

first.yaml file:

First:
  Properties:
   env: ${env}

Upvotes: 1

Views: 1964

Answers (1)

Anthon
Anthon

Reputation: 76742

This cannot be done in YAML itself, i.e. there is nothing in the specification that speaks about including sub files or variable expansion.

It is possible that a program that loads the YAML does something like this, but there are some problems with the syntax that you indicate.

The ${env} looks like a template what you expect to be replaced by staging during loading. However it is unclear from your example whether you always expect a complete scalar node to be replaced, or if this can be done mid-scalar and if so what the escape mechanism is (i.e. how to specify something in an included file that results in a string ${env} in your program).

You should IMO explicitly tag scalars that needs template expansion. You could make your first.yaml example into

   env: !v env

where interpretation of the !v tag takes the full scalar. And if you want expansion withing scalars you use a different tag and the more verbose template option you have been using.

   xyz: !t This is a more verbose ${env} specficication

You might think you no longer need to worry about escaping, because if there is no tag, the ${env} is not interpreted, but that is not the case: you can still can have scalars where some ${...} patterns need interpreting and other don't.

Your !Include tag has some problems as well. It is good that you make things explicit by using a tag. Some programs like Symfony do this kind of inclusion by magically interpreting special keys and scalar syntax (but this could be a result of having to work around the rather incomplete PHP YAML parser the use).

But your parameter passing is going to provide some problems as this:

!Include /templates/first.yaml, variables: {env: staging}

is going to be interpreted as if you wrote a single huge key with an embedded comma. Your YAML is equivalent to

  • !Include "/templates/first.yaml, variables": {env: staging}

And I don't think that is what you want. You should probably make the parameter for !Include an explicit sequence:

  • !Include [/templates/first.yaml, variables: {env: staging}]

in which case order of parameters is important. Or use mappings for every parameter:

  • !Include {file: /templates/second.yaml, variables: {env: production}}

How this all should be actually implemented depends on your programming language and the parser you are using.

Upvotes: 1

Related Questions