Puppeteers Blog

Lisää läskiä työnkulkuun, osa 4: Roolit ja profiilit

February 1, 2018 

Mikäli hallintarepon, r10k:n ja GitLab:in sisältävä työnkulku tuntuu vielä liian kevyeltä, on läskiä ja abstraktiotasoja lisättävissä onneksi toisaalla, nimittäin itse Puppet-moduuleissa. Pelastuksen tarjoaa ns. "Roles and Profiles pattern", jonka kehitti alunperin Craig Dunn, ja joka löi läpi todennäköisesti Gary Larizzan blogikirjoitusten myötä. Alla käytämme englanninkielisen termin sijaan lähes suomenkielistä termiä "roolit ja profiilit".

Roolit ja profiilit ovat aivan tavallisia Puppet-luokkia. Ne eivät ole kuitenkaan ole Gary Larizzan termiä käyttäen ns. komponenttimoduuleja, jotka on suunniteltu jonkin yksittäisen asian tekoon, ja jotka olisivat siten (ainakin periaatteessa) jaettavissa muiden käyttäjien kesken esim. Puppet Forgessa.

Profiilien tarkoitus on kasata suurehko kasa toiminnallisuutta, esimerkiksi jokin "Technology Stack" yhteen. Hyvä esimerkki on vaikkapa jokin verkkosovellus, jonka asennus vaatii verkkopalvelimen (nginx, apache), tietokantapalvelimen (postgresql, mysql) ja monen muun asian laittamista kuntoon. Tällaisen sovelluksen konfiguraatiot voisi toki toteuttaa myös "tavallisella" Puppet-moduulilla, mutta moduulin uudelleenkäytettävyys olisi varsin rajattua kahdesta syystä:

  • Mitä enemmän liikkuvia osia, sitä useammalla tavalla niitä voi yhdistellä, eikä täsmälleen samaa yhdistelmää halua kovin moni henkilö.
  • Jos kaikki liikkuvat osat yritetään pakottaa samaan yleiskäyttöiseen moduuliin, tulee moduulista helposti äärimmäisen monimutkainen ja siten hauras.

Tässä tulevat apuun profiilit, joita ei ole tarkoitettukaan yleiskäyttöisiksi, vaan lähinnä korvaamaan luokkien ja niiden kaikkien parametrien määrittely suoraan Hierassa. Toisin sanoen profiililla kasataan komponenttimoduuleista toimivia kokonaisuuksia. Parametrit poimitaan profiili-luokassa suoraan Hierasta lookup-funktiolla.

Alla esimerkki yksinkertaisesta profiilista, jolla konfiguroidaan tyypillisen *NIX-palvelimen perusasetukset:

#
 # == Class: profile::unixbase
 #
 # *NIX-tyyppisten koneiden yleiset asetukset eräässä ympäristössä
 #
 class profile::unixbase {
 
 # Oletussähköpostiosoite, jota monet moduulit käyttävät
 $email = lookup('default_email')
 
 # Sisäverkon osoite ja verkkomaski, esimerkiksi muotoa
 # 10.95.5.0/24
 $intranet = lookup('intranet')
 
 # Puppet-palvelimen osoite
 $puppet_server = lookup('puppet_server')
 
 # Luokat ja määritetyt resurssit
 include ::bash
 bash::config::user { 'samuli':
 ensure => 'present',
 }
 include ::localbackups
 class { '::locales':
 locales => [ 'en_US.UTF-8 UTF-8',
 'fi_FI.UTF-8 UTF-8',
 'it_IT.UTF-8 UTF-8', ]
 }
 include ::localusers
 class { '::mdns':
 allow_ipv4_address => $intranet,
 }
 include ::nano
 class { '::ntp':
 ensure => 'running',
 ntp_pools => [ '0.fi.pool.ntp.org',
 '1.fi.pool.ntp.org',
 '2.fi.pool.ntp.org', ]
 }
 include ::postfix
 class { '::puppetagent':
 master => $puppet_server,
 }
 class { '::puppetagent::cron':
 splaylimit => '10m',
 email => $email,
 }
 include ::ssh
 class { '::sshd':
 passwordauthentication => 'yes',
 permitrootlogin => 'without-password',
 }
 include ::systemd
 class { '::timezone':
 timezone => 'Europe/Helsinki',
 }
 class { '::updater':
 hour => 13,
 minute => 5,
 weekday => '*',
 install => 'yes',
 mailon => 'error',
 }
 }

Yllä olevasta profiilista näkee helposti yleisellä tasolla mihin järjestelmän konfiguraatioihin se koskee. Ylhäällä haetaan muutama "globaali" parametri Hierasta ja käytetään niitä luokkien parametreina. Lookup-funktio kutsut tehdään heti profiilin alussa, jotta profiilin käyttämät parametrit näkyvät helposti yhdestä paikasta sen sijaan, että ne olisi ripoteltu pitkin profiilia.

Parametrien hausta lookup-kutsulla on hyötyä tietyn tyyppisten arvojen kanssa:

  • Useissa kertoja mahdollisesti eri profiileissa toistuvat arvot kuten IP-osoitteet, verkkoalueet ja sähköpostiosoitteet: lookupilla voidaan varmistua siitä, ettei profiileihin jää vanhentuneita, kovakoodattuja arvoja.
  • Arvot, joita joudutaan muuttamaan Hieran eri tasoilla (esim. käyttöjärjestelmä- tai noodikohtaisesti.

Muissa tapauksissa parametrien arvot voi turvallisesti kirjoittaa suoraan profiilin luokkakutsuihin, jolloin pelkästään profiilia katsomalla saa varsin hyvän käsityksen mitä se tekee.

Se, miksi profiileja ei tehdä parametrisoiduiksi luokiksi vaan käytetään "maagisia" Hiera-lookuppeja ei ole ainakaan minulle täysin selvää: täytyyhän profiilin tarvitsemat parametrit joka tapauksessa lisätä Hieraan. Muutama etu ei-parametrisoiduista profiileista kuitenkin on:

  • Saman profiilin voi lisätä ("include") useita kertoja. Tästä on hyötyä silloin, jos jollain noodilla on useita rooleja (ks.alla), jotka sisältävät saman profiilin. Parametrisoidulla profiililla tuloksena olisi Puppet-ajon epäonnistuminen.
  • Hieran lookup()-funktion asetuksien säädöistä (esim. "merge behavior" ja oletusarvot) voi olla tietyissä tapauksissa oikeaa hyötyä.

Roolit ovat vielä korkeamman tason abstraktiotasolla ja niissä kasataan yhteen ainoastaan profiileja:

#
 # == Class: role::webserver
 #
 class role::webserver {
 include ::profile::unixbase
 include ::profile::nginx
 }

Noodin yaml-tiedoston tiedostoon tarvitsee tämän jälkeen lisätä vain yksi rivi, jotta koneesta saadaan rakennettua webbipalvelin:

classes:
 - role::webserver

Rooleissa ja profiileissa on siis pohjimmiltaan kyse entistä suurempien, ainakin organisaation sisällä uudelleenkäytettävien Puppet-luokkien luomisesta sen sijaan, että pienistä komponenttimoduuleista kasattaisiin toimivia, suuren määrän parametreja ja luokkia sisältäviä kokonaisuuksia Hieran noodikohtaisissa yaml-tiedostoissa.

Artikkelisarjan muut osat:

Samuli Seppänen
Samuli Seppänen
Author archive
menucross-circle