How to convert json to an ansible playbook yaml file
- Step 1Shape the JSON for its destination — For a variable file, use a flat or nested object (
{ "http_port": 8080, "app": { "replicas": 3 } }). For a task list, use an array of task objects, each withnameand a module key ([{ "name": "Install nginx", "ansible.builtin.apt": { "name": "nginx", "state": "present" } }]). - Step 2Drop the JSON file on the tool — There is no paste field — drop your
.jsonfile onto the dropzone. The free tier accepts files up to 2 MB; Pro raises this to 100 MB, which covers even large dynamic-inventory dumps. - Step 3Pick indent 2 and run — Leave indent at 2 for the compact
- name:task style Ansible authors expect, then click Convert to YAML. Indent 4 expands each list item, which is valid but reads oddly and trips someansible-lintstyle rules. - Step 4Fix any quoted-boolean values you actually want as booleans — If a JSON string
"yes"should be a real boolean in Ansible, change the source JSON to a JSON booleantrueand reconvert — or unquote it in the output. The converter deliberately quotes string-booleans to keep them strings. - Step 5Add Ansible-only keys by hand —
whenconditions,loop/with_items,notifyhandlers,tags,become, andregisterrarely exist in source JSON. Add them to the converted YAML manually — the converter never invents them. - Step 6Save to the right Ansible path — Variable files go in
group_vars/<group>.ymlorhost_vars/<host>.yml. Task lists go inside a playbook'stasks:block or a role'stasks/main.yml. To verify the YAML round-trips, convert it back with yaml-to-json and diff against the original.
The two real conversion controls
Only these two options appear in the json-to-yaml UI. Line width (80) and anchor handling are fixed defaults.
| Control | Values | Default | Ansible impact |
|---|---|---|---|
| Indent | 2 or 4 | 2 | Use 2 for the compact - name: task style. Indent 4 puts the sequence - on its own line with the task body indented under it — valid, but not idiomatic and flagged by some linters |
| Sort keys alphabetically | on / off | off (preserves order) | Off keeps authored order so name: stays first on a task. On alphabetises every mapping, which can push name: below ansible.builtin.* and hurt readability — usually leave off for tasks |
| Line width (fixed) | 80 columns | 80 (not adjustable) | A long single-line command/shell value folds with >- across multiple lines. The value is unchanged, but it is not the literal | form some authors expect |
| Anchors / aliases (fixed) | disabled | noRefs = true | Repeated sub-structures are written out fully — no &anchor/*alias. Avoids surprising Ansible's parser with YAML merge keys you didn't intend |
JSON → YAML mapping for Ansible data
Type behaviour for the value shapes Ansible variable files and tasks hit most.
| JSON in | YAML out | Ansible note |
|---|---|---|
"state": "present" | state: present | Plain string, unquoted — paste-ready module arg |
"enabled": true | enabled: true | Real boolean stays a boolean — correct for module flags |
"value": "yes" | value: 'yes' | Quoted to stay a string. Without quotes Ansible's YAML 1.1 parser would read it as boolean true |
"http_port": 8080 | http_port: 8080 | Unquoted integer |
[ {"name":"..."}, ... ] (top level) | - name: ... sequence | Top-level array → top-level YAML list; no wrapper key added |
"cmd": "<120-char command>" | cmd: >- folded block | Single-line long string folds with >-, not | |
Cookbook
Real Ansible variable and task JSON converted to playbook YAML. Hostnames and secrets are illustrative; nothing is uploaded.
JSON task array → playbook tasks block
ExampleAn array of task objects converts to a YAML sequence you paste straight under tasks:. Note that name comes first because sort-keys is off (the default).
JSON:
[
{"name":"Install nginx",
"ansible.builtin.apt":{"name":"nginx","state":"present"}},
{"name":"Start nginx",
"ansible.builtin.service":{"name":"nginx","state":"started"}}
]
YAML (indent 2):
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Start nginx
ansible.builtin.service:
name: nginx
state: startedThe 'yes'/'no' string-vs-boolean trap
ExampleThis is the single most important Ansible-YAML gotcha. A JSON string "yes" is quoted so it stays a string; a JSON boolean true stays a boolean. Get the source JSON type right and the YAML is correct.
JSON:
{"gather_facts":false,"answer":"yes","managed":true}
YAML:
gather_facts: false # boolean (from JSON false)
answer: 'yes' # STRING (quoted) — stays the literal text 'yes'
managed: true # boolean (from JSON true)
If you wanted answer to be a boolean, set it to true in the JSON.Nested vars for group_vars
ExampleA nested config object becomes a clean YAML mapping ready for group_vars/web.yml — no quote noise around keys.
JSON:
{"app":{"name":"web","replicas":3,"ports":[80,443]},
"feature_flags":{"beta":true}}
YAML (indent 2):
app:
name: web
replicas: 3
ports:
- 80
- 443
feature_flags:
beta: trueDynamic inventory JSON → static YAML inventory
ExampleA dynamic-inventory script's --list output is JSON. Convert it to YAML to review or freeze it as a static inventory for local testing, without running the dynamic script.
JSON (inventory --list):
{"web":{"hosts":["web1","web2"]},
"_meta":{"hostvars":{"web1":{"ansible_host":"10.0.0.1"}}}}
YAML (indent 2):
web:
hosts:
- web1
- web2
'_meta':
hostvars:
web1:
ansible_host: 10.0.0.1Long shell command folds with >-
ExampleA single-line command longer than 80 chars is folded, not kept on one line and not written as a literal | block. The command still runs identically because >- reconstructs the original string.
JSON:
{"ansible.builtin.shell":"find /var/log -name '*.log' -mtime +30 -exec gzip {} \\;"}
YAML:
ansible.builtin.shell: >-
find /var/log -name '*.log' -mtime +30 -exec gzip {}
\;Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
String 'yes'/'no' quoted to avoid boolean coercion
PreservedAnsible uses YAML 1.1, where bare yes, no, on, off are booleans. The converter quotes string-valued 'yes'/'no' so they stay strings — which is almost always what you want. If you actually need a boolean, set the JSON value to a real true/false and reconvert.
Long command folds with >- not |
PreservedA single-line shell/command string over 80 chars is wrapped with a folded block scalar (>-), not the literal | form. The folded value reconstructs to the same command, so execution is identical — but if you specifically need a literal multi-line block, embed real newlines (\n) in the JSON string, which produces |- instead.
No Ansible keys are added
By designwhen, loop, notify, tags, become, and register do not exist in source JSON and the converter never invents them. Add them by hand after conversion. This keeps the tool a faithful JSON→YAML converter rather than a playbook generator.
Indent 4 expands task list items
ExpectedAt indent 4, each sequence item is written as a bare - with the task mapping indented beneath it. Ansible parses it, but it's not idiomatic and ansible-lint's indentation rules may flag it. Use indent 2 for tasks.
Invalid JSON input
ErrorThe converter runs JSON.parse on the file. A trailing comma, a // comment, or a single-quoted string throws and nothing converts. If your source was hand-edited or copied from a JS file, fix it with json-format-fixer first.
Multi-line string becomes a |- block
SupportedIf a JSON string contains real newline characters (\n), js-yaml emits it as a literal block scalar (|-), preserving the line breaks — useful for multi-line copy content or here-docs. This differs from the folded >- you get for a long single-line string.
Sorting keys reorders task fields
ExpectedTurning on sort-keys alphabetises every mapping, which can push name: below ansible.builtin.* on a task and hurt readability. Leave sort-keys off for task lists; reserve it for alphabetising flat variable files.
Underscore/reserved-looking keys quoted
PreservedKeys like _meta (common in dynamic-inventory JSON) or values that resemble YAML keywords are quoted on output to remain valid scalars. They parse back to the same key/value, so Ansible reads them correctly.
Vault-encrypted values pass through as strings
PreservedAn !vault block can't exist in JSON, but a vault-referenced secret name or an already-encrypted string stored as a JSON string passes through verbatim. The converter never decrypts or re-encrypts anything; encryption is Ansible's job via ansible-vault.
Frequently asked questions
How are JSON booleans mapped in Ansible YAML?
JSON true/false become unquoted YAML true/false — real booleans. Crucially, a JSON string "yes" becomes the quoted YAML string 'yes', NOT the boolean true. Ansible reads YAML 1.1, where bare yes/no/on/off are booleans, so the quoting is what keeps your intended strings as strings. Set the JSON type correctly and the YAML follows.
Why was my long shell command folded across lines?
A single-line string longer than 80 columns is wrapped with a folded block scalar (>-). The folded text reconstructs to the exact original string, so the command runs identically. If you want a true multi-line literal block (|-), put real newlines in the JSON string instead of one long line.
Does it add when, loop, notify, or tags for me?
No. Those are Ansible-specific keys that don't exist in source JSON, and the converter never invents fields. Add when, loop/with_items, notify, tags, become, and register by hand to the converted YAML.
Can I use this for dynamic inventory output?
Yes. A dynamic-inventory script's --list output is JSON; convert it to YAML to review it or freeze it as a static inventory file for local testing without re-running the script. Keys like _meta are quoted on output to stay valid, and Ansible reads them back correctly.
Which indent should I use for playbook tasks?
Indent 2. It gives the compact - name: sequence style Ansible authors use. Indent 4 puts the dash on its own line with the task body indented beneath — valid YAML but not idiomatic, and some ansible-lint indentation rules flag it.
Is inventory data, including hostnames and credentials, sent to JAD Apps?
No. Conversion runs entirely in your browser using js-yaml. Inventory host data, variable values, vault-referenced secret names, and internal hostnames never reach a JAD Apps server. The only server-side record when signed in is an anonymous run counter, with no content.
Will a top-level JSON array become a bare task list?
Yes. A top-level JSON array converts to a top-level YAML sequence with - items and no wrapper key — exactly the shape a tasks: block or list inventory expects. A top-level object becomes a YAML mapping.
How do I get a literal multi-line block (|) instead of folded (>-)?
Embed real newline characters in the JSON string value ("line1\nline2"). js-yaml emits multi-line strings as a literal block scalar (|-). A single long line without newlines folds with >-. The behaviour is driven by the content, not a UI toggle.
Can I merge several JSON var files into one group_vars file?
Convert each separately, or merge the JSON first with json-object-merger and convert the merged result. Alternatively, keep them as separate YAML files — Ansible layers group_vars and host_vars for you at runtime.
Does sort-keys help or hurt for Ansible?
It hurts for task lists (it can push name: below the module key) but helps for flat variable files where alphabetical order makes values easy to find. It's off by default; turn it on only for tidy group_vars/host_vars.
What's the file size limit?
Free tier accepts files up to 2 MB; Pro raises it to 100 MB. The tool takes a dropped .json file — there is no paste box. 2 MB comfortably covers most variable files and task lists; large dynamic-inventory dumps may need Pro.
Can I verify the YAML matches the source JSON?
Yes. Convert the YAML back to JSON with yaml-to-json and compare with json-diff. A clean diff confirms the round-trip preserved every value (key order aside if you used sort-keys).
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.