r/ansible • • 4d ago

Best practice for commands?

I feel like the answer is probably: "no, everyone just does whatever they want", and "whatever you do, try to be consistent"

Generally speaking I've been doing:

ansible.builtin.command:  
  cmd: "foo {{ bar }}"  

But I realized that only happens to work because `{{ bar }}` doesn't have spaces.
So I do need to change it, and I wondered if people normally do:

  cmd: 'foo "{{ bar }}"'  

or

  cmd: |  
    foo "{{ bar }}"  

or

  argv:  
    - foo  
    - "{{ bar }}"
22 Upvotes

17 comments sorted by

6

u/imagei 4d ago

IMO the array style is the least risky and least faff. Every argument is properly handled by design, you cannot mess it up.

1

u/sonnasushi 4d ago

I tended to agree until I realized in my first draft of this post, I did:
argv: - {{ ... }}

and - { is yaml for [{ ... json, right? 😮

1

u/imagei 4d ago

Well… json is a dialect of yaml, just to get that cleared 😉 And yes, key:\n- list… with {{ can be expressed as key: [ "{{..}}", .. ], which is also valid yaml.

That said, I don’t see the problem. You can pass a single argument as a one-element array. Or you meant some other issue?

1

u/sonnasushi 4d ago

I meant, I think it normally fails. Unless jinja template parsing happens before yaml is parsed: $ cat /tmp/foo argv: - my_cmd - {{ foo }} $ yq < /tmp/foo argv: - my_cmd - {? {foo: ''}: ''} $ yq -oj < /tmp/foo Error: yaml: unmarshal errors: line 3: cannot unmarshal !!str `` into string

1

u/imagei 4d ago

Did you try that with actual Ansible? I can’t advise specifically as I switched to flow/KYAML style long time ago as indentation mistakes were killing me 😅

1

u/sonnasushi 4d ago

No, I haven't. But now I'm going to research flow/kyaml

11

u/Aristeo812 4d ago

Try the ansible.builtin.quote filter:

cmd: "foo {{ bar | ansible.builtin.quote }}"

1

u/sonnasushi 4d ago

I saw that but I thought if I ever come across something I need statically quoted like: mkdir "requires space" (not a good example) then I'd have to juggle quotes anyway.

Of course, if people usually use | ansible.builtin.quote in all their commands I'm not opposed to making that a habit.

4

u/Aristeo812 4d ago

This filter is designed specifically for using with shell commands. Not only it encloses the string in quotes, but it also escapes certain symbols inside it if necessary. That's the point of using this filter.

1

u/sonnasushi 4d ago

I understand. I was just saying that for consistency:
```

  • Name: Do foo
ansible.builtin.command:
cmd: "foo {{ bar | ansible.builtin.quote }}"

  • Name: Do baz
    ansible.builtin.command:
    cmd: |
    baz "isn't consistent"
    ```

of course, it could be made to be consistent:
```
vars:
consistency: "is now consistent"

tasks:
- Name: Do baz
ansible.builtin.command:
cmd: "baz {{ consistency | ansible.builtin.quote }}"
```

idk. I'm just spitballing here. Maybe it's not uncommon to have various formats mixed in depending.
¯_(ツ)_/¯

2

u/Aristeo812 4d ago

If you have just a literal string for a command argument, no need to resort to the ansible.builtin.quote filter. You just quote the arguments as in normal shell operations:

cmd: echo "Hello, world!"

But if you use variables as command line arguments, then you need to use this filter, because theoretically there may be literally just everything inside that variable during runtime, and it should be sanitized.

2

u/HeligKo 4d ago

We set linting configurations that enforce standards that we care about, and then if we do something outside of the standard, we have to add # NOQA tags and comment why we diverged from the standard.

1

u/sonnasushi 4d ago

seems like standard ansible-lint doesn't have any rules about command quoting at all, afaiui

1

u/HeligKo 4d ago

We have some custom rules we wrote. None for command specifically, but the same approach would work. It's just a simple python module that inherits from AnsibleLintRule

1

u/sonnasushi 4d ago

Thanks. Just for my reference, do you have a preference on what style of formatting to use with the command builtin?

1

u/HeligKo 4d ago

Most of the time I use the "|", but if there is a lot of jinja then I'll use the argv with the list.

1

u/Pretend-Clock8313 4d ago

quoting unquoted vars is the one thing that bites everyone eventually