« Back to Index

Yaml: merge key and reference pointer

View original Gist on GitHub

Tags: #yaml #syntax #dereference #pointer #merge

yaml merge key and reference pointer.md

NOTE: use https://onlineyamltools.com/convert-yaml-to-json for testing conversions.

Lists

You can create a reference pointer using & and dereference the pointer using * as shown here:

foo:
 - &ref |-
  x
 - y
 - z

bar:
  - *ref
  - a
  - b

This will produce the following JSON (notice the x list element was duplicated):

{
  "foo": [
    "x",
    "y",
    "z"
  ],
  "bar": [
    "x",
    "a",
    "b"
  ]
}

Objects

This works for key value objects too by using the ‘merge key’ syntax << with a pointer to an object:

ref: &obj
  foo: bar

another_key:
 << : *obj
 beep: boop

This will produce the following JSON (notice the foo: bar key/value was duplicated):

{
  "ref": {
    "foo": "bar"
  },
  "another_key": {
    "foo": "bar",
    "beep": "boop"
  }
}

Merge Key reference (spacing doesn’t matter, e.g. <<: *obj vs << : *obj)

Nested example

The following example is a list of objects:

dockers:
- <<: &docker_opts
    use_buildx: true
    dockerfile: Dockerfile
  image_templates:
    - "ghcr.io/fastly/cli:{{ .Version }}-386"
  build_flag_templates:
    - "--platform=linux/386"
- <<: *docker_opts
  image_templates:
    - "ghcr.io/fastly/cli:{{ .Version }}-amd64"
  build_flag_templates:
    - "--platform=linux/amd64"
- <<: *docker_opts
  image_templates:
    - "ghcr.io/fastly/cli:{{ .Version }}-arm64"
  build_flag_templates:
    - "--platform=linux/arm64"
  goarch: arm64

Caveats

This doesn’t work as well when it comes to grouping multiple list elements:

foo: &ref
 - y
 - z

bar:
  - *ref
  - a
  - b

As this will nest the reference instead of merging it:

{
  "foo": [
    "y",
    "z"
  ],
  "bar": [
    [
      "y",
      "z"
    ],
    "a",
    "b"
  ]
}

This also doesn’t work (at all) for copying individual key/value fields (i.e. you can only reference an object ‘block’).

The following example is broken:

foo: &ref bar # the &ref isn't invalid (i.e. it doesn't break the yaml parser)
beep: boop
nested:
  << : *ref   # but 'using' the ref in this way IS invalid