Slashes vs Backslashes When Targeting MS Windows Hosts

When targeting MS Windows hosts, use slashes for all paths. Convert to backslashes only if necessary.

When targeting MS hosts, consistently use slashes for paths. In the rare event that a module, such as Ansible’s win_package, does not support slashes, apply a filter to convert slashes to backslashes, such as c2platform.core.replace_slashes.

Problem

Using backslashes when targeting Windows hosts in Ansible projects can cause issues because, in Ansible YAML code, the backslash serves as an escape character. This results in various potential solutions, leading to inconsistency and differing workarounds in the codebase without a standardized approach.

Consider a scenario where you have a variable, fme_flow_backup_path, intended to create a backup, differing by DTAP environment. For example, the “test” environment backup should be located at \\backup\test. A project variable, gs_env, indicates the environment type, equating to test when targeting a “test” environment node.

An intuitive but incorrect initial solution could resemble the following:

fme_flow_backup_path: "\\backup\{gs_env}\"  # ❌ Not valid Ansible / YAML code

The code above is flawed since the backslash is misinterpreted as an escape character. Rewriting requires each backslash to be escaped:

fme_flow_backup_path: "\\\\backup\\{gs_env}\\"

Alternatively, escape is unnecessary with single quotes:

fme_flow_backup_path: '\\backup\{gs_env}\'

Or, replace backslashes with slashes:

fme_flow_backup_path: "//backup/{gs_env}/"

These examples highlight assorted methods to handle Windows paths in Ansible projects. Without a clear guideline, developers’ personal preferences could lead to inconsistent approaches.

Solution

The recommended approach in this guideline is to consistently use double quotes and slashes. Using forward slashes as path separators is generally effective, especially when creating code functional on both Windows and POSIX (Unix/Linux/macOS) systems. Windows automatically performs path normalization, converting slashes to backslashes1. For Ansible modules where slashes are unsupported, employ a filter (e.g., c2platform.core.replace_slashes) to transform slashes into backslashes.

  1. Follow the Ansible community practice of using double quotes.
  2. Choose slashes over backslashes, as Windows supports them via path normalization1.
  3. Employ a filter like c2platform.core.replace_slashes for modules like win_package2 that necessitate backslashes.

This approach ensures consistent slash usage regardless of targeting Windows hosts, while applying filters to handle specific exceptions.

Example and Implementation

To configure an Ansible variable with a Windows path, as in the “test” environment scenario directing to a share \\backup\test, employ “slashes” as demonstrated below, with gs_env equal to test:

fme_flow_backup_path: "//backup/{gs_env}/"

In instances where slashes are ineffective, such as the win_package module which requires backslashes2, utilize the c2platform.core.replace_slashes filter, as shown:

---
- name: Windows Package
  hosts: windows
  vars:
    my_windows_package_path: //software/arcgis/WebDeploy_amd64_en-US.msi
  tasks:
    - name: My Windows Package
      win_package:
        path: "{{ my_windows_package_path | c2platform.core.replace_slashes }}"

Footnotes


  1. For more on Windows path normalization and handling of slashes, refer to File path formats on Windows systems - .NET | Microsoft Learn   ↩︎ ↩︎

  2. At the time of this guideline’s creation, the win_package Ansible module was noted as the only module not supporting slashes. ↩︎ ↩︎



Last modified November 13, 2024: translate false C2-587 (af41e45)