===== Puppet ===== The Learning VM TUtorial is here: https://kjhenner.gitbooks.io/puppet-quest-guide/content/quests/application_orchestrator.html Te learning VM is available here: https://puppet.com/download-learning-vm ==== Glossary ==== |Resources | Describing node configuration works by declaring resources. Server provides the descriptions of relevant resources to the nodes then. Resource may describe * a single file * a package * a service daemons * a maintenance tasks Abstract declaration of a resource "user" user { 'root': ensure => 'present', comment => 'root', gid => '0', home => '/root', password => '$1$PrY3W9V8$JTfCFGrmJ7tl7VwgXga14.', password_max_age => '99999', password_min_age => '0', shell => '/bin/bash', uid => '0', } | |Classes | The class is the next level of abstraction above a resource. \\ Groups the resources. \\ Groups other classes. Class may describe * describe entire system role as "database-server", "web application worker" * some abstract aspect as "cloud-tools", which is composed of many tools To **define** a class - means to describe it in a module, so that it can be used on nodes. \\ To **declare** a class - means to apply the class to a node. So it will execute there and do its modifications, defined in the .pp file. Achtung: you only can apply a clas once to a node. So if you wish to use the same peace of code with ifferent parameters (e.g. create multiple users, folders...) use defined resource types | | defined resource types | like classes, but appliable to nodes multiple times | |node definition | The task of configuring which classes will be applied to a given node - is called **node classification**. \\ Node definitions are a puppet concept to write node classification down. | |.pp manifests| Puppet language files. Rules * Must use UTF8 encoding * May use Unix (LF) or Windows (CRLF) line breaks (note that the line break format also affects literal line breaks in strings) | |Modules| A Puppet module is a self-contained bundle of all the Puppet code and other data needed to manage some aspect of your configuration. \\ You can download pre-built modules from the [[https://forge.puppet.com/|Puppet Forge]] or you can write your own modules. | |Puppet master | The puppet server which configures the puppet agents| |Puppet agent| Installed on machines, which should be controlled by puppet (by puppet master)| ==== Commands ==== | puppet module search | Search module| | puppet module install -v 5.16.1 | Install module| | puppet agent --test \\ puppet agent -t| manually trigger puppet agent run. \\ Puppet run is the check for new configurations. \\ It usually occurs every 30 Minutes automatically| | puppet resource user root | check user root as resource | | puppet describe user | describe resource "user". Especially available attributes. | | puppet apply -e "user { 'galatea': ensure => present, }" | Createa resource user | | puppet apply --noop -e "user | --noop allows to try out what would be if your would do that on the node | | puppet resource -e user galatea | Modify resourece user in VIM. (**ESC i** is editing. **:wq** is quit and save.) | | puppet resource package fortune-mod ensure=absent \\ puppet resource package cowsay ensure=absent provider=gem | Uninstall a package resource from node | |puppet master --configprint all \\ puppet config print graphdir |print configs| |puppet module list|print module list| |tree -L 2 -d /etc/puppetlabs/code/environments/production/modules/| Print the modules as a tree, and only modules from one location, limiting modules to 2 levels âââ cowsayings â   âââ examples â   âââ manifests âââ graphite â   âââ manifests â   âââ spec â   âââ templates âââ vsftpd âââ examples âââ manifests âââ templates âââ tests | ==== Class example in modules ==== == definition == Class **definition** - description of the class. Done before association with nodes. # /etc/puppetlabs/code/environments/production/modules/cowsayings/manifests/cowsay.pp class cowsayings::cowsay { package { 'cowsay': ensure => present, provider => 'gem', } } # /etc/puppetlabs/code/environments/production/modules/cowsayings/manifests/fortune.pp class cowsayings::fortune { package { 'fortune-mod': ensure => present, } } # /etc/puppetlabs/code/environments/production/modules/cowsayings/manifests/init.pp class cowsayings { include cowsaying::cowsay include cowsaying::fortune } Pefix **cowsayings** is the name of the module in this case. Default path **manifests/init.pp** contains the default module's manifest **manifests/init.pp**. It contains the name of the module. == declaration == Class **declaration** of a class "cowsay" on a node. # /etc/puppetlabs/code/environments/production/modules/cowsayings/examples/cowsay.pp include cowsayings::cowsay Class **declaration** of a parent class "cowsayings" on a node. \\ Parent class "cowsayings" includes both of them # /etc/puppetlabs/code/environments/production/modules/cowsayings/examples/init.pp include cowsayings == Apply == Apply the class "cowsay" on the node puppet apply /etc/puppetlabs/code/environments/production/modules/cowsayings/examples/cowsay.pp Apply the parent class "cowsayings" on the node, which would install both subclasses "cowsay", "fortune" puppet apply /etc/puppetlabs/code/environments/production/modules/cowsayings/examples/init.pp == Parameterized class include == You can pass some parameters, when including external classes. \\ Here instead of writing **include poodle** and so accepting the defaults, we define the **$ensure to be true**. example of **NO parametrized** poodle class include node 'beetle.example.com' { include basicstuff include poodle } example of **parametrized** poodle class include \\ Here **NO INCLUDE-keyword** was used. node 'beetle.example.com' { include basicstuff class { 'poodle': $ensure => 'stopped' } } ==== Defined Resource types ==== * Use **define** keyword instead of **class** * **$title** is a special variable, which must be unique on a node and is mandatory * Binding of parameter variables ($content, $password) to values happens in parallel, meaning that you cannot use the value of one parameter to set another. The exception is the $title variable. # /etc/puppetlabs/code/environments/production/modules/web_user/manifests/user.pp define web_user::user ( $content = "

Welcome to ${title}'s home page!

", $password = undef, ) { $home_dir = "/home/${title}" $public_html = "${home_dir}/public_html" user { $title: ensure => present, password => $password, } file { [$home_dir, $public_html]: ensure => directory, owner => $title, group => $title, mode => '0755', } file { "${public_html}/index.html": ensure => file, owner => $title, group => $title, replace => false, content => $content, mode => '0644', } }
**Declaration** of users on a node. \\ 'shelob', 'frodo' are the titles of the users, which may be references via the **$title** variable # /etc/puppetlabs/code/environments/production/modules/web_user/examples/user.pp web_user::user { 'shelob': } web_user::user { 'frodo': content => 'Custom Content!', password => pw_hash('sting', 'SHA-512', 'mysalt'), } ==== Classes Metaparameter ==== Defines relationships between resources. == before / required== Define the ordering of reources, in which they have to be installed SSH config File required package "openssh-server" file { '/etc/ssh/sshd_config': ensure => present, source => 'puppet:///modules/sshd/sshd_config', require => Package['openssh-server'], }
Package "openssh-server" must be installed, before service "sshd" \\ **before** turns the requirenments around package { 'openssh-server': ensure => present, before => Service['sshd'], } You can generate a graph, to check resource dependencies # generate the dependency graph puppet apply sshd/examples/init.pp --noop --graph # check where the .dot graphs are going to puppet config print graphdir #generate a png dot -Tpng /opt/puppetlabs/puppet/cache/state/graphs/relationships.dot -o /var/www/quest/relationships.png ==== Files ==== You can distribute files via puppet. \\ Files under modules "files" dir are made available via puppet URL and may be used in class definitions. == Add File to module == To create a module, which will distribute a config file do: \\ add the config files to **/etc/puppetlabs/code/environments/production/modules/vimrc/files/vimrc** == Create file distributing class == Creating a **class vimrc** to distribute file "vimrc" class vimrc { file { '/root/.vimrc': ensure => present, source => 'puppet:///modules/vimrc/vimrc', } } The URL to file in puppet-module has the form puppet://{server hostname (optional)}/{mount point}/{remainder of path} |server hostname|the name of the puppet server. Can omit that, when referencing the default server.| |mount point|Where are the files? \\ **modules** is a shortcut, to the folders with puppet modules| |remainder of path|Module name **vimrc**. \\ All files are always under **files** dir, so omit that. \\ **vimrc** is the name of the file. | So path becomes ^File^URL^ | /etc/puppetlabs/code/environments/production/modules/vimrc/files/vimrc | puppet:///modules/vimrc/vimrc | Make sure that puppet has **the rights** to change the file chown pe-puppet:pe-puppet /etc/puppetlabs/code/environments/production/modules/vimrc/files/vimrc == Apply == Create as usual a **init.pp** with **include vimrc**. Install by puppet apply vimrc/examples/init.pp ==== Default node definition ==== Manifest **site.pp** \\ in /etc/puppetlabs/code/environments/production/manifests/site.pp \\ defines the default node configuration. ==== Node setup ==== Puppet master provides a bash script for setting up nodes: curl -k https://:8140/packages/current/install.bash | sudo bash Puppet MASTER keeps signed certificates of each Node, which is a part of the infrastructure. To involve a node - sighn its certificate. List all unsigned certificates of Nodes. Executable on master. puppet cert list Sign a certificate of node named **webserver.learning.puppetlabs.vm ** puppet cert sign webserver.learning.puppetlabs.vm ==== Variables ==== Definition $doc_root = '/var/www/quest/' Access "${doc_root}hello.html" class web { $doc_root = '/var/www/quest/' $english = 'Hello world!' $french = 'Bonjour le monde!' file { "${doc_root}hello.html": ensure => present, content => "${english}", } file { "${doc_root}bonjour.html": ensure => present, content => "${french}", } } ==== Facts ==== Global variables, available via **facter** or in code (like variables). Output facts facter -p | less facter operatingsystem Syntax to access facts in code $::factname class accounts ($user_name) { if $::operatingsystem == 'centos' { $groups = 'wheel' } elsif $::operatingsystem == 'debian' { $groups = 'admin' } else { fail( "This module doesn't support ${::operatingsystem}." ) } notice ( "Groups for user ${user_name} set to ${groups}" ) ... } Apply manifest, with modified facts, via prefix: FACTER_factname=new_value Example FACTER_operatingsystem=Debian puppet apply --noop accounts/examples/init.pp ==== Class parameters ==== **Define** a class, with parameters, which can be modifed later on. class classname ( $parameter = 'default' ) { ... } class web ( $page_name="title", $message="message" ) { **Declare** (include on a node) a class, with parameters. \\ Fill them with values. class {'classname': parameter => 'value', } class {'web': page_name => 'hola', message => 'Hola mundo!', } ==== Puppet master (server) Configurations ==== You can retrieve ALL puppet configurations by executing puppet master --configprint all Or just single lines by doing puppet master --configprint agent_catalog_run_lockfile puppet master --configprint agent_disabled_lockfile ... puppet master --configprint modulepath ... Example configuration agent_catalog_run_lockfile = /opt/puppetlabs/puppet/cache/state/agent_catalog_run.lock agent_disabled_lockfile = /opt/puppetlabs/puppet/cache/state/agent_disabled.lock allow_duplicate_certs = false always_cache_features = true app_management = true archive_file_server = learning.puppetlabs.vm archive_files = true autoflush = true autosign = /etc/puppetlabs/puppet/autosign.conf basemodulepath = /etc/puppetlabs/code/modules:/opt/puppetlabs/puppet/modules bindaddress = 0.0.0.0 binder_config = bucketdir = /opt/puppetlabs/puppet/cache/bucket ca = true ca_name = Puppet CA: learning.puppetlabs.vm ca_port = 8140 ca_server = learning.puppetlabs.vm ca_ttl = 157680000 cacert = /etc/puppetlabs/puppet/ssl/ca/ca_crt.pem cacrl = /etc/puppetlabs/puppet/ssl/ca/ca_crl.pem cadir = /etc/puppetlabs/puppet/ssl/ca cakey = /etc/puppetlabs/puppet/ssl/ca/ca_key.pem capass = /etc/puppetlabs/puppet/ssl/ca/private/ca.pass caprivatedir = /etc/puppetlabs/puppet/ssl/ca/private capub = /etc/puppetlabs/puppet/ssl/ca/ca_pub.pem catalog_cache_terminus = store_configs catalog_terminus = compiler cert_inventory = /etc/puppetlabs/puppet/ssl/ca/inventory.txt certdir = /etc/puppetlabs/puppet/ssl/certs certificate_revocation = true certname = learning.puppetlabs.vm cfacter = false classfile = /opt/puppetlabs/puppet/cache/state/classes.txt client_datadir = /opt/puppetlabs/puppet/cache/client_data clientbucketdir = /opt/puppetlabs/puppet/cache/clientbucket clientyamldir = /opt/puppetlabs/puppet/cache/client_yaml code = "" codedir = /etc/puppetlabs/code color = ansi confdir = /etc/puppetlabs/puppet config = /etc/puppetlabs/puppet/puppet.conf config_file_name = puppet.conf config_version = "" configprint = all configtimeout = 120 csr_attributes = /etc/puppetlabs/puppet/csr_attributes.yaml csrdir = /etc/puppetlabs/puppet/ssl/ca/requests daemonize = true data_binding_terminus = hiera default_file_terminus = rest default_manifest = ./manifests default_schedules = true deviceconfig = /etc/puppetlabs/puppet/device.conf devicedir = /opt/puppetlabs/puppet/cache/devices diff = diff diff_args = -u digest_algorithm = md5 disable_per_environment_manifest = false disable_warnings = ["deprecations"] dns_alt_names = "" document_all = false environment = production environment_data_provider = none environment_timeout = 0 environmentpath = /etc/puppetlabs/code/environments evaltrace = false external_nodes = none factpath = /opt/puppetlabs/puppet/cache/lib/facter:/opt/puppetlabs/puppet/cache/facts facts_terminus = yaml fileserverconfig = /etc/puppetlabs/puppet/fileserver.conf filetimeout = 15 forge_authorization = freeze_main = false genconfig = false genmanifest = false graph = false graphdir = /opt/puppetlabs/puppet/cache/state/graphs group = pe-puppet hiera_config = /etc/puppetlabs/code/hiera.yaml hostcert = /etc/puppetlabs/puppet/ssl/certs/learning.puppetlabs.vm.pem hostcrl = /etc/puppetlabs/puppet/ssl/crl.pem hostcsr = /etc/puppetlabs/puppet/ssl/csr_learning.puppetlabs.vm.pem hostprivkey = /etc/puppetlabs/puppet/ssl/private_keys/learning.puppetlabs.vm.pem hostpubkey = /etc/puppetlabs/puppet/ssl/public_keys/learning.puppetlabs.vm.pem http_connect_timeout = 120 http_debug = false http_keepalive_timeout = 4 http_proxy_host = none http_proxy_password = none http_proxy_port = 3128 http_proxy_user = none http_read_timeout = ignorecache = false ignoremissingtypes = false ignoreschedules = false keylength = 4096 lastrunfile = /opt/puppetlabs/puppet/cache/state/last_run_summary.yaml lastrunreport = /opt/puppetlabs/puppet/cache/state/last_run_report.yaml ldapattrs = all ldapbase = "" ldapclassattrs = puppetclass ldapparentattr = parentnode ldappassword = "" ldapport = 389 ldapserver = ldap ldapssl = false ldapstackedattrs = puppetvar ldapstring = (&(objectclass=puppetClient)(cn=%s)) ldaptls = false ldapuser = "" libdir = /opt/puppetlabs/puppet/cache/lib localcacert = /etc/puppetlabs/puppet/ssl/certs/ca.pem log_level = notice logdir = /var/log/puppetlabs/puppet manage_internal_file_permissions = true manifest = /etc/puppetlabs/code/environments/production/manifests masterhttplog = /var/log/puppetlabs/puppet/masterhttp.log masterport = 8140 max_deprecations = 10 max_errors = 10 max_warnings = 10 maximum_uid = 4294967290 mkusers = false module_groups = base+pe_only module_repository = https://forgeapi.puppetlabs.com module_skeleton_dir = /opt/puppetlabs/puppet/cache/puppet-module/skeleton module_working_dir = /opt/puppetlabs/puppet/cache/puppet-module modulepath = /etc/puppetlabs/code/environments/production/modules:/etc/puppetlabs/code/modules:/opt/puppetlabs/puppet/modules name = master node_cache_terminus = write_only_yaml node_name = cert node_name_fact = "" node_name_value = learning.puppetlabs.vm node_terminus = classifier noop = false onetime = false ordering = manifest passfile = /etc/puppetlabs/puppet/ssl/private/password path = none pidfile = /var/run/puppetlabs/master.pid plugindest = /opt/puppetlabs/puppet/cache/lib pluginfactdest = /opt/puppetlabs/puppet/cache/facts.d pluginfactsource = puppet:///pluginfacts pluginsignore = .svn CVS .git pluginsource = puppet:///plugins pluginsync = true postrun_command = "" preferred_serialization_format = pson prerun_command = "" preview_outputdir = /opt/puppetlabs/puppet/cache/preview priority = privatedir = /etc/puppetlabs/puppet/ssl/private privatekeydir = /etc/puppetlabs/puppet/ssl/private_keys profile = false publickeydir = /etc/puppetlabs/puppet/ssl/public_keys puppetdlog = /var/log/puppetlabs/puppet/puppetd.log report = true report_port = 8140 report_server = learning.puppetlabs.vm reportdir = /opt/puppetlabs/puppet/cache/reports reports = puppetdb reporturl = http://localhost:3000/reports/upload req_bits = 4096 requestdir = /etc/puppetlabs/puppet/ssl/certificate_requests resourcefile = /opt/puppetlabs/puppet/cache/state/resources.txt rest_authconfig = /etc/puppetlabs/puppet/auth.conf route_file = /etc/puppetlabs/puppet/routes.yaml rundir = /var/run/puppetlabs runinterval = 1800 serial = /etc/puppetlabs/puppet/ssl/ca/serial server = learning.puppetlabs.vm server_datadir = /opt/puppetlabs/puppet/cache/server_data show_diff = false signeddir = /etc/puppetlabs/puppet/ssl/ca/signed skip_tags = "" splay = false splaylimit = 1800 srv_domain = puppetlabs.vm ssl_client_ca_auth = ssl_client_header = HTTP_X_CLIENT_DN ssl_client_verify_header = HTTP_X_CLIENT_VERIFY ssl_server_ca_auth = ssldir = /etc/puppetlabs/puppet/ssl statedir = /opt/puppetlabs/puppet/cache/state statefile = /opt/puppetlabs/puppet/cache/state/state.yaml static_catalogs = true storeconfigs = true storeconfigs_backend = puppetdb strict_environment_mode = false strict_hostname_checking = false strict_variables = false summarize = false supported_checksum_types = ["md5", "sha256"] syslogfacility = daemon tags = "" trace = false trusted_oid_mapping_file = /etc/puppetlabs/puppet/custom_trusted_oid_mapping.yaml trusted_server_facts = false use_cached_catalog = false use_srv_records = false usecacheonfailure = true user = pe-puppet vardir = /opt/puppetlabs/puppet/cache waitforcert = 120 yamldir = /opt/puppetlabs/puppet/cache/yaml ===== Orchestration ===== Details are here: https://kjhenner.gitbooks.io/puppet-quest-guide/content/quests/application_orchestrator.html Orchestration allows to install dependent applications in the right order. It works as following: - setup the node to know the orchestrator - create an Application, which may combine multiple nodes to a single semantical unit (MySQL Server, Apache with PHP application ) - setup orchestrator user with the rights - setup an **artificial, public resource** to share the data between nodes (**in ruby**) - define, which node **produces** data to fill artificial, public resource. Which node consumes data from artificial, public resource. - declare the resource - in site.pp declare - which part of the application will be installed on which node. {{http://i520.photobucket.com/albums/w327/schajtan/2016-04-25_14-27-49_zpsphhbuy9w.png}}