Escape characters in Ruby ( and therefore in Chef) start with a backslash. Nothing wrong with that.But it will mess up your paths when you are working on windows – because in the windows world our paths are made out of backslashes ( a nice article on the history or back slashes in windows can be found here.
Online sources and docs point you towards helpers and functions to fix this. However in my experience the best way to deal with this is just escaping them properly. And since Windows has no issues with double backslashes instead of single back slashes you could – as a precaution – just use double back slashes in all your attribute assignments.
This does mean however that an UNC path needs double escaping, e.g. \\someserver\somepath. More about UNC paths and fileshares later.
2. Thou Powershall not
Chef supports Powershell.
Or well actually it provides you with a couple of ways to run powershell from a recipe. Powershell_script will create a temporary script on the file system and run that and Powershell_out actually starts a powershell process and runs the code you provide.
However is important to realize that while you can use recipe variables such as node attributes in your powershell script – you can’t actually pass back the objects powershell returns. Powershell_script just returns the exit code and powershell_out captures all return data – but in a string – which is perfectly suitable for error handling or reporting but it denies you access to one of the big advantages of powershell, the fact that you can gather all sorts of information about your environment and use that in your script’s decision making logic without having to parse the ouput and put it into some sort of data structure.
Par example – there is no really added value to using the AD cmdlets over plain old dsquery because if you want to use data it returns you’ll have to parse the returned strings with some sort of fancy regex and what not. And in all honesty powershell is much slower then most cmdline based tools – especially when they are RPC rather then WMI based.
This is by no means a design flaw or anything – the whole idea behind Chef is that when you start a run you already have the necessary environment data, either from Ohai or from loading up your defined resources.
So either use equivalent ruby code or fall back to the old cmdline binaries ( where I personally prefer using ruby code )
3. Execution Context
This in itself has actually very little to do with Chef. If you want to run something on a box you’ll need to do that under some sort of security context which determines what you can and what you cannot do. Before you get access to that context you will need to authenticate.
If you want to automate a whole set of systems there you really two things you can do :
1. Run commands and execute them remotely on a system with some sort of network shell ( an example could be running a powershell remoting session from an admin machine to a set of target machines).
2. Use a service or a scheduled task to run tasks locally on each machine.
Chef and quite a few other config management tools use the second option. And this works really well if you only need to change things on that particular node. You can just use the Local System account – no password needed and it has all the permissions you might need. No it no suprise that this is the account the chef-client uses to do it’s regular runs.
But what if you’d need to change a setting outside of the node/machine? Like creating a DNS entry, or a SPN or use the template resource on a CIFS\SMB Share? The local system account ( even though it has some permissions when the machine is domain joined – such as being a member authenticated users) cannot access either of these resources. And what further complicates this is, is that in the “chef world” – testing and development is generally done by running chef with some sort of “real user” ( either the person logged on the machine or the vagrant user when you are using vagrant). So you won’t notice that you have a problem until you actually deploy your cookbook.
There are three ways to solve this :
1. Use chef_shellout in your recipes.It supports running a commmand as another user( basically what it does is spawn a process). Or when you are dealing with network shares, use the mount provider. It allows you to mount a share as another user as well. All actions you perform after mounting the share will executed as that user. Even though it might seem tempting to use shell_out to call Powershell remember that at the moment this has very little added value.
The powershell_out mixin btw strangly enough has no option to run as another user (yet).
2. To the outside world ( inside your domain anyway) – the Local System account will perform actions outside of the host as the AD computer account. So if you try to reach a share from Chef on let’s say windowsbox1 while Chef-client is running as the local system account ( which is the default and as far as I’ve seen the only recommended configuration) you will see a logon request from contoso\windowsbox1. You could of course just grant this machine account permission to your share ( either directly our through some group). This may sound crazy – but there are other situations were this is perfectly normal ( such as Microsoft Clustering, Kerberos constrained delegation in TMG,SCCM and some part of MS Exchange).
One caveat : you really have to have a working Kerberos authentication setup – because authenticating as a computer account won’t work over NTLM.
3. Bypass the windows security context all together. Easier said then done most of the time but some of the infrastructures services actually have a network interface or API ( LDAP, SharePoint). This will enable you to define a bind account or authenticate through web services and only for that specific task or service.
And there might be a fourth – running chef-client under a service account. I haven’t really seen anyone do this though.
In my next post I will try to the pro’s and con’s of these three approaches and show a simple and easy way to simulate this real world limitation when you are developing your cookbooks.