spuder
spuder

Reputation: 18467

How do you create pretty json in CHEF (ruby)

How would you make an erb template that has human readable json?

The following code works, but it makes a flat json file

default.rb

default['foo']['bar'] = { :herp => 'true', :derp => 42 }

recipe.rb

template "foo.json" do
  source 'foo.json.erb'
  variables :settings => node['foo']['bar'].to_json
  action :create
end

foo.json.erb

<%= @settings %>

Similar SO questions
Chef and ruby templates - how to loop though key value pairs?
How can I "pretty" format my JSON output in Ruby on Rails?

Upvotes: 7

Views: 8400

Answers (3)

<%= Chef::JSONCompat.to_json_pretty(@settings) %> Works like Charm !!

Upvotes: 0

spuder
spuder

Reputation: 18467

As pointed out by this SO Answer .erb templates are great for HTML, and XML, but is not good for json.

Luckily, CHEF uses its own json library which has support for this using .to_json_pretty

@coderanger in IRC, pointed out that you can use this library right inside the recipe. This article shows more extensively how to use chef helpers in recipes.

default.rb

# if ['foo']['bar'] is null, to_json_pretty() will error
default['foo']['bar'] = {}

recipe/foo.rb

pretty_settings = Chef::JSONCompat.to_json_pretty(node['foo']['bar'])

template "foo.json" do
  source 'foo.json.erb'
  variables :settings => pretty_settings
  action :create
end

Or more concise as pointed out by YMMV

default.rb

# if ['foo']['bar'] is null, to_json_pretty() will error
default['foo']['bar'] = {}

recipe/foo.rb

template "foo.json" do
  source 'foo.json.erb'
  variables :settings => node['foo']['bar']
  action :create
end

templates/foo.json.erb

<%= Chef::JSONCompat.to_json_pretty(@settings) %>

Upvotes: 9

sandstrom
sandstrom

Reputation: 15112

Something like this would also work:

file "/var/my-file.json" do
  content Chef::JSONCompat.to_json_pretty(node['foo']['bar'].to_hash)
end

Upvotes: 6

Related Questions