I am trying to create a .ssh folder and then add id_rsa and known_hosts file into the .ssh folder in a windows 2016 server. This folder needs to get into any user who runs puppet manually(or as a service). To make this work I have written a custom fact $::user_profile_directory that figures the home directory (%userprofile%). The method works completely fine for all users except when puppet runs as a service.
When puppet runs as a service it creates the .ssh folder inside "c:/windows/system32/config/systemprofile" folder, but does not create the files in the created .ssh folder folder(id_rsa file known_hosts file). This does not happen if run the puppet service as any other user.
Puppet also does not show any errors in the logs and instead says the content was changed to specific md5 sum hash. But the .ssh folder does not contain any of the files if I go and check manually using the explorer.
Also if I place the files manually into the c:/windows/system32/config/systemprofile/.ssh folder it corrects the permissions on the files. I don't understand, if it's able to correct the permissions on the files if present, then why is it not able to create files.
Here is my simple puppet code:
$user_home = $::user_profile_directory
file { "${user_home}/.ssh":
ensure => 'directory',
#owner => $user_name,
group => 'Administrators',
mode => '0700'
} ->
file { "${user_home}/.ssh/id_rsa":
ensure => 'file',
content => hiera('vester::vester_private_key'),
#owner => $user_name,
group => 'Administrators',
mode => '0600'
} ->
file { "${user_home}/.ssh/known_hosts":
ensure => 'file',
source => 'puppet:///modules/vester/known_hosts',
source_permissions => 'ignore',
#owner => $user_name,
#group => 'Administrators',
#mode => '0660'
}
when puppet runs as service:
${user_home} is c:/windows/system32/config/systemprofile
when puppet runs as other user (let's say vagrant):
${user_home} is c:/users/vagrant
Facter code that generates the $::user_home fact:
Facter.add('user_profile_directory') do
confine :osfamily => :windows
setcode do
ENV['USERPROFILE']
end
end
EDIT 1: Just figured, I am able to create folders but not able to create files in any of the folders/subfolders under "C:/windows/system32". How can I create files in a custom folder under system32 using puppet.?
EDIT 2: JUST figured, even though $::user_profile_directory is returning
c:/windows/system32/config/systemprofile
all my files are getting placed under
c:/windows/syswow64/config/systemprofile
Puppet 32 bit client was installed on my 64 bit Windows 2016 Server.
The files were actually getting created, but instead of
c:/windows/system32/config/systemprofile/.ssh
the files were created inside
c:/windows/syswow64/config/systemprofile/.ssh
folder by my puppet client.
The %windir%\System32 directory is reserved for 64-bit applications on 64-bit Windows. Most DLL file names were not changed when 64-bit versions of the DLLs were created, so 32-bit versions of the DLLs are stored in a different directory. WOW64 hides this difference by using a file system redirector.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, %windir%\lastgood\system32, or `%windir%\regedit.exe, the access is redirected to an architecture-specific path.
It's weird since, even though files are created in c:/windows/syswow64/config/systemprofile/.ssh folder, the puppet logs in the event viewer were showing that files were being successfully created inside the c:/windows/system32/config/systemprofile/.ssh. This happened because puppet 32 bit clients are unaware of the secret redirection in windows.
The fix for me was to just remove the 32 bit puppet client and install back the 64 bit puppet client since one of my puppet-modules(puppetlabs/vsrepo) was trying to access the knownhost file from c:/windows/system32/config/systemprofile/.ssh folder as it was using 64 bit git.exe client in background.
More about the WOW64 secret redirection in Microsoft documentation here
Related
Can someone please help me with the open source puppet?
I want to provide a jar file to a windows client and execute the .jar file with the command line.
The .jar file is actually an update for an application which is running as a service.
I am poorly familiar with the puppet language but would guess something like this to execute the jar file:
exec { 'jar_execution':
command => 'cmd.exe /c java -jar foo.jar',
}
Should this be part of the manifest which could look like this?
service { 'fooservice':
name => foo_service,
ensure => running,
enable => true,
}
file { 'foo.jar':
path => 'C:/foo/temp/foo.jar',
ensure => file,
source => "puppet:///modules/foo/foo.jar",
}
exec { 'jar_execution':
command => 'cmd.exe /c java -jar C:/foor/temp/foo.jar',
}
And how does the agent actually run this command?
There are few architectural considerations:
Use archive resource (from archive module) instead of: file with your .jar in your module's .git history.
Have all artifacts (e.g. binary files) served by another service like Apache Archiva, Nexus or Artifactory or even Puppet Server itself. If the .jar is not developed by your company, you may want to use the authoritative source with maybe some internal caching.
Name your resources in a way that are global to your whole infrastructure, otherwise you may have events that notify themselves and produce undesired outcome.
Order of resources in puppet doesn't matter. You want to order the resources the way it makes sense to you and use the before, after, require, notify to ensure dependency.
I would recommend having binaries files outside of a module, as binaries are not supposed to be versioned. You would probably have another service that can serve files, or even your puppet infrastructure can provide those packages, in the similar way it provides the puppet-agent itself, regardless if you use Puppet OSS or Puppet Enterprise.
archive { 'C:/foo/temp/foo.jar':
source => https://location/to/your/.jar,
}
exec { 'C:/foo/temp/foo.jar': # notice in resource name recommended to use / not \
command => 'cmd.exe /c java -jar C:/foor/temp/foo.jar',
refreshonly => true # this one executes exec only if the file was re-downloaded (maybe it's signature has changed), or the file was removed from disk and was re-downloaded.
onlyif => 'test -f C:\foo\temp\foo.jar' # or some command that guards you to not run this .jar every time you run puppet
subscribe => Archive['C:/foo/temp/foo.jar'],
notify => Service['foo_service'] # most probably you need to restart the service after you ran the .jar, otherwise you wouldn't have added in your question.
}
service { 'foo_service':
ensure => running,
enable => true,
}
I notice that in your example you don't need to remove your .jar after being executed. In case you need that, another exec command can remove the file downloaded in the same
I have the following flyway.pp Puppet class which installs Flyway onto Windows machines. It copies two files into the installation folder.
class rehan::flyway {
package { 'flyway':
ensure => latest,
provider => chocolatey
}
file { 'C:/Program Files/flyway/ntlmauth.dll':
ensure => 'file',
source => 'puppet:///modules/rehan/manifests/ntlmauth.dll',
}
file { 'C:/Program Files/flyway/drivers/sqljdbc4.jar':
ensure => 'file',
source => 'puppet:///modules/rehan/manifests/sqljdbc4.jar',
}
}
The above modules lives at modules/rehan/manifests/flyway.pp. I have placed the two files ntlmauth.dll and sqljdbc4.jar along side it but it seems a bit messy. Is there a standard directory or location where these files are normally placed? Also, how can I refer to these files using a relative path, I use puppet:///modules/rehan/manifests/ntlmauth.dll because I've seen it somewhere but that does not work.
This could be a bit confusing.
In your module's directory, you should have a subdirectory named 'files' and all files you want to be copied/installed somewhere need to be put there.
The confusing bit is that when addressing one of the objects stored there, you don't mention 'files' in the path!
So,
source => 'puppet:///modules/rehan/sqljdbc4.jar'
picks up the jar file from the following path:
/etc/puppet/modules/rehan/files/sqljdbc4.jar
The reason why puppet:///modules/rehan/manifests/ntlmauth.dll doesn't work is that it maps the path to /etc/puppet/modules/rehan/files/manifests/ntlmauth.dll which doesn't exist.
You can not reference an object located in your manifests directory using puppet:///
I have written manifest that installs an .exe and applies a hotfix to it every-time it installs on a new machine.
windowsinstaller { 'AppFabric install 1.1 install':
software_title => 'AppFabric 1.1 for Windows Server',
software_path => '/Microsoft/AppFabric1.1/WindowsServerAppFabricSetup_x64.exe',
install_options => ['/i','/SkipUpdates'],
}
windowsinstaller { 'AppFabric 1.1 HotFix install':
software_title => 'Windows Server AppFabric v1.1 CU5 [KB2932678]',
software_path => '/Microsoft/AppFabric1.1/AppFabric1.1-KB2932678-x64-ENU.exe',
install_options => ['/q','/norestart'],
subscribe => Windowsinstaller['AppFabric install 1.1 install']
}
service { 'Remote Registry Service':
name => 'RemoteRegistry',
ensure => running,
restart => true,
}
I am trying to get this install to run only if it's registry key is absent.
Using puppetlabs registry module you can manage keys, redirect them, and change the values.
reference: http://puppetlabs.com/blog/module-of-the-week-puppetlabs-registry-windows
Unfortunately, I can't seem to find a way to simply check if the key is there, I can either delete it or make sure its present using ensure => present and ensure => absent.
As I can't put resources into variables I am finding it hard to use conditional statements, and as present and absent set the key instead of check it, I don't think I can use meta parameters with the registry_key resource.
I know that I can wrap everything in an if statement and use a custom fact but I have been told that this is not the right way to proceed.
If anyone has an example of where this has been done before either using this module or something else registered in the puppet forge or any ideas it would be greatly appreciated.
The user manbart found the answer 7 months ago with this question
Exec onlyif registry value is not present
calling reg.exe to query the registry in an exec resource.
I need to alter permission on a existing file which was created during rpm installation. I use
file { '/usr/lib/hadoop-yarn/bin/container-executor':
ensure => present,
group => $hadoop::hadoop_group,
owner => 'root',
mode => 6050,
}
Quite often that is not the state founded after puppet run. I noticed that once the owner and group is changed, second time priviledges changed etc.
When I re-run the puppet apply than all is ok, permissions get changed. Nearly every time there is just one step, either changing permissions or owner+group. But to change it at once is very unusual in this case.
Does anybody has the same experience?
My OS is Linux CentOs
Thanks
I am currently working on puppet using Amazon Fedora EC2 instances. Both Puppet Server and Client are working fine. I am able to create certificate from client and server is able to sign that but still whatever code I have written in manifest files doesn’t get executed.
Below mentioned is my code in Site.pp file :
class test_class {
file { “/tmp/testfile”:
ensure => present,
mode => 644,
owner => root,
group => root
}
}
node puppetclient {
include test_class
}
Here, puppetclient is the hostname of client. But still after signing certificate /tmp/testfile doesn’t get created.
DNS is also working perfectly fine. I can ping puppetserver(named as puppet) from puppet client.
Can you please tell me what must be the possible mistake ??
It's probably just a typo in the question, but the default catalog file is 'site.pp', not 'Site.pp', so try it with 'site.pp' instead.