Bill Armstrong
Bill Armstrong

Reputation: 1777

Anisble Yaml file formating for quotes

I'm running an ansible playbook that allows me to (or should allow me to) replace two lines in a configuration file for a remote server. Most of the file replacements are dictionary style entries where neither the key nor the value have quotes. But there is one replacement where the name needs to be quoted. Here is the task from the ansible playbook:

- name: Enable traefikExporter within vars.jsonnet configuration file.
  ansible.builtin.replace:
    path: /home/bill/cluster-monitoring/vars.jsonnet
    regexp: "name: 'traefikExporter',[\n\r].*[\n\r]"
    replace: |6
        name: 'traefikExporter',
        enabled: true,

The error thrown is:

The offending line appears to be

  replace: |6
    name: 'traefikExporter'
    ^ here

and it notes that it is a mismatched quote. But I've tried changing the yaml replace parameter to > and using \n for line breaks on a single line as well as the | with quoted lines. They all throw versions of the mismatched quote error.

For reference, the following task, which is immediately above this task, runs correctly without errors:

- name: Enable k3s Monitoring within vars.jsonnet configuration file.
  ansible.builtin.replace:
    path: /home/bill/cluster-monitoring/vars.jsonnet
    regexp: "\  k3s: {[^}]*},"
    replace: |2
        k3s: {
          enabled: true,
          master_ip: ['192.168.2.139'],
        },

The closest thing I could find is here, but this didn't work. In both cases the regexp covers multiple lines and the replace covers the same lines identified by the regexp. What am I missing?

update

I also tried replacing the replacement text and now believe that the actual formatting issue is in the regexp: "name: 'traefikExporter',[\n\r].*[\n\r]" line. No matter what I place in the replace line it throws the error. I think the quotes in the regexp are the issue.

work around

I came up with a work around but it still isn't right. The following is very close to what I'd like - but a bit frustrated that it isn't exactly what I expected:

-  name: Enable traefikExporter within vars.jsonnet configuration file.
   ansible.builtin.replace:
     path: /home/bill/cluster-monitoring/vars.jsonnet
     regexp: "name: 'traefikExporter',[\n\r].*"
     replace: >4
         name: 'traefikExporter',
               enabled: true,

The |6 or >6 was the problem - but not sure why. My expected behavior was to have a 6 space indent. But this is the thing throwing the error. When I put it to 4 there is no quote error. But as you can see - to get the formatting right I have to do some weird spacing (the name: is the correct indentation with the 4, but I have to add 6 actual spaces to get the next line to align. Not part of this question - but neither the | nor the > seems to impact the trailing return in both cases there is an extra line after the replacement.

Upvotes: 0

Views: 327

Answers (1)

flyx
flyx

Reputation: 39708

YAML processes escape sequences in double-quoted scalars, so you should use

    regexp: "name: 'traefikExporter',[\\n\\r].*[\\n\\r]"

I suggest however to use a block scalar to avoid escaping hell:

    regexp: >-
      name: 'traefikExporter',[\n\r].*[\n\r]

Regarding the indentation indicator, this cannot work:

      replace: |6
        name: 'traefikExporter',
        enabled: true,

You are basically saying „the following block scalar has 6 spaces indentation in addition to the indentation of the replace: key“. However, it only has two, which makes the YAML parser immediately drop out of block scalar parsing mode. The following error results from the YAML parser trying to interpret what you intend to be the block scalar's content as part of the YAML structure.

I suggest doing:

      replace: |-2
          name: 'traefikExporter',
          enabled: true,

to give the block scalar 2 space in front of each line (which seems to be what you want) and also to remove the trailing newline (with the -).

Upvotes: 1

Related Questions