dropdown menu

DEVOPS - PUPPET SYNTAX

Syntax recommendations in general:

- Donʼt forget commas and colons. (Forgetting them causes parsing errors.)
- The resource type and the attribute names should always be lowercase.
- The values used for titles and attribute values will usually be strings, which you should usually quote. 
- There are two kinds of quotes in Puppet: single (') and double ("). Double quotes let you interpolate $variables.
- Attribute names (like path, ensure, etc.) are special keywords, not strings. They shouldnʼt be quoted.
- It is recommended visually lining up the => arrows, because it makes it easier to understand a manifest at a glance.
- Puppet disallows duplicate titles within a given type (you canʼt declare the same resource twice)

=========================================

Variables:

$my_variable='A bunch of text'
notify{$my_variable:}

Variables can hold strings, numbers, booleans, arrays, hashes, and the special undef value. If youʼve never assigned a variable, you can actually still use it - its value will be undef. Always include curly braces ({}) around variable names when referring to them in strings, for example, as follows:
$value = "${one}${two} is the new value"
source => "puppet:///modules/webserver/${brand}.conf",

notify { "operatingsystem is ${::operatingsystem}": }     <--printing out variables


Variable scope:
Each class and definition introduces a new scope, and there is also a top scope for everything defined outside of those structures. Variables cannot be redefined inside the same scope they were defined in. (Puppet does not rely on order or sequence of the code, so redefining a variable (changing a value) would cause problem, because puppet does not know which definition is the first.)

Top scope is anything declared in site.pp or imported manifests. Top scope can be explicitly accessed by prepending :: to a variable. It is best practice to write fact variables as $::osfamily so as to use the fact at top scope, thus preventing the variable from being overwritten anywhere.

Local scope is the scope of a single class or defined type.

If you reference a variable with its short name and it isnʼt present in the local scope, Puppet will also check the global top scope, so short name is most of the cases works well.
$variable                short variable name
$scope::variable         fully qualified variable name, e.g. name => $::ssh::params::ssh_package_name (the variable $ssh_package_name can be found in ssh::params class)
$::variable              top scope variable name

All of the facts from facter can be referenced as top scope variables, e.g. the fully qualified domain name (FQDN) of the node may be referenced by "${::fqdn}". For the highest level scope, top scope or global, use two colons (::) at the beginning of a variable identifier: ${::fqdn} (:: is like / root)

file { '/etc/motd':
 content => "Welcome to ${::fqdn}\n"
}

People who write manifests often adopt the habit of always using the $::variable notation when referring to facts. As mentioned above, the double-colon prefix specifies that a given variable should be found at top scope. This isnʼt actually necessary, since variable lookup will always reach top scope anyway.

=========================================

Quotes, Regular expressions

Always quote parameter values that are not reserved words in Puppet. For example, the following values are not reserved words:
name => 'dave',
mode => '0700',
owner => 'root',

However, these values are reserved words and therefore not quoted:
enable => true,
ensure => running,


Regular expressions:
if $::architecture =~ /64/ {    <--the text between the slashes to be matched (like grep 64)
if $::kernel !~ /Linux/ {       <--if the text does not match

Ruby's regular expression syntax at this website: http://www.tutorialspoint.com/ruby/ruby_regular_expressions.htm

===========================

If condition

An example code for if condition, which could be run with puppet apply:
$color = 'blue'

if $color == 'blue' {
  notify {"it is blue":}
}
else {
  notify {"it is not blue":}
}

----------------------------------------------

if $::timezone == 'UTC' {
if $::timezone != 'UTC' {
if $::uptime_days > 365 {
if $::mtu_eth0 <= 1500 {
if ($::uptime_days > 365) and ($::kernel == 'Linux') {
Boolean expressions: or, and 
if $crewmember in ['Frank', 'Dave', 'HAL' ]

----------------------------------------------

The condition for an if statement has to resolve to a boolean true/false value. However, all facts are strings, and all non-empty strings — including the string "false" — are true. This means that facts that are “false” need to be transformed before Puppet will treat them as false.

In this case, weʼre using the str2bool function. Surrounding the variable with double quotes — if it contained an actual boolean for some reason (and it usually wouldnʼt), this would convert it to a string. Passing the string to the str2bool function, which converts a string that looks like a boolean into a real true or false value:

if str2bool("$is_virtual") {
  notify {"it is true":}
}
else {
  notify {"it is false":}
}

The str2boolfunction is part of the puppetlabs/stdlib module, which is included with Puppet Enterprise. If you are running open source Puppet, you can install it by running: 
sudo puppet module install puppetlabs/stdlib

===========================

Case condition

case $operatingsystem {
  centos: { $apache = "httpd" }
  redhat: { $apache = "httpd" }
  debian: { $apache = "apache2" }
  default: { fail("Unrecognized operating system for webserver") }
}
package{'apache':
  name   => $apache,
  ensure => latest,
}

(The above used fail function doesnʼt resolve to a value; instead, it fails compilation immediately with an error message.)

----------------------------------------------
Another example wit regex:
case $ipaddress_eth0 {
  /^127[\d.]+$/: {
    notify{'misconfig':
      message=>"Possible network misconfiguration: IP address of $0",
    }
  }
}

Regex matches also assign captured subpatterns to $1, $2, etc. inside the associated code block, with $0 containing the whole matching string.
----------------------------------------------
===========================

Array:

Adding square brackets [] around a list:
package { [ 'package1', 'package2', 'package3' ]: ensure => installed }     <--  array (specify many items in a  single resource)

or…

$packages = [ 'ruby1.8-dev',
 'ruby1.8',
 'ri1.8',
 'libopenssl-ruby' ]

package { $packages: ensure => installed }

===========================

Hash:

A hash is like an array, but each of the elements can be stored and looked up by name (referred to as the key), for example (hash.pp):

$interface = {
 'name' => 'eth0',
 'ip' => '192.168.0.1',
 'mac' => '52:54:00:4a:60:07'
}

notify { "(${interface['ip']}) at ${interface['mac']} on
 ${interface['name']}": }

===========================

Selector:

$lunch = 'Filet mignon.'
$lunchtype = $lunch ? {
 /fries/ => 'unhealthy',
 /salad/ => 'healthy',
 default => 'unknown',
}
notify { "Your lunch was ${lunchtype}": }

===========================

Loops

Most commonly an array is used to repeat a test with different values.

$packages = ['vim', 'git', 'curl']  

package { $packages: 
   ensure => "installed" 

===========================

No comments: