So I know I can do something like this:
copy:
  dest: /etc/issue
  content: |
    Hello
    World
But this doesn't work:
vars:
  login_banner_text: !!str |-
    "Hello\nWorld"
tasks:
  - name: Set TTY login banner
    copy:
      dest: /etc/issue
      content: "{{ login_banner_text }}"
The newline character is printed straight to the file, without parsing, i.e. it's a single line populated with \n strings. I'd like to do this without copying a file into place, because I need to copy this text to two files. 
For one file, the \n strings need to remain unparsed, so it's written to file as a single line. For the other, I want the \n to be interpreted, so that the text is expanded into multiple lines. 
The first file is being modified using the ini_file module. This task works as expected using the explicit \n in the variable declaration.
- name: "Set message"
  ini_file:
    dest: /etc/dconf/db/gdm.d/00-security-settings
    section: org/gnome/login-screen
    option: banner-message-text
    value: string '{{ login_banner_text }}'
    create: yes
    tags:
      - always
However, other modules behave this way as well.
If I copy a file into place, the rather long text (not "Hello World") has to be maintained in two places.
I found, what I think is, a better way of doing this, based on this post. It stores the banner in a separate file, and then uses that to modify both configuration files. So the value is only stored in one place. However, the answer given by @larsks does answer the question as it was originally posed.
- hosts: 127.0.0.1
  connection: local
  vars:
    login_banner_text: "{{ lookup('file', 'login_banner.txt') }}"
  tasks:
    - name: "Set the GNOME3 Login Warning Banner Text"
      ini_file:
        dest: /etc/dconf/db/gdm.d/00-security-settings
        section: org/gnome/login-screen
        option: banner-message-text
        value: '{{ login_banner_text | to_json }}'
        create: yes
      tags:
        - always
    - name: "Set the TTY Login Warning Banner Text"
      copy:
        dest: '/etc/issue'
        content: "{{ '\n' + login_banner_text + '\n' }}"
      tags:
        - always
You already know how to specify a value with literal newlines; you're doing it when setting the content key in your first example. You can set the value of a variable the same way:
---
- hosts: localhost
  gather_facts: false
  vars:
    mytext: |
      Hello
      World
  tasks:
    - copy:
        dest: ./output.txt
        content: "{{ mytext }}"
This would create output.txt with the content:
Hello
World
If instead your goal is to have content like this...
[org/gnome/login-screen]
banner-message-text = "Hello\nWorld"
...then you don't want literal newlines, you want a literal \n, in which case this would work:
---
- hosts: localhost
  gather_facts: false
  vars:
    mytext: "Hello\\nWorld"
  tasks:
    - ini_file:
        dest: ./example.ini
        section: org/gnome/login-screen
        option: banner-message-text
        value: "{{ mytext }}"
        create: true
Which would result in:
[org/gnome/login-screen]
banner-message-text = Hello\nWorld
If you wanted the value in the config file quoted, then:
    - ini_file:
        dest: ./example.ini
        section: org/gnome/login-screen
        option: banner-message-text
        value: '"{{ mytext }}"'
        create: true
Which gets you:
[org/gnome/login-screen]
banner-message-text = "Hello\nWorld"
You could also do it like this:
---
- hosts: localhost
  gather_facts: false
  vars:
    mytext: |-
      Hello
      World
  tasks:
    - ini_file:
        dest: ./example.ini
        section: org/gnome/login-screen
        option: banner-message-text
        value: '{{ mytext|to_json }}'
        create: true
This gets you the same output as the previous example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With