Platform Independent Manifest to install and run apache2 or httpd - puppet

I need to write a single manifest as install-apache.pp that will install
apache2 package if it is Debian based system or
httpd package if it is RedHat based system
Below is the code; this works in CentOS but does not work in Ubuntu.
case $facts['os']['name'] {
'Debian': {
package { 'apache2':
ensure => installed,
}
service { 'apache2':
ensure => running,
}
}
'RedHat': {
package { 'httpd' :
ensure => installed,
}
service { 'httpd':
ensure => running,
}
}
}
So I made some changes as below, but am not sure why it is not working.
case $operatingsystem {
'Debian': {
package { 'apache2':
ensure => installed,
} ->
service { 'apache2':
ensure => running,
enable => true,
}
}
'RedHat': {
package { 'httpd' :
ensure => installed,
} ->
service { 'httpd':
ensure => running,
enable => true,
}
}
}
Command used to execute:
puppet apply install-apache.pp --logdest /root/output.log

The problem here is that you are making use of the fact $facts['os']['name'] which is assigned the specific operating system of the distribution and not the family of the distribution. That fact will be assigned Ubuntu on Ubuntu and not Debian. The fact needs to be fixed to $facts['os']['family'], which will be assigned Debian on Ubuntu.
You can also make use of selectors to improve this a bit more in addition to the fix. It is also recommended to construct a dependency of the service on the package in that manifest to ensure proper ordering. Refreshing would also be helpful.
With those fixes and improvements in mind, your final manifest would look like:
$web_service = $facts['os']['family'] ? {
'RedHat' => 'httpd',
'Debian' => 'apache2',
default => fail('Unsupported operating system.'),
}
package { $web_service:
ensure => installed,
}
~> service { $web_service:
ensure => running,
enable => true,
}

Related

Nodejs Error: spawn git ENOENT when using simple-git to clone repo

I am building an app that clones a repo, parses xml files in the repo and displays the information. I am using the simple-git npm module. I have this working on my local system, and on the dev test server. I am trying to deploy it to an integration server and this is the error I get. Some of the stuff I have seen says it is because the directory I'm attempting to clone to doesn't exist, but it most definitely does.
Here is the code I wrote to either clone the repo if it doesn't exists or pull pull the latest changes. This is a method of a class. this.path is the path to the directory the repo will be cloned to. this.repoRoot is the path to the root of the repo on the local system. this.remote is the url for the remote.
/**
* gets the latest version of the remote repo and specified branch by either using clone or pull
* #return {Promise<void>}
*/
getLatest() {
return new Promise((resolve, reject) => {
this.checkForDir(this.path).then((parentDirExists) => {
if (!parentDirExists) {
fs.mkdirSync(this.path);
}
}).then(() => {
this.checkForDir(this.repoRoot).then((repoExistsLocally) => {
if (!repoExistsLocally) {
git(this.path).clone(this.remote).then((cloneResult) => {
git(this.repoRoot).checkout(this.branch).then(() => {
resolve();
});
});
}
else {
git(this.repoRoot).pull().then((pullResult) => {
resolve();
});
}
})
})
})
}
Thanks in advance for any help!
As it turns out, the problem was related to permissions the account the server was running on. The account did not have permissions to write to the directory it was attempting to write to.

puppet code deleted a file, instead of replacing

I am having issues with puppet modules, and this modules should replace /etc/ssh/sshd_config file based on Redhat version. So the issue is, after applying the code, puppet deleted the file, instead of replacing it.
someone please suggest any wrong with my code.
here is the my puppet manifest file;
class os_vul_ssh {
case $::operatingsystemmajrelease {
'6':{$sshconfigfile = 'sshd_config.rhel6'}
'7':{$sshconfigfile = 'sshd_config.rhel7'}
}
package { "openssh-server":
ensure => installed,
}
service { 'sshd':
ensure => "running",
enable => true,
require => Package["openssh-server"],
}
file { "/etc/ssh/sshd_config":
owner => root,
group => root,
mode => '0644',
source => "puppet:///modules/os_vul/${::sshconfigfile}",
require => Package["openssh-server"],
notify => Service["sshd"],
}
}
file { "/etc/ssh/sshd_config":
ensure => file, <----- this is missing
owner => root,
group => root,
mode => '0644',
source => "puppet:///modules/os_vul/${::sshconfigfile}",
require => Package["openssh-server"],
notify => Service["sshd"],
}
Might be more going on here, but this is the first issue that jumps out at me.
By the way, you can cleanup your code with this:
file { "/etc/ssh/sshd_config":
ensure => file,
owner => root,
group => root,
mode => '0644',
source => "puppet:///modules/os_vul/sshd_config.rhel${::operatingsystemmajrelease}",
require => Package["openssh-server"],
notify => Service["sshd"],
}
and if you are using Facter 3 then consider changing your fact to:
$facts['operatingsystemmajrelease']
and note that your sshconfigfile is a local variable and should be included in your file resource as a local variable $sshconfigfile and not global $::sshconfigfile.

Run custom services on startup with puppet

I'm migrating our old process of doing our linux configurations to be managed by puppet but I'm having issues trying to figure out how to do this. We add some custom scripts to the init.d folder on our systems to manage some processes, and then these need this command executed on them to launch on startup:
update-rc.d $file defaults
So what I'm doing with puppet is that I have all these scripts residing a directory, and I copy them over to init.d. I then want to call 'exec' on each of these files with the former command and use the file name as an argument. This is what I have so far:
#copy init files
file { '/etc/init.d/':
ensure => 'directory',
recurse => 'remote',
source => ["puppet:///files/init_files/"],
mode => 755,
notify => Exec[echo],
}
exec { "echo":
command => "update-rc.d $file defaults",
cwd => "/tmp", #directory to execute from
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:",
refreshonly => true
}
This will copy all the files and it calls exec when something is added/updated, but what I can't figure out is how to pass the name of the file as an argument into the exec command. It seems I'm really close but I just can't find anything to help with what I need to do. Is this the right way to try and achieve this?
Thanks.
Your probably not going to accomplish that if your using ensure => 'directory'. You will want to declare the file resource for each individual init script. And the exec isn't the way to go to enable a service. Use the service resource.
file { '/etc/init.d':
ensure => 'directory',
mode => '0755'
}
file { '/etc/init.d/init_script_1':
ensure => 'present',
owner => 'root',
group => 'root',
mode => '0755',
notify => Service['init_script_1']
}
file { '/etc/init.d/init_script_2':
ensure => 'present',
owner => 'root',
group => 'root',
mode => '0755',
notify => Service['init_script_2']
}
service { 'init_script_1':
ensure => running,
enable => true
}
service { 'init_script_2':
ensure => running,
enable => true
}
Hope this helps.

Puppet: Found 1 dependency cycle

I am getting this error when applying my Puppet manifest:
Error: Could not apply complete catalog: Found 1 dependency cycle:
(Exec[pip install requirements] => File[change venv permissions] => File[enforce MinGW compiler] => Exec[pip install requirements])
Try the '--graph' option and opening the resulting '.dot' file in OmniGraffle or GraphViz
Here is my Puppet manifest (the relevant part) and I don't see any dependency cycle there. Any ideas?
exec {'create virtualenv':
command => "$install_dir/Scripts/virtualenv.exe venv",
cwd => $project_dir,
require => Exec['install virtualenv'],
}
file { "fix Mingw32CCompiler":
path => "C:/Python27/Lib/distutils/cygwinccompiler.py",
content => template($cygwinc_template),
ensure => present,
require => Exec['create virtualenv'],
}
file { "enforce MinGW compiler":
path => "$project_dir/venv/Lib/distutils/distutils.cfg",
owner => $user,
content => $mingw,
ensure => present,
require => File['fix Mingw32CCompiler'],
}
exec {'pip install requirements':
timeout => 1200,
command => "$project_dir/venv/Scripts/pip.exe install -r $project_dir/requirements.txt",
require => File['enforce MinGW compiler'],
}
file {'change venv permissions':
path => "$project_dir/venv",
recurse => true,
owner => $user,
mode => 0770,
require => Exec['pip install requirements'],
}
In puppet files have an implicit require for any parent directories that are declared.
Effectively:
File['change venv permissions'] -> File['enforce MinGW compiler']
So the parent requires the exec, the exec requires the child, and the child requires the parent, creating a loop.
What was your last change (that's probably the moment you added the cycle).
Try the suggestion to generate the graph. Post the generated dot file as gist so that we can investigate further.
Take a look at Debugging cycle or missing dependency.

Puppet notify service error

I try to write a puppet configuration in order to install lamp env.
But i have an issue with notify option.
I have an apache conf:
class apache inherits apache::params {
package { 'apache':
name => "${apache::params::package}",
ensure => present
}
service { 'apache':
ensure => running,
name => $apache::params::service,
enable => true,
subscribe => Package['apache'],
}
}
and and php module conf:
define php::module(
$notify = $php::params::notify,
$package_prefix = $php::params::module_package_prefix
) {
package { "php-module-${name}":
ensure => present,
name => "${package_prefix}${name}",
notify => Service['apache'],
require => [Class['apache'], Package['php', 'php-dev']]
}
}
but when I launch puppet I have this error:
Error: Parameter notify failed on Php::Module[mcrypt]: No title provided and "apache" is not a valid resource reference
I don't understand why it said that apache service is not a valid resources ?
I think there might be 2 issues here:
1) Puppet doesn't like this line in php::module:
$notify = $php::params::notify,
Can you try to remove that or check what is in $php::params::notify? (I don't see you using it)
2) Did you have something like
include apache
in your site.pp? The class still needs to be declared before you can reference the contained resources.

Resources