Search code examples
jsontemplatesansiblejinja2ansible-vault

Ansible Vault inline variable with to_nice_json: Unexpected templating type error occurred...not JSON serializable


I typically configure my projects by settings configuration variables in vars/main.yml and rendering a subset of those out to a JSON via to_nice_json.

Consider an example of the vars/main.yaml like the one below:

  # Application Configuration Settings.
  config:

    dev:
      # General Settings.
      logger_level: DEBUG

      # PostgreSQL Server Configuration Settings.
      sql_host: "localhost"
      sql_port: 5432
      sql_username: "someuser"
      sql_password: "somepassword"
      sql_db: "somedb"

which I render out via a Jinja2 template and the template module with the following content:

{{ config.dev | to_nice_json }}

Recently I tried to use Ansible Vault to encrypt the sensitive bits, e.g., the sql_password through the encrypt_string command as such:

ansible-vault encrypt_string --vault-id .ansible-vault-password "somepassword" --name 'sql_password'

and inline the encrypted version directly in the YAML file like this:

# Application Configuration Settings.
config:

    dev:
      # General Settings.
      logger_level: DEBUG

      # PostgreSQL Server Configuration Settings.
      sql_host: "localhost"
      sql_port: 5432
      sql_username: "someuser"
      sql_password: !vault |
      $ANSIBLE_VAULT;1.1;AES256
      35383832623937353934636538306539623336633336643430396662323161333838333463653764
      3839653635326166303636643664333466376236626137310a323839373862626237643162303535
      35333966383834356239376566356263656635323865323466306362323864356663383661333262
      3165643733633262650a663363653832373936383033306137633234626264353538356630336131
      3063
      sql_db: "somedb"

However, when the to_nice_json filter is applied I get the following error:

fatal: [myrole]: FAILED! => {"changed": false, "msg": "AnsibleError: Unexpected templating type error occurred on ({{ config.dev | to_nice_json }}\n): somepassword' is not JSON serializable"}

As can be see, the variable is property decrypted but it errors out when serialising to JSON. If I wrap the inline vault variable in double-quotes, however, the decryption doesn't happen and the resulting JSON contains the entire vault blob.

Am I missing something? Is this issue with the to_nice_json filter or am inlining it the wrong way?


Solution

  • As a workaround for such problems extract the vaulted value to a separate variable (as opposed to a value of a key in a dictionary):

    vars:
      my_sql_password: !vault | 
        $ANSIBLE_VAULT;1.1;AES256
        5383832623937353934636538306539623336633336643430396662323161333838333463653764
        3839653635326166303636643664333466376236626137310a323839373862626237643162303535
        35333966383834356239376566356263656635323865323466306362323864356663383661333262
        3165643733633262650a663363653832373936383033306137633234626264353538356630336131
        3063
      # Application Configuration Settings.
      config:
        dev:
          # General Settings.
          logger_level: DEBUG
    
          # PostgreSQL Server Configuration Settings.
          sql_host: "localhost"
          sql_port: 5432
          sql_username: "someuser"
          sql_password: "{{ my_sql_password }}"
          sql_db: "somedb"