YML Error when using shell module

Hello, I am using the shell module to run a command inside a docker container and it is giving me a yaml error. The command is stupid silly complicated :wink: Is there a way to get Ansible to just send it as is and ignore \ escape out the characters that may be freaking out Yaml?

Here is an example of a basic command that does work.

shell: docker exec -it 9d5e563a6e9e bash -c “cd /var/log ; ls; cat bootstrap.log”

However this command gives me a yaml eror

shell: docker exec -it 9d5e563a6e9e bash -c “echo ‘rs.initiate({_id: "mongors1conf",configsvr: true, members: [{ _id : 0, host : "mongocfg1" },{ _id : 1, host : "mongocfg2" }, { _id : 2, host : "mongocfg3" }]})’ | mongo”

Here is a snippet of the error
ERROR! Syntax Error while loading YAML.

mapping values are not allowed in this context

shell: docker exec -it 9d5e563a6e9e bash -c "echo 'rs.initiate({_id: \"mongors1conf\",configsvr: true, members: [{ _id : 0, host : \"mongocfg1\" },{ _id : 1, host : \"mongocfg2\" }, { _id : 2, host : \"mongocfg3\" }]})' | mongo" **^ here**

This command works just fine at the bash shell of the docker host. I have tried the ansible shell and the Ansible command module

I know this command looks complicated but please keep in mind I am only asking how to format this to work in Ansible. I am not asking you to understand docker exec Mongodb commands :wink:

Thanks for your help

Hello, I am using the shell module to run a command inside a docker container and it is giving me a yaml error. The command is stupid silly complicated :wink: Is there a way to get Ansible to just send it as is and ignore \ escape out the characters that may be freaking out Yaml?

Here is an example of a basic command that does work.

shell: docker exec -it 9d5e563a6e9e bash -c “cd /var/log ; ls; cat bootstrap.log”

However this command gives me a yaml eror

shell: docker exec -it 9d5e563a6e9e bash -c “echo ‘rs.initiate({_id: "mongors1conf",configsvr: true, members: [{ _id : 0, host : "mongocfg1" },{ _id : 1, host : "mongocfg2" }, { _id : 2, host : "mongocfg3" }]})’ | mongo”

Here is a snippet of the error
ERROR! Syntax Error while loading YAML.

mapping values are not allowed in this context

shell: docker exec -it 9d5e563a6e9e bash -c "echo 'rs.initiate({_id: \"mongors1conf\",configsvr: true, members: [{ _id : 0, host : \"mongocfg1\" },{ _id : 1, host : \"mongocfg2\" }, { _id : 2, host : \"mongocfg3\" }]})' | mongo" **^ here**

This command works just fine at the bash shell of the docker host. I have tried the ansible shell and the Ansible command module

Did you try one of the dedicated docker modules?

https://docs.ansible.com/ansible/latest/collections/community/general/docker_container_module.html

FWIW, test the run-string first. For example

    - set_fact:
        my_init: '{_id: \"mongors1conf\",
                    configsvr: true,
                    members: [{_id: 0, host: \"mongocfg1\"},
                              {_id: 1, host: \"mongocfg2\"},
                              {_id: 2, host: \"mongocfg3\"}]}'
    - shell: "echo 'echo \"rs.initiate({{ my_init }})\"|mongo'"
      register: result
    - debug:
        var: result.stdout

should give

  result.stdout: 'echo "rs.initiate({_id: \"mongors1conf\",
  configsvr: true, members: [{_id: 0, host: \"mongocfg1\"}, {_id: 1,
  host: \"mongocfg2\"}, {_id: 2, host: \"mongocfg3\"}]})"|mongo'

Send it to mongo if it looks like what you want. But, mongo should
accept JSON. It'd be simpler to create a dictionary in YAML and use
the Ansible filter *to_json* to convert the data. In addition to this
filter use Jinja filter *tojson* to escape the quotes and strip the
leading and cloding quote. For example

    - set_fact:
        my_init: "{{ (my_init_yaml|to_json|tojson)[1:-1] }}"
      vars:
        my_init_yaml:
          _id: mongors1conf
          configsvr: true
          members:
            - _id: 0
              host: mongocfg1
            - _id: 1
              host: mongocfg2
            - _id: 2
              host: mongocfg3
    - shell: "echo 'echo \"rs.initiate({{ my_init }})\"|mongo'"
      register: result
    - debug:
        var: result.stdout

should give valid escaped JSON

  result.stdout: 'echo "rs.initiate({\"_id\": \"mongors1conf\",
  \"configsvr\": true, \"members\": [{\"_id\": 0, \"host\":
  \"mongocfg1\"}, {\"_id\": 1, \"host\": \"mongocfg2\"}, {\"_id\": 2,
  \"host\": \"mongocfg3\"}]})"|mongo'

Ref: No quotes in MongoDB JSON
https://stackoverflow.com/questions/35100836/no-quotes-in-mongodb-json

Yeah I did look at the Docker Module. Unfortunately, it does not have any modules for what I am doing

Vladimir, very thankful for your well thought out and detailed answer! This gives me enough information to explore the json option