Central management of multiple servers - Exercise 1
==============

*Disclaimer:*
--------------

This exercise is a part of [Configuration Management (ICT4TN022, spring 2018) // Palvelinten hallinta (ICT4TN022, kevät 2018)](http://www.haaga-helia.fi/fi/opinto-opas/opintojaksokuvaukset/ICT4TN022) school course organized as a part of Information Technology studies in Haaga-Helia university of Applied Sciences, Helsinki, Finland. Course lecturer [Tero Karvinen](http://terokarvinen.com/) has defined the original assignment descriptions in Finnish presented in this document in English. Answers and translations have been written by Pekka Helenius (me, ~ Fincer).

*Table of contents*
--------------

- [c) Install Salt master and minion using pull architecture (e.g. master takes server role). You can set up the master and the slave on the same computer. Test the configuration by issuing salt commands remotely.](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/exercises/h1.md#c-install-salt-master-and-minion-using-pull-architecture-eg-master-takes-server-role-you-can-set-up-the-master-and-the-slave-on-the-same-computer-test-the-configuration-by-issuing-salt-commands-remotely)

- [d) Test a salt-state example by Laine or modify some existing salt state configuration. Test the Salt-state functionality. Be aware that Laine has some unifinished examples on his repository (such as Battlenet installation on Windows)](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/exercises/h1.md#d-test-a-salt-state-example-by-laine-or-modify-some-existing-salt-state-configuration-test-the-salt-state-functionality-be-aware-that-laine-has-some-unifinished-examples-on-his-repository-such-as-battlenet-installation-on-windows)

- [e) Collect system information from Salt minion computers by using Salt grains interface.](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/exercises/h1.md#e-collect-system-information-from-salt-minion-computers-by-using-salt-grains-interface)

- [f) Real life test. Set up a real SaltStack configuration on your own computer or using your existing virtual server. (Note: It is recommended to test SaltStack in real life but if unsuccessful, configure a virtual environment for this assignment)](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/exercises/h1.md#f-real-life-test-set-up-a-real-saltstack-configuration-on-your-own-computer-or-using-your-existing-virtual-server-note-it-is-recommended-to-test-saltstack-in-real-life-but-if-unsuccessful-configure-a-virtual-environment-for-this-assignment)

**c)** Install Salt master and minion using pull architecture (e.g. master takes server role). You can set up the master and the slave on the same computer. Test the configuration by issuing salt commands remotely.
--------------

**Answer:**

Both `salt-master` and `salt-ssh` (+ SSH server daemon) should be installed on the host computer, `salt-minion` and SSH client on the client computer. We install both Salt minion and master to the same computer in this assignment.

```
sudo apt-get update && sudo apt-get install salt-common salt-master salt-minion salt-ssh ssh
```

Start Salt master service:

```
sudo systemctl enable salt-master.service
sudo systemctl start salt-master.service
```

Check status of the Salt master service:

```
systemctl is-active salt-master.service
```

or

```
systemctl status salt-master.service
```

Start Salt minion service:

```
sudo systemctl enable salt-minion.service
sudo systemctl start salt-minion.service
```

Check status of the Salt minion service:

```
systemctl is-active salt-minion.service
```

or

```
systemctl status salt-minion.service
```

Find out Salt master IP address by issuing `ifconfig` command*. IP address is the value of `inet` field in output.

*On Debian-based Linux distributions, it is possible to find out IP addresses by issuing `hostname -I` command (see [hostname -I](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=562830)) as this command is not widely available on other Linux distributions by default.

We shall configure Salt master IP address (or hostname) for the Salt minion service by editing Salt minion configuration file `/etc/salt/minion`. In addition, we shall add an ID `slave` to the minion service.

Issue command `sudo nano /etc/salt/minion` or `sudoedit /etc/salt/minion` and add the following entries:

```
master: 127.0.0.1
id: slave
```

Restart Salt minion service:

```
sudo systemctl restart salt-minion.service
```

Run the following commands in your Salt master:

```
sudo salt-key
sudo salt-key -A
```

Sample output:

```
fincer@computer:~$ sudo salt-key
Accepted Keys:
Denied Keys:
Unaccepted Keys:
slave
Rejected Keys:
fincer@computer:~$ sudo salt-key -A
The following keys are going to be accepted:
Unaccepted Keys:
slave
Proceed? [n/Y] y
Key for minion slave accepted.
```

Restart Salt minion again (may not be necessary):

```
sudo systemctl restart salt-minion.service
```

Run a sample command in order to test the Salt master/minion configuration:

```
fincer@computer:~$ sudo salt '*' cmd.run "ls /boot"
slave:
    System.map-4.15.0-13-generic
    abi-4.15.0-13-generic
    config-4.15.0-13-generic
    grub
    initrd.img-4.15.0-13-generic
    memtest86+.bin
    memtest86+.elf
    memtest86+_multiboot.bin
    retpoline-4.15.0-13-generic
    vmlinuz-4.15.0-13-generic
```

**d)** Test a salt-state example by Laine or modify some existing salt state configuration. Test the Salt-state functionality. Be aware that Laine has some unifinished examples on his repository (such as Battlenet installation on Windows)
--------------

**Answer:**

Create folder path `/srv/salt` on the Salt master:

```
sudo mkdir -p /srv/salt
```

Add new Salt state files `/srv/salt/top.sls` and `/srv/salt/firewall.sls`:

```
sudo touch /srv/salt/{top.sls,firewall.sls}
```

Add the following contents into the `/srv/salt/firewall.sls`:

```
ufw:
  pkg.installed

ufw-enable:
  cmd.run:
    - name: 'ufw --force enable'
    - require:
      - pkg: ufw

```

Reference: [joonaleppalahti - firewall.sls](https://github.com/joonaleppalahti/CCM/blob/master/salt/srv/salt/firewall.sls)

Add the following contents into the `/srv/salt/top.sls`:

```
base:
  'slave':
    - firewall

```

where `slave` refers to a minion ID* on the network, and `firewall` refers to the Salt state file `/srv/salt/firewall.sls` found on the Salt master. In this case, contents and configurations declared in `/srv/salt/firewall.sls` are supplied to the minion `slave`.

*Salt accepts regular expressions in minion ID field and, therefore, allows multiple minions to be matched. Any matching Salt minion on the network gets the configuration defined by Salt master. For instance, the following `/srv/salt/top.sls` configuration would match any minion ID starting with `slave` phrase (e.g. slave01, slavea, slave534, slave4 etc.)

```
base:
  'slave*':
    - firewall

```

Run the following command on Salt master:

```
sudo salt '*' state.highstate
```

The previous command should print the following output:

```
fincer@computer:~$ sudo salt '*' state.highstate
slave:
----------
          ID: ufw
    Function: pkg.installed
      Result: True
     Comment: All specified packages are already installed
     Started: 13:28:16.290668
    Duration: 858.482 ms
     Changes:   
----------
          ID: ufw-enable
    Function: cmd.run
        Name: ufw --force enable
      Result: True
     Comment: Command "ufw --force enable" run
     Started: 13:28:17.190531
    Duration: 843.309 ms
     Changes:   
              ----------
              pid:
                  10265
              retcode:
                  0
              stderr:
              stdout:
                  Firewall is active and enabled on system startup

Summary for slave
------------
Succeeded: 2 (changed=1)
Failed:    0
------------
Total states run:     2
Total run time:   1.718 s

```

UFW firewall was already installed on the minion computer but it was not enabled properly. Therefore, only one modification was applied to the Salt minion computer configuration, although two commands were issued.

**e)** Collect system information from Salt minion computers by using Salt grains interface.
--------------

**Answer:**

Grains of every Salt minion (which have been accepted beforehand by the Salt master) can be printed out by issuing the following command on the Salt master:

```
sudo salt '*' grains.ls
```

Sample output, returned by a Salt minion (asterix (`*`) is a regex for matching any character, i.e. any Salt minion ID):

```
fincer@computer:~$ sudo salt '*' grains.items | grep saltversion -C 4
        - candidate
        - 1
    saltpath:
        /usr/lib/python3/dist-packages/salt
    saltversion:
        2017.7.4
    saltversioninfo:
        - 2017
        - 7
        - 4
        - 0
```

Systemd information of a Salt minion (supported features and version number):

```
fincer@computer:~$ sudo salt '*' grains.item systemd
slave:
    ----------
    systemd:
        ----------
        features:
            +PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid
        version:
            237
```

etc.

**f)** Real life test. Set up a real SaltStack configuration on your own computer or using your existing virtual server. (Note: It is recommended to test SaltStack in real life but if unsuccessful, configure a virtual environment for this assignment)
--------------

**Answer:**

**NOTE:** `salt-ssh` was not used in this assignment!

Let's set up two Salt computers on the same network. One takes Salt master role, the other one takes Salt minion role.

- IP address of the Salt master is 10.11.11.101 (ifconfig)

- IP address of the Salt minion is 10.11.11.102 (ifconfig)

- IP addresses were determined with DHCP server.

We shall set up Master and Minion system configurations by following instructions of the assignment [c)]((https://github.com/Fincer/central-management-of-multiple-servers/blob/master/exercises/h1.md#c-install-salt-master-and-minion-using-pull-architecture-eg-master-takes-server-role-you-can-set-up-the-master-and-the-slave-on-the-same-computer-test-the-configuration-by-issuing-salt-commands-remotely)). On the Salt minion, add Salt master IP and Salt minion ID into `/etc/salt/minion` file:

```
master: 10.11.11.101
id: slave_computer
```

after which you should run the following command on the Salt master (NOTE: Salt minion may not be immediately listed by `salt-key` command):

```
sudo salt-key && sudo salt-key -A
```

Output:

```
fincer@master:~$ sudo salt-key && sudo salt-key -A
Accepted Keys:
Denied Keys:
Unaccepted Keys:
slave_computer
Rejected Keys:
The following keys are going to be accepted:
Unaccepted Keys:
slave_computer
Proceed? [n/Y] y
Key for minion slave_computer accepted.
```

Let's install LAMP server environment and insert `/var/www/html/index.php` to the Salt minion computer. Run the following commands on Salt master:

```
sudo mkdir -p /srv/salt
echo "<?php phpinfo(); ?>" | sudo tee /srv/salt/index.php
sudo wget https://raw.githubusercontent.com/joonaleppalahti/CCM/master/salt/srv/salt/lamp.sls -O /srv/salt/lamp.sls
sudo sed -i '14,18d; s/salt\:\/\/webserver\//salt\:\/\//' /srv/salt/lamp.sls
sudo salt 'slave*' state.apply lamp

```

Salt state file `lamp.sls` includes definitions for `index.html` which are not defined in this assignment. We delete those definitions by issuing `sed` command above. In addition, references to subfolder `webserver` are also deleted with `sed` command.

Output of successfully executed `salt` command (run on the Salt master):

```
fincer@master:~$ cat /srv/salt/lamp.sls 
 install_lamp:
   pkg.installed:
     - pkgs:
       - apache2
       - libapache2-mod-php

 /var/www/html/index.php:
  file:
    - managed
    - source: salt://index.php
    - require:
      - pkg: install_lamp

fincer@master:~$ sudo salt 'slave*' state.apply lamp
slave_computer:
----------
          ID: install_lamp
    Function: pkg.installed
      Result: True
     Comment: 2 targeted packages were installed/updated.
     Started: 15:07:24.960653
    Duration: 50817.827 ms
     Changes:   
              ----------
              apache2:
                  ----------
                  new:
                      2.4.29-1ubuntu4
                  old:
              apache2-api-20120211:
                  ----------
                  new:
                      1
                  old:
              apache2-api-20120211-openssl1.1:
                  ----------
                  new:
                      1
                  old:
              apache2-bin:
                  ----------
                  new:
                      2.4.29-1ubuntu4
                  old:
              apache2-data:
                  ----------
                  new:
                      2.4.29-1ubuntu4
                  old:
              apache2-utils:
                  ----------
                  new:
                      2.4.29-1ubuntu4
                  old:
              httpd:
                  ----------
                  new:
                      1
                  old:
              httpd-cgi:
                  ----------
                  new:
                      1
                  old:
              libapache2-mod-php:
                  ----------
                  new:
                      1:7.2+60ubuntu1
                  old:
              libapache2-mod-php7.2:
                  ----------
                  new:
                      7.2.3-1ubuntu1
                  old:
              libapr1:
                  ----------
                  new:
                      1.6.3-2
                  old:
              libaprutil1:
                  ----------
                  new:
                      1.6.1-2
                  old:
              libaprutil1-dbd-sqlite3:
                  ----------
                  new:
                      1.6.1-2
                  old:
              libaprutil1-ldap:
                  ----------
                  new:
                      1.6.1-2
                  old:
              liblua5.2-0:
                  ----------
                  new:
                      5.2.4-1.1build1
                  old:
              php-calendar:
                  ----------
                  new:
                      1
                  old:
              php-cli:
                  ----------
                  new:
                      1
                  old:
              php-common:
                  ----------
                  new:
                      1:60ubuntu1
                  old:
              php-ctype:
                  ----------
                  new:
                      1
                  old:
              php-exif:
                  ----------
                  new:
                      1
                  old:
              php-fileinfo:
                  ----------
                  new:
                      1
                  old:
              php-ftp:
                  ----------
                  new:
                      1
                  old:
              php-iconv:
                  ----------
                  new:
                      1
                  old:
              php-json:
                  ----------
                  new:
                      1
                  old:
              php-opcache:
                  ----------
                  new:
                      1
                  old:
              php-pdo:
                  ----------
                  new:
                      1
                  old:
              php-phar:
                  ----------
                  new:
                      1
                  old:
              php-posix:
                  ----------
                  new:
                      1
                  old:
              php-readline:
                  ----------
                  new:
                      1
                  old:
              php-shmop:
                  ----------
                  new:
                      1
                  old:
              php-sockets:
                  ----------
                  new:
                      1
                  old:
              php-sysvmsg:
                  ----------
                  new:
                      1
                  old:
              php-sysvsem:
                  ----------
                  new:
                      1
                  old:
              php-sysvshm:
                  ----------
                  new:
                      1
                  old:
              php-tokenizer:
                  ----------
                  new:
                      1
                  old:
              php7.2-calendar:
                  ----------
                  new:
                      1
                  old:
              php7.2-cli:
                  ----------
                  new:
                      7.2.3-1ubuntu1
                  old:
              php7.2-common:
                  ----------
                  new:
                      7.2.3-1ubuntu1
                  old:
              php7.2-ctype:
                  ----------
                  new:
                      1
                  old:
              php7.2-exif:
                  ----------
                  new:
                      1
                  old:
              php7.2-fileinfo:
                  ----------
                  new:
                      1
                  old:
              php7.2-ftp:
                  ----------
                  new:
                      1
                  old:
              php7.2-gettext:
                  ----------
                  new:
                      1
                  old:
              php7.2-iconv:
                  ----------
                  new:
                      1
                  old:
              php7.2-json:
                  ----------
                  new:
                      7.2.3-1ubuntu1
                  old:
              php7.2-opcache:
                  ----------
                  new:
                      7.2.3-1ubuntu1
                  old:
              php7.2-pdo:
                  ----------
                  new:
                      1
                  old:
              php7.2-phar:
                  ----------
                  new:
                      1
                  old:
              php7.2-posix:
                  ----------
                  new:
                      1
                  old:
              php7.2-readline:
                  ----------
                  new:
                      7.2.3-1ubuntu1
                  old:
              php7.2-shmop:
                  ----------
                  new:
                      1
                  old:
              php7.2-sockets:
                  ----------
                  new:
                      1
                  old:
              php7.2-sysvmsg:
                  ----------
                  new:
                      1
                  old:
              php7.2-sysvsem:
                  ----------
                  new:
                      1
                  old:
              php7.2-sysvshm:
                  ----------
                  new:
                      1
                  old:
              php7.2-tokenizer:
                  ----------
                  new:
                      1
                  old:
              phpapi-20170718:
                  ----------
                  new:
                      1
                  old:
----------
          ID: /var/www/html/index.php
    Function: file.managed
      Result: True
     Comment: File /var/www/html/index.php updated
     Started: 15:08:15.783571
    Duration: 67.439 ms
     Changes:   
              ----------
              diff:
                  New file
              mode:
                  0644

Summary for slave_computer
------------
Succeeded: 2 (changed=2)
Failed:    0
------------
Total states run:     2
Total run time:  50.885 s
```

And:

```
fincer@master:~$ sudo salt 'slave_computer' cmd.run 'dpkg --get-selections | grep apache'
slave_computer:
    apache2						install
    apache2-bin						install
    apache2-data					install
    apache2-utils					install
    libapache2-mod-php					install
    libapache2-mod-php7.2				install
```
