3. Puppet

Todo

sprawdzić czy działają tematy związane z tworzeniem faktów

Todo

sprawdzić jak zachowa się to z Facter

Todo

sprawdzić deklarowanie i używanie zmiennych

Todo

podzielić Puppet na osobne pliki per temat (zadanie do rozwiązania)

Todo

co z tematem odpalania jako user a nie root?

Todo

uspójnić wszędzie nazwy userów i grup (vagrant, ubuntu, www-data, myuser) wybrać jeden

Todo

błąd ze sprawdzaniem czy user i grupa www-data istnieją, kiedy wykorzystujemy moduł apache

3.1. Architektura

  • zasada działania

  • infrastructure as a code

  • ad hoc changes

  • scaling

  • wprowadzanie zmian w zależności od faktów

  • developer env changes

  • instalacja ręczna pakietów

3.1.1. Jak działa

manifest.pp

file { '/var/www':
    ensure => 'directory',
    owner => 'www-data',
    group => 'www-data',
    mode  => '0755',
}
exec { 'package definition update':
    command => '/usr/bin/apt update',
}

package { ['nmap', 'htop', 'git']:
    ensure => 'latest',
    require => Exec['package definition update'],
}

3.1.2. Model

  • klient server

  • standalone - puppet apply

  • fakty i kolejność wykonywania manifestów

3.1.3. Components

  • manifests (pliki z rozszerzeniem .pp)

  • zmienne

  • classes

  • resources

  • facts

3.1.4. Puppet language

  • DSL

  • ruby

  • ERB templates

3.2. Templates

  • ERB templates

3.2.1. Comment

<%# This is a comment. %>

3.2.2. Variables

There are two ways to access variables in an ERB template:

@variable
scope['variable']

Example:

scope['ntp::tinker']

3.2.3. Printing variables

ServerName <%= @fqdn %>
ServerAlias <%= @hostname %>

3.2.4. If

if <CONDITION>
  ... code ...
elsif <CONDITION>
  ... other code ...
end
<% if @broadcast != "NONE" %>
    broadcast <%= @broadcast %>
<% end %>

3.2.5. For

<% @values.each do |val| -%>
    Some stuff with <%= val %>
<% end -%>

If $values was set to [‘one’, ‘two’], this example would produce:

Some stuff with one
Some stuff with two

3.3. Instalacja i konfiguracja

sudo apt update
sudo apt install puppet

Zaglądnij do katalogu /etc/puppet. Co się tam znajduje?

Jeżeli nie ma katalogu /etc/puppet/manifests to go stwórz.

mkdir -p /etc/puppet/manifests

Przejdź do katalogu /etc/puppet/manifests, jeżeli.

Warning

Uwaga, puppet od wersji 4 ma inną składnię. W Ubuntu 16.04 (LTS) instaluje się Puppet 3.8.5. Wersja ta może być niekompatybilna z modułami pobieranymi przez Puppet (np. Apache, Tomcat, Java). Rozwiązaniem jest ściąganie modułów w niższych wersjach (pasujących do wersji 3.8.5) lub instalacja Puppet w wersji wyższej niż ta w LTS.

# Instalacja puppet w ostatniej wersji

# Yum-based systems (np. Enterprise Linux 7)
sudo rpm -Uvh https://yum.puppet.com/puppet5/puppet5-release-el-7.noarch.rpm
sudo yum -y install puppet-agent
export PATH=/opt/puppetlabs/bin:$PATH

# Apt-based systems (np. Ubuntu 16.04 Xenial Xerus)
wget https://apt.puppetlabs.com/puppet5-release-xenial.deb
sudo dpkg -i puppet5-release-xenial.deb
sudo apt update
sudo apt -y install puppet-agent
export PATH=/opt/puppetlabs/bin:$PATH

3.4. HTTPS problem

Gdyby wystąpił problem z certyfikatem ssl przy instalacji modułów należy:

  • postaw maszynę w Amazonie (Ubuntu LTS)

  • zainstaluj squid

sudo apt update
sudo apt install squid
  • na maszynie gościa (tam gdzie chcesz instalować moduł Puppet ustaw:

export http_proxy=http://<IP>:3128
export https_proxy=http://<IP>:3128

Lub:

[user]
http_proxy = http://<IP>:3128
https_proxy = http://<IP>:3128
sudo service puppet restart
sudo su -
puppet module install

3.5. Narzędzia pomocnicze

3.5.1. Facter

Przyjrzyj się wynikom poleceń:

facter
facter ipaddress
facter lsbdistdescription

Co zauważyłeś? Jak można wykorzystać te informacje?

Kod przedstawia wynik polecenia facter na świeżej maszynie Ubuntu postawionej w Amazon AWS

Korzystanie z faktów w manifestach:

Sposób klasyczny, jako zmienne na głównym poziomie

# Definicja
operatingsystem = 'Ubuntu'

# Wykorzystanie
case $::operatingsystem {
  'CentOS': { include centos }
  'MacOS':  { include mac }
}
Jako zmienne w tablicy faktów

# Definicja
$facts['fact_name'] = 'Ubuntu'

# Wykorzystanie
case $facts['fact_name'] {
  'CentOS': { include centos }
  'MacOS':  { include mac }
}

Tworzenie nowych faktów:

require 'facter'

Facter.add(:system_role) do
  setcode "cat /etc/system_role"
end
require 'facter'

Facter.add(:system_role) do
  setcode do
    Facter::Util::Resolution.exec("cat /etc/system_role")
  end
end

Druga metoda tworzenia faktów:

export FACTER_system_role=$(cat /etc/system_role); facter

3.5.2. Hiera

  • /etc/puppet/hiera.yaml

---
:backends:
  - yaml

:hierarchy:
  - "nodes/%{::fqdn}"
  - "roles/%{::role}"
  - common

:yaml:
  :datadir: /etc/puppet/hiera/

:logging:
  - console
nginx::nginx_servers:
     'devops-alldomains':
         server_name:
             - '~^(?<fqdn>.+?)$'
         www_root: '/var/www/$fqdn'
         index_files:
             - 'index.php'
         try_files:
             - '$uri'
             - '$uri/'
             - '/index.php?$args'
         access_log: '/var/log/nginx/devops-alldomains-access.log'
         error_log: '/var/log/nginx/devops-alldomains-error.log'

     'devops-alldomains-ssl':
         server_name:
             - '~^(?<fqdn>.+?)$'
         listen_port: '443'
         ssl_port: '443'
         www_root: '/var/www/$fqdn'
         ssl: true
         ssl_key: '/etc/ssl/www/$fqdn.key'
         ssl_cert: '/etc/ssl/www/$fqdn.crt'
         index_files:
             - 'index.php'
         try_files:
             - '$uri'
             - '$uri/'
             - '/index.php?$args'
         access_log: '/var/log/nginx/devops-alldomains-access-ssl.log'
         error_log: '/var/log/nginx/devops-alldomains-error-ssl.log'

 nginx::nginx_locations:
     'devops-alldomains-loc':
         location: '~ \.php$'
         www_root: '/var/www/$fqdn'
         server: 'devops-alldomains'
         fastcgi: 'unix:/var/run/php7-fpm.sock'
         fastcgi_split_path: '^(.+\.php)(/.*)$'
         fastcgi_index: 'index.php'
         fastcgi_param:
             'SCRIPT_FILENAME': '$document_root$fastcgi_script_name'

     'devops-alldomains-ssl-loc':
         location: '~ \.php$'
         www_root: '/var/www/$fqdn'
         server: 'devops-alldomains-ssl'
         ssl: true
         ssl_only: true
         fastcgi: 'unix:/var/run/php7-fpm.sock'
         fastcgi_split_path: '^(.+\.php)(/.*)$'
         fastcgi_index: 'index.php'
         fastcgi_param:
             'SCRIPT_FILENAME': '$document_root$fastcgi_script_name'

3.6. Przykłady

Exec {
    path => "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
}

group { "vagrant":
    ensure => present
}

user { "vagrant":
    ensure => present,
    gid => "vagrant"
}

exec { "update package definition":
    command => "/usr/bin/apt update"
}

package { [
    "git",
    "vim",
    "nmap",
    "htop",
    "wget",
    "curl",
    "nginx",
    "python3",
    "python3-dev",
    "python3-pip",
    "p7zip-full",
    "uwsgi",
    "uwsgi-plugin-python3",
    "postgresql-client",
    "postgresql",
    "postgresql-server-dev-all",
    "libmemcached-dev"
  ] :
    ensure => latest,
    require => Exec["update package definition"],
}

file { [
        "/var/www",
        "/var/www/log",
        "/var/www/public",
        "/var/www/public/media",
        "/var/www/public/static",
        "/var/www/tmp",
        "/var/www/src"
    ]:

    ensure => directory,
    owner => "vagrant",
    group => "vagrant",
    mode => 0755,
}

3.6.1. Unless

exec { "set hostname":
    command => '/bin/hostname -F /etc/hostname',
    unless  => "/usr/bin/test `hostname` = `/bin/cat /etc/hostname`",
}

3.7. Moduły

puppet module search apache
puppet module install puppetlabs-apache

3.7.1. Java

class { 'java' :
  package => 'java-1.8.0-openjdk-devel',
}
java::oracle { 'jdk8' :
  ensure  => 'present',
  version => '8',
  java_se => 'jdk',
}
java::oracle { 'jdk8' :
  ensure  => 'present',
  version_major => '8u101',
  version_minor => 'b13',
  java_se => 'jdk',
}

3.7.2. JBoss

To install JBoss Application Server you can use just, it will install Wildfly 8.2.0.Final by default:

include jboss

To install JBoss EAP or older JBoss AS use:

class { 'jboss':
  product => 'jboss-eap',
  version => '6.4.0.GA',
}

or use hiera:

jboss::params::product: 'jboss-as'
jboss::params::version: '7.1.1.Final'
$user = 'jb-user'
$passwd = 'SeC3eT!1'

node 'controller' {
  include jboss::domain::controller
  include jboss
  jboss::user { $user:
    ensure   => 'present',
    password => $passwd,
  }
}

3.9. Zadania do rozwiązania

3.9.1. Instalacja pakietów za pomocą Puppet

  • Manifest do tego zadania zapisz w pliku /etc/puppet/manifests/packages.pp

  • Zainstaluj następujące pakiety za pomocą Puppet:

    • nmap

    • htop

    • git

  • Upewnij się by Puppet wykonał polecenie apt update na początku

3.9.2. Zmiana hostname

  • Manifest do tego zadania zapisz w pliku /etc/puppet/manifests/hostname.pp

  • Za pomocą manifestu zmień hostname maszyny na ecosystem.local

  • Upewnij się, że po wpisaniu polecenia hostname będzie ustawiona na odpowiednią wartość

  • Upewnij się, że hostname nie przywróci się do domyślnej wartości po ponownym uruchomieniu

  • Hostname zmienia się na dwa sposoby:

    • podmiana zawartości pliku /etc/hostname i uruchomienie hostname -F /etc/hostname

    • uruchomienie polecenia hostnamectl set-hostname ...

3.9.3. Zarządzanie użytkownikami, grupami i katalogami

  • Manifest do tego zadania zapisz w pliku /etc/puppet/manifests/users.pp

  • Upewnij się, że użytkownik vagrant istnieje, ma uid=1337 i należy do grupy vagrant

  • Upewnij się, że grupa vagrant istnieje i ma gid=1337

  • Upewnij się, że:

    • Katalog /var/www istnieje

    • Właścicielem jego jest user vagrant

    • Właścicielem jego jest grupa vagrant

    • Ma uprawnienia rwxr-xr-x

3.9.4. Konfiguracja nginx

  • Za pomocą Puppet upewnij się by był użytkownik www-data i miał uid=33

  • Za pomocą Puppet upewnij się by była grupa www-data i miała gid=33

  • Upewnij się że katalog /var/www istnieje i właścicielem jego są user www-data i grupa www-data i że ma uprawnienia rwxr-xr-x

  • Zainstaluj i skonfiguruj nginx wykorzystując moduł Puppet

  • Z terminala wygeneruj certyfikaty self signed OpenSSL (.cert i .key) (za pomocą i umieść je w /etc/ssl/)

  • Za pomocą Puppet Stwórz dwa vhosty:

    • insecure.example.com na porcie 80 i z katalogiem domowym /var/www/insecure-example-com

    • ssl.example.com na porcie 443 i z katalogiem domowym /var/www/ssl-example-com + używanie certyfikatów SSL wcześniej wygenerowanych

  • Stwórz pliki z treścią:

    • /var/www/insecure-example-com/index.html z treścią Ehlo World! - Insecure

    • /var/www/ssl-example-com/index.html z treścią Ehlo World! - SSL!

  • W przeglądarce na komputerze lokalnym wejdź na stronę:

3.9.5. Konfiguracja Apache2 (opcjonalnie)

  • Za pomocą Puppet upewnij się by był użytkownik www-data i miał uid=33

  • Za pomocą Puppet upewnij się by była grupa www-data i miała gid=33

  • Upewnij się że katalog /var/www istnieje i właścicielem jego są user www-data i grupa www-data i że ma uprawnienia rwxr-xr-x

  • Zainstaluj i skonfiguruj Apache2 wykorzystując moduł Puppet

  • Z terminala wygeneruj certyfikaty self signed OpenSSL (.cert i .key) (za pomocą i umieść je w /etc/ssl/)

  • Za pomocą Puppet Stwórz dwa vhosty:

    • insecure.example.com na porcie 80 i z katalogiem domowym /var/www/insecure-example-com

    • ssl.example.com na porcie 443 i z katalogiem domowym /var/www/ssl-example-com + używanie certyfikatów SSL wcześniej wygenerowanych

  • Stwórz pliki z treścią:

    • /var/www/insecure-example-com/index.html z treścią Ehlo World! - Insecure

    • /var/www/ssl-example-com/index.html z treścią Ehlo World! - SSL!

  • W przeglądarce na komputerze lokalnym wejdź na stronę:

Warning

Uwaga, puppet od wersji 4 ma inną składnię. W Ubuntu 16.04 (LTS) instaluje się Puppet 3.8.5. Puppet module instaluje zawsze najnowszą (w tym wypadku niekompatybilną z naszym Puppet)! Aby zainstalować apache należy wymusić odpowiednią wersję (ostatnia supportująca Puppet 3.8 to 1.10.

$ puppet module install puppetlabs-apache --version 1.10.0

3.9.6. Instalacja i konfiguracja MySQL

  • Manifest do tego zadania zapisz w pliku /etc/puppet/manifests/mysql.pp

  • Zainstaluj bazę danych MySQL wykorzystując moduł Puppet

  • Ustaw hasło dla użytkownika root na mypassword

  • Ustaw nasłuchiwanie serwera mysqld na wszystkich interfejsach (0.0.0.0)

  • Stwórz bazę danych mydb z utf-8

  • Stwórz usera myusername z hasłem mypassword

  • Nadaj wszystkie uprawnienia dla usera myusername dla bazy mydb

  • Ustaw backupowanie bazy danych do /tmp/mysql-backup

3.9.7. Instalacja i konfiguracja Tomcat

  • Manifest do tego zadania zapisz w pliku /etc/puppet/manifests/tomcat.pp

  • Zainstaluj język Java za pomocą modułu Puppet

  • Zainstaluj Tomcat 8 za pomocą Puppet w katalogu /opt/tomcat8

  • Skonfiguruj dwie instancje Tomcat działające jednocześnie:

    • Jedna uruchamiana na domyślnych portach

    • Druga uruchamiana na 8006 a connector z portu 8081 przekierowywał na 8443

    • Na pierwszej uruchom war z lokacji /opt/tomcat8/webapps/docs/appdev/sample/sample.war