6

I have a chef recipe where I want to take all of the attributes under node['cfn']['environment'] and write them to a yml file. I could do something like this (it works fine):

content = {
  "environment_class" => node['cfn']['environment']['environment_class'],
  "node_id" => node['cfn']['environment']['node_id'],
  "reporting_prefix" => node['cfn']['environment']['reporting_prefix'],
  "cfn_signal_url" => node['cfn']['environment']['signal_url']
}

yml_string = YAML::dump(content)

file "/etc/configuration/environment/platform.yml" do
  mode 0644
  action :create
  content "#{yml_string}"
end

But I don't like that I have to explicitly list out the names of the attributes. If later I add a new attributes it would be nice if it automatically was included in the written out yml file. So I tried something like this:

yml_string = node['cfn']['environment'].to_yaml

But because the node is actually a Mash, I get a platform.yml file like this (it contains a lot of unexpected nesting that I don't want):

--- !ruby/object:Chef::Node::Attribute
normal:
  tags: []
  cfn:
    environment: &25793640
      reporting_prefix: Platform2
      signal_url: https://cloudformation-waitcondition-us-east-1.s3.amazonaws.com/...
      environment_class: Dev
      node_id: i-908adf9
...

But what I want is this:

----
reporting_prefix: Platform2
signal_url: https://cloudformation-waitcondition-us-east-1.s3.amazonaws.com/...
environment_class: Dev
node_id: i-908adf9

How can I achieve the desired yml output w/o explicitly listing the attributes by name?

2 Answers 2

6

This will do the trick:

yml_string = YAML::dump(node['cfn']['environment'].to_hash)
1
1

This also works and better ruby style:

yml_string = node['cfn']['environment'].to_hash.to_yaml

2
  • note: this won't work with empty hashes
    – spuder
    Oct 12, 2017 at 17:57
  • Why not? >> {}.to_hash.to_yaml => "--- {}\n"
    – sekrett
    Oct 16, 2017 at 14:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .