### Puppet stuff * pdrun has different output than puppet agent; use both * or & and must be used instead of bitwise operators * resource types (files,packages,services) can be included/excluded within if/else constructs for specific os's, lsbdists, etc. * array types can be used as a $string; $packages = [....] / package { $packages : ensure => present }, etc. * when specifying a user and GID, make sure user and group are created in the manifest. * ENSURE should always be present despite puppet cheat sheet! * Conditionals can go within other conditionals (case statements) and module manifests "::blah" ## 2.7 Docs link http://docs.puppetlabs.com/puppet/2.7/reference/ http://docs.puppetlabs.com/references/2.7.latest/type.html (file, package) ## foreman and puppet * use class module::specific {..} to specific a "specific" init.pp file; class foo::bar references foo/manifests/bar.pp ## puppet language syntax stuff $var = assign a variable (string) $var = [ "blah", "blah", ] assign an array; trailing commas are allowed $var = { key => "value",} assign a hash; trailing commas are allowed * regex cannot be passed to functions or resource attributes * semicolons are used for attribute blocks (multiple resources) ## puppet references * Uses capitalized forms, e.g. File, Package, etc. * used within relationship parameters * when using with resources, primarily used to add/modify attributes ## Common resource parameters for file, package, service, and exec # file { "file": ... } * ensure => present (matches any form of file existance or creates a new empty file) * ensure => absent (deletes file/directory if recurse => true) * ensure => link (creates symlink); use with target => /path/ * ensure => directory (creates directory) * group, owner, mode (0644, or o=rw,g+rx) (self explanitory) * path => path to file; if ommited uses the resource title, e.g. file { "/etc/inetd.conf" * source => "puppet:///module_name/some_file.txt"; the "files" directory is always omitted; arrays can be used and first match found is used * content => template('module/somefile.erb'); loads "somefile.erb" from module/templates folder # service { "servicename": ... } * enable => "true|false|manual" (should a service be started at boot?) * ensure => "stopped or false|running or true" (should a service be running?) * hasrestart => "true|false" (specifies service has a restart function) * hasstatus => "true|false" (specifics service has a status function) # package { "package_name": ... } OR { [ "package1", "package2", ] : attribute => value; } * ensure => "(present|installed),absent,purged,latest,version#" (package install options) # exec { "command optons": ... } * path => ["/bin", "/sbin", ... ] (array of paths that exec uses) ### ERB templating w/ puppet * Facter values can be called directly, i.e. processorcount, etc.; use <%= processorcount %> * If using simple facter value in template, use if lsbmajdist * use if has_variable("name")? for facter/foreman parameters * check syntax with erb -P -x -T '-' template.erb | ruby -c * template texts (different configs for different facts) can just be text: <% if has_variable?("blah") -%> config_1 <% else -%> config_2 <% end -%> <% statement %> = ruby statements such as if, else, etc. <%= expression =%> = inserts value from expression; useful for printing values in loops <% -%> = trim mode (supresses leading whitespaces) * Test with facter within IRB via require 'facter' && access Facter['key'].value * call fact directly (facter -p) within puppet templates * regex must be enclosed in / / * use @blah/<%= blah %> to reference foreman parameters within templates * use $foreman_parameter to reference user parameter within manifest ## facts * host parameters can be placed in manifests & do not require templating * BUT they cannot be used in complex if statements: if $var == 1 or $var2 == 1 ## relationship Metaparameters: require, subscribe, notify, before * require => Type["..."] Guarantees source object is applied before "require" target object. * subscribe => Type["..."] Guarantees source object (exec/service) is refreshed/restarted if subscribed "Type" is changed (file/directory) * notify => Service['...'] (opposite of subscribe, creates dependency like 'before' and causes dependent object to refresh when changed) * before => Type['...'] Guarantees source object is applied before "before" target object (think yum repo before package install) ## relationships and ordering before = resource gets applied before target resource require = resource gets applied after target resource notify = resource gets applied before target, target resource then refreshes if notify source changes; use with file for service subscribe = resource gets applied after target, subscribe resource refreshes if target rource changes; use with service for file -> = causes resource on the left to get applied before the resource on the right ~> = causes resource on the left to be applied first and then refreshes the resource on the right ### cool stuff * use single lines for resource decs, file { "blah": source => blah, mode => blah } * Metaparameters can use arrays with mutiple dependencies; subscribe => [ File["one"], File["two"] ] * using files with arrays $array = [ "file", "file2", "file3" ] file { $array[0]: \n source => puppet://blah; } File [ $array ] { owner => ,etc.. } * using packages with arrays $packages = ['','',''] package { $packages : ensure => installed } * multiple require items require => [ File["/home/1"], File["/home/2"] ] #### refreshers Type { ["blah"] : parameter => } => #### Renew CA 1.) Backup current SSL on puppet server tar cvzf /root/puppet-ssl-backup.tar.gz /var/lib/puppet/ssl/ 2.) cd /var/lib/puppet/ssl/ca and verify ca_key.pem and ca_crt.pem have same MD5 sum openssl rsa -noout -modulus -in ca_key.pem 2> /dev/null | openssl md5 ; openssl x509 -noout -modulus -in ca_crt.pem 2> /dev/null | openssl md5 ) 3.) Generate new CSR from existing key and ca cert openssl x509 -x509toreq -in ca_crt.pem -signkey ca_key.pem -out ca_csr.pem 4.) Create SSL extension.cnf file cat > extension.cnf << EOF [CA_extensions] basicConstraints = critical,CA:TRUE nsComment = "Puppet Ruby/OpenSSL Internal Certificate" keyUsage = critical,keyCertSign,cRLSign subjectKeyIdentifier = hash EOF 5.) Backup old ca cert and generate new one from CSR; verify validity cp ca_crt.pem ca_crt.pem.old openssl x509 -req -days 3650 -in ca_csr.pem -signkey ca_key.pem -out ca_crt.pem -extfile extension.cnf -extensions CA_extensions openssl x509 -in ca_crt.pem -noout -text|grep -A 3 Validity 6.) Generate new CSR for puppet server with new CA cd /var/lib/puppet/ssl openssl x509 -x509toreq -in certs/$(hostname).pem -signkey private_keys/$(hostname).pem -out certificate_requests/$(hostname)_csr.pem 7.) Backup old puppet server certificate and create new with new CSR/CA combo cp certs/$(hostname).pem certs/$(hostname).pem.old openssl x509 -req -days 3650 -in certificate_requests/$(hostname)_csr.pem -CA ca/ca_crt.pem -CAkey ca/ca_key.pem -CAserial ca/serial -out certs/$(hostname).pem 8.) Verify MD5sums are the same openssl rsa -noout -modulus -in private_keys/$(hostname).pem 2> /dev/null | openssl md5 ; openssl x509 -noout -modulus -in certs/$(hostname).pem 2> /dev/null | openssl md5 9.) Restart Apache systemctl restart httpd.service 10.) Sign new certificate request for host (may not be required if certificate hasn't expired yet) puppet cert sign --all On clients need to: 1.) rm -rf /var/lib/puppet/ssl/ on client 2.) rm -rf /var/lib/puppet/ssl/ca/HOST on server OR 1.) mv /var/lib/puppet/ssl/ca.pem /var/lib/puppet/ssl/ca.pem.old 2.) cp NEW ca.pem to /var/lib/puppet/ssl/ca.pem