Hi All,
It’s been a long while since I posted last (as usual). It’s also been a long while since I started working for Puppet.
Until now, I haven’t really found much puppet things to blog about, but that’s about to change.
Lets start with something I ran into today. Custom Facts on Windows with Puppet!
Coincidentally, while working on something else, I dropped a fact into my facts.d folder and went on working on other things … only to bang my head against a wall for a few hours.
Custom facts are easy in Puppet!
“Custom facts are easy”, you say… “All I need to do is drop something like this on the OS”:
echo my_custom_fact=value123 > C:\ProgramData\PuppetLabs\facter\facts.d\my_custom_fact.txt
[Note: The code above is a single wrapped line]
… and you would be wrong. Like I was. That method works fine for posix based systems … but not for Windows (read on to learn why, and how to work around it).
Of course, I figured my fact was fine … it created the file and the file looked okay, so I went on trying to troubleshoot the other thing I was working on while getting this error when running the puppet agent (“puppet agent -t”) on my node:
What the hell does that mean? \xFF? …
File encoding types… ugh.
Well, after some google-fu, turns out that \xFF is one of the starting byte codes for a file encoding type …. ok, so it looks like a file encoding error.
So like a dumbass, I was checking all my other files and certificate properties, even rebuilt the VM a few (dozen) times (because that’s what I was working on when I hit this error)… not realizing all along it was the filetype of my custom fact that was causing this bullsh*t.
It turns out Puppet on Windows really doesn’t like things that aren’t UTF8 encoded… especially in facter …. and the error output is basically useless because it doesn’t point you in the direction of factor or the custom facts.d file at all.
That’s right, hours and many rebuilds of my VM because windows “echo >” in Windows decides to create files in “UCS-2 Little Endian” encoding … and Puppet (or well, more likely some of the ruby code in behind it for facter) can’t properly decode/re-encode Windows UCS-2 to UTF-8.
Okay, great … save the file in UTF8, and away we go…
BTW, You’ll need to run puppet agent twice to clear out the old, wrongly encoded fact from your master to get a clean run…
But…. Automation? Scripting?
Well … we can’t very well use the “echo something > facts.d/something.txt” method anymore …. so what’s the fix that I can use in an automated process?
Powershell to the rescue!
Here’s a way to do it that will create a proper UTF-8 file that Puppet/facter can read:
echo "my_custom_fact=value123" | out-file -filepath C:\ProgramData\PuppetLabs\facter\facts.d\my_custom_fact.txt -encoding UTF
[Note: The code above is a single wrapped line]
That’ll do it … of course, if you’re not working in powershell (or using a provisioning shell from vagrant like I am), then you just need to wrap it in a call to powershell like so (and make sure you escape your quotes properly using backticks and not single quotes!):
powershell -Command "echo `"my_custom_fact=value123`" | out-file -filepath C:\ProgramData\PuppetLabs\facter\facts.d\my_custom_fact.txt -encoding UTF8"
[Note: The code above is a single wrapped line]
Ok, That’s it … hours of figuring out WTF was happening so you don’t have to go through it yourself … hopefully google will pick this up for searches on ‘Puppet Windows “”\xFF”” errors’ and save you some time.
Until next time!
-Paul
Google did and you just saved me a few hours of work, you’re my hero of the day!
BTW, this also works and at least looks a bit more fancy:
Create the file:
Set-Content -Value “fact” -path C:\ProgramData\PuppetLabs\facter\facts.d\facts.txt -Encoding utf8
Add some additional facts if you want:
Add-Content -Value “fact2” -path C:\ProgramData\PuppetLabs\facter\facts.d\facts.txt