Subhankar
Subhankar

Reputation: 507

YAML : How do I override variables

I have a YAML like the following:

defaults: &defaults
  username: admin
  password: admin
  agents:
    blueprint: &agent_blueprint
      version: '1'
      auth:
        username: agent
        password: secret
      supported_features:
      - state
      - lifecycle
      - credentials
      - backup
      - restore
  services:
  - &blueprint_service
    id: '24731fb8-7b84-4f57-914f-c3d55d793dd4'
    name: 'blueprint'
    plans:
    - id: 'bc158c9a-7934-401e-94ab-057082a5073f'
      name: 'v1.0-dedicated-xsmall'
      free: false
      manager:
        name: 'director'
        settings:
          prefix: 'blueprint'
          agent: *agent_blueprint
          context:
            agent: *agent_blueprint

Now I want to add another node to override the supported_features nodes inside the services array. So, I added something like this.

development:
  <<: *defaults
  agents:
    blueprint:
      <<: *agent_blueprint
      supported_features:
      - state
      - lifecycle
      - credentials
  services:
  - *blueprint_service

However, it does not update the supported_features node under services. How do I do it?

Upvotes: 1

Views: 11081

Answers (1)

Anthon
Anthon

Reputation: 76588

In YAML there are no variables, and I think you have misunderstanding on what the merge key feature of YAML actually does.

In your second YAML block you do this:

development:
  <<: *defaults

which has absolutely no effect as you immediately override both of the key-value pairs (with keys agents and blueprints) and this:

agents:
    <<: *agents

has no effect because you override the single key blueprint.

After that you do:

blueprint: &agent_blueprint
  <<: *agent_blueprint
  supported_features:

which merges in the keys from the value for blueprint that you just started defining, i.e. supported_features (the one on the third line) and its value. This is because an alias always takes the definition from the anchor that comes before it (and if there are multiple anchors with the same name, from the latest anchor defined).

So your second example could be written much simpler as:

development:
  agents:
    blueprint: 
      supported_features:
      - state
      - lifecycle
      - credentials
  services:
  - *blueprint_service

where *blueprint_service gets expanded to:

id: 24731fb8-7b84-4f57-914f-c3d55d793dd4
name: blueprint
plans:
- free: false
  id: bc158c9a-7934-401e-94ab-057082a5073f
  manager:
    name: director
    settings:
      agent: *agent_blueprint
      context:
        agent: *agent_blueprint
      prefix: blueprint
  name: v1.0-dedicated-xsmall

because of the anchors in effect when that anchors is defined in your first YAML block. And *agent_blueprint in there to:

  auth: {password: secret, username: agent}
  supported_features: [state, lifecycle, credentials, backup, restore]
  version: '1'

There is no "updating". An alias gets its value from what the anchor is defined as, when the alias gets parsed.

Upvotes: 1

Related Questions