chef-infrachef-attributes

pass variables from a chef resouce to other resources in the same chef recipe


I'm new to Chef and Ruby, I'm very confused how to handle variables in Chef, and I am trying to pass a variable [Var] from ruby_block resource to http_request resource and assign the [Var] value to the value in "value":"#{Var}" in the chef recipe [customer.rb] as shown in the code below and I got an error.

[Var.js] is a json file and contains a round 100 lines of code. I want to pass the content of this file to a variable [Var] and call this variable to update some configuration of the website [http://localhost:6000/Master/endpoint_1_in/set]

        directory 'work' do
            owner 'root'
            group 'root'
            mode '0775'
            recursive true
            action :create
        end

        bash 'Extract customer Package' do
        cwd '/work'
        code <<-EOH
            curl -L --header "PRIVATE-TOKEN: XXXXXXXXXXXXXX" "https://www.company.sm/api/v4/projects/44/packages/generic/customer/1.0.0-customer/customer.tar.gz" > /work/customer.tar.gz
            tar xzf customer.tar.gz
            EOH
        end

        ruby_block 'Read customer file into Var variable' do
            block do
                if File.exists?("/work/customer/Var.js")
                    Var = IO.read("/work/customer/Var.js")
                end
            end
        end

        http_request 'cusromer update' do
            action :put
            url 'http://localhost:6000/Master/endpoint_1_in/set'
            message ({
                "moduleId" => "endpoint_1_in",
                "moduleType" => "ENDPOINT_1_IN",
                "options" => [
                    {
                        "key": "somename.text",
                        "value":"#{Var}" 
                    }
                ],
            }.to_json)
            headers({'Authorization' => "Basic #{basicauth}", 'Content-Type' => 'application/json;charset=utf-8' })

            retries 10
            retry_delay 30

        end

and the error I got is

        Installing cookbook gem dependencies:
            Compiling cookbooks...
            Loading Chef InSpec profile files:
            Loading Chef InSpec input files:
            Loading Chef InSpec waiver files:
            
            ================================================================================
            Recipe Compile Error in /tmp/kitchen/cache/cookbooks/clinic/recipes/customer.rb
            ================================================================================
            
            NameError
            ---------
            uninitialized constant #<Class:#<Chef::Recipe:0x0000000002bac870>>::Var
            
            Cookbook Trace: (most recent call first)
            ----------------------------------------
            
            Relevant File Content:
            ----------------------
            /tmp/kitchen/cache/cookbooks/clinic/recipes/customer.rb:
            
                64:      url 'http://localhost:6000/Master/endpoint_1_in/set'
                65:      message ({
                66:          "moduleId" => "endpoint_1_in",
                67:          "moduleType" => "ENDPOINT_1_IN",
                68:          "options" => [
                69:              {
                70:                  "key": "somename.text",
                71>>                 "value":"#{Var}" 
                72:              }
                73:          ],
                74:          
                75:      }.to_json)
            
            System Info:
            ------------
            chef_version=17.10.3
            platform=ubuntu
            platform_version=20.04
            ruby=ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]
            program_name=/opt/chef/bin/chef-client
            executable=/opt/chef/bin/chef-client
            
            
            Running handlers:
            [2022-05-13T16:25:57+00:00] ERROR: Running exception handlers
            Running handlers complete
            [2022-05-13T16:25:57+00:00] ERROR: Exception handlers complete
            Infra Phase failed. 0 resources updated in 02 seconds
            [2022-05-13T16:25:57+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
            [2022-05-13T16:25:57+00:00] FATAL: ---------------------------------------------------------------------------------------
            [2022-05-13T16:25:57+00:00] FATAL: PLEASE PROVIDE THE CONTENTS OF THE stacktrace.out FILE (above) IF YOU FILE A BUG REPORT
            [2022-05-13T16:25:57+00:00] FATAL: ---------------------------------------------------------------------------------------
            [2022-05-13T16:25:57+00:00] FATAL: NameError: uninitialized constant #<Class:#<Chef::Recipe:0x0000000002bac870>>::Var
        >>>>>> ------Exception-------
        >>>>>> Class: Kitchen::ActionFailed
        >>>>>> Message: 1 actions failed.
        >>>>>>     Converge failed on instance <default-ubuntu-2004>.  Please see .kitchen/logs/default-ubuntu-2004.log for more details
        >>>>>> ----------------------
        >>>>>> Please see .kitchen/logs/kitchen.log for more details
        >>>>>> Also try runn

I spent 2 weeks to solve it I could not. If there is workaround to do it, please help me.


Solution

  • Since you are running some Ruby code to get the file contents, you can even do it outside Chef resources. Something like:

    if File.exists?("/work/customer/Var.js")
      var = File.read("/work/customer/Var.js")
    end
    
    http_request 'cusromer update' do
      action :put
      # rest of code
    end
    

    Note that I've used var with lower case v.

    Explanation:

    The chef-client goes through several phases during the run. The two relevant for this answer are:

    All variable and resources are compiled and assignments happen in the compile phase. So var remains unassigned as there is no definition in for it in compile phase. Whereas ruby_block and http_request run in the converge phase.