7

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?

1
  • If your erb is just a single <%= @something %> you'd be better off using the file resource. Commented Jul 31, 2015 at 14:13

3 Answers 3

9

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) %>
Sign up to request clarification or add additional context in comments.

1 Comment

You should also be able to do this in your erb template: <%= Chef::JSONCompat.to_json_pretty(@settings) %>. I kind of like that because it turns the responsibility of the format of the string into the view logic in the template. YMMV.
6

Something like this would also work:

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.