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 "" | 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 ```