<p>I'd go with <a href="https://docs.chef.io/recipes.html#node-run-state" rel="nofollow noreferrer"><code>node.run_state</code></a> to store a transient variable in a run and define it in a <a href="https://docs.chef.io/resource_ruby_block.html" rel="nofollow noreferrer"><code>ruby_block</code></a> so it happens at converge time, something like this:</p>

<pre><code>yum_package 'somepackage'

ruby_block 'set myvar' do
  block do
    node.run_state['my_var'] = Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip
  end
end
</code></pre>

<p>As far as I know requiring 'mixlib/shellout' is not necessary.</p>

CC BY-SA 3.0
2017-09-26T08:24:58.670Z
2017-09-26T08:24:58.670Z
Tensibai
<p>The specifics depend on the exact use case. If the value is only used as a property on another resource, you would use the <code>lazy</code> helper method. If you don't need the output, you would use the <code>execute</code> resource. In some more complex cases you might use a <code>ruby_block</code> resource or write your own custom resource.</p>

CC BY-SA 3.0
2017-09-25T05:28:35.847Z
2017-09-25T05:28:35.847Z
coderanger
<p>Let us say I have some Chef code like:</p>

<pre><code>require 'mixlib/shellout'
yum_package 'somepackage'
myvar =  Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip
</code></pre>

<p>Where <code>/bin/somecommand</code> does not exist yet because it is installed by <code>somepackage</code>. This will fail at recipe compile time for that reason, but will obviously work at convergence time providing the package installs successfully (and if it doesn't then obviously the recipe has failed anyway). This also fails if the package is installed be a previous recipe in the runlist since they are all compiled together upfront. How do I include things in a Chef recipe that that recipe or runlist installs itself?</p>

CC BY-SA 3.0
2017-09-24T13:24:25.967Z
This sort of thing isn't a problem in CFEngine
Gaius
CC BY-SA 3.0
2017-09-25T08:30:02.610Z
Without insight on the use of `myvar` there's no real answer, usually I avoid using code evaluation from external commands at compile time unless very necessary to define other resources. In brief, I'd do a `ruby_block 'set myvar' { node.run_state['myvar'] = Mixlib::ShellOut.[...] }`
Tensibai
CC BY-SA 3.0
2017-09-25T19:24:15.917Z
@Tensibai `node.run_state` was exactly what I was looking for - thanks. Make that an answer and I'll accept it!
Gaius
CC BY-SA 3.0
2017-09-25T19:30:03.093Z
That will have to wait until tomorrow :) too hard to write a correct answer on phone
Tensibai
<chef><configuration-management><infrastructure-as-code>
How to Chef things that don't exist yet
Gaius
# How to Chef things that don't exist yet

(Asked by: username_0 on 2017-09-24)

Let us say I have some Chef code like:
require 'mixlib/shellout'
yum_package 'somepackage'
myvar =  Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip

Where /bin/somecommand does not exist yet because it is installed by somepackage. This will fail at recipe compile time for that reason, but will obviously work at convergence time providing the package installs successfully (and if it doesn't then obviously the recipe has failed anyway). This also fails if the package is installed be a previous recipe in the runlist since they are all compiled together upfront. How do I include things in a Chef recipe that that recipe or runlist installs itself?

**Tags:** chef, configuration-management, infrastructure-as-code

> **Comments:**
> **username_0**: This sort of thing isn't a problem in CFEngine  
> **username_1**: Without insight on the use of `myvar` there's no real answer, usually I avoid using code evaluation from external commands at compile time unless very necessary to define other resources. In brief, I'd do a `ruby_block 'set myvar' { node.run_state['myvar'] = Mixlib::ShellOut.[...] }`  
> **username_0**: @username_1 `node.run_state` was exactly what I was looking for - thanks. Make that an answer and I'll accept it!  
> **username_1**: That will have to wait until tomorrow :) too hard to write a correct answer on phone  

---

## 2 answers

### Answer by username_1 on 2017-09-26. Score: 4 | Accepted answer

I'd go with node.run_state to store a transient variable in a run and define it in a ruby_block so it happens at converge time, something like this:
yum_package 'somepackage'

ruby_block 'set myvar' do
  block do
    node.run_state['my_var'] = Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip
  end
end

As far as I know requiring 'mixlib/shellout' is not necessary.


---

### Answer by username_2 on 2017-09-25. Score: 2

The specifics depend on the exact use case. If the value is only used as a property on another resource, you would use the `lazy` helper method. If you don't need the output, you would use the `execute` resource. In some more complex cases you might use a `ruby_block` resource or write your own custom resource.


---

