Chef command are not working in Azure DevOps after installing ChefDK step in the pipeline

Has anyone experienced any issues when running chef commands in powershell step in the Azure DevOps build pipeline?
I have got a build pipeline in Azure DevOps with the first step is to install ChefDK, then the powershell step to execute some chef commands, especially "chef exec rspec" to run some ChefSpec tests. However, it keeps failing with

chef : The term 'chef' is not recognized as the name of a cmdlet, function, script file, or operable program. Check 
the spelling of the name, or if a path was included, verify that the path is correct and try again.

If you have just installed Chef on your build agent via another task then the subsequent PowerShell task will be inheriting the environment from the parent process that hasn't been reloaded to take into account the updated PATH.

As ChefDK will not be on your path and you will need to use the full path to the chef command in your PowerShell task (i.e. c:\opscode\chefdk\bin\chef.bat)

Thanks for your reply, it works but now I encounter another issue. At first, it threw error of failure to accept the Chef licence, so I added a powershell command to accept the licence but there is a bit of ugly hack here

c:\opscode\chefdk\bin\chef.bat exec --chef-license=accept

I had to run this command in order to accept the Chef licence. However, it did accept the licence, but threw the error afterwards about chef exec because according to the Chef documentation the right command to accept the Chef licence is "Chef --chef-license accept or setting an environment variable CHEF_LICENSE="accept". None of these worked and even threw errors.

+---------------------------------------------+
✔‌ 3 product licenses accepted.‌
+---------------------------------------------+
C:/opscode/chefdk/embedded/lib/ruby/gems/2.6.0/gems/chef-dk-4.0.67/lib/chef-dk/command/exec.rb:30:in `exec': No such file or directory - --chef-license=accept (Errno::ENOENT)
	from C:/opscode/chefdk/embedded/lib/ruby/gems/2.6.0/gems/chef-dk-4.0.67/lib/chef-dk/command/exec.rb:30:in `run'
	from C:/opscode/chefdk/embedded/lib/ruby/gems/2.6.0/gems/chef-dk-4.0.67/lib/chef-dk/command/base.rb:62:in `run_with_default_options'
	from C:/opscode/chefdk/embedded/lib/ruby/gems/2.6.0/gems/chef-dk-4.0.67/lib/chef-dk/cli.rb:73:in `run'
	from C:/opscode/chefdk/embedded/lib/ruby/gems/2.6.0/gems/chef-dk-4.0.67/bin/chef:25:in `<top (required)>'
	from C:/opscode/chefdk/bin/chef:333:in `load'
	from C:/opscode/chefdk/bin/chef:333:in `<main>'

Is there any other clean and better way to accept Chef licence in the pipeline either via powershell command or anything else? Thanks

If you're using Azure DevOps then the correct way to set an environment variable is to set a build variable (either in your YAML definition, or using the classic editor). This is then available to all all the tasks in your build. Have a read of: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables

Thanks Stuart, but setting a build variable is just another way to pass the value for the environment value in the powershell command when I tried to set the environment variable for the build agent as part of the pipeline.

I mean in the Chef build pipeline:

  • Install ChefDK step
  • Powershell step to set environment variable Env:CHEF_LICENSE = (CHEF_LICENSE)
  • Another powershell step to run ChefSpec test

but this will fail because Chef licence hasnt been accepted. Therefore, I dont think setting that environment variable to accept Chef licence worked. I had to do a hack here by running a powershell command before running the ChefSpec test

c:\opscode\chefdk\bin\chef.bat exec --chef-license=accept

This command will accept licence but at the same time it will also throw syntax error because exec does not have attribute --chef-licence. I got no idea how it works but with obviously a syntax error as I mentioned above in the thread. And I dont know whats the best way to accept Chef licence before executing any other Chef commands.
Thanks

In the page I referenced it says that "variables are also made available to scripts through environment variables". That means they are available to all processes that the build agent starts:

image

If you set an environment variable to the local scope in one PowerShell task using $env:VARIABLE="value" then that value will not be available to a second PowerShell task (or other Azure Pipelines task). You need to use the build variable as per the doc and then you can avoid the need to set the variable at a local scope.

In your azure-pipelines.yml

variables:
  CHEF_LICENSE: accept 

or in a legacy build pipeline:

image

If you add a PowerShell task to your build with a one liner to list all the environment variables:

dir env:

Then you will see evidence of the environment variable in your build output:

image

Stuart

1 Like

Thanks Stuart, it works.