loading...

Work with Serverspec alternative tool Goss

koh_sh profile image koh-sh Originally published at koh-sh.hatenablog.com ・4 min read

What is Goss?

Goss is a YAML based server testing tool written in Go.
It checks statuses of process, ports and else.

GitHub logo aelsabbahy / goss

Quick and Easy server testing/validation

Goss - Quick and Easy server validation

Build Status Github All Releases ** Blog

Goss in 45 seconds

asciicast

Note: For an even faster way of doing this, see: autoadd

Note: For testing docker containers see the dgoss wrapper. Also, user submitted wrapper scripts for Kubernetes kgoss and Docker Compose dcgoss.

Note: For some Docker/Kubernetes healthcheck, health endpoint, and container ordering examples, see my blog post here.

Introduction

What is Goss?

Goss is a YAML based serverspec alternative tool for validating a server’s configuration. It eases the process of writing tests by allowing the user to generate tests from the current system state. Once the test suite is written they can be executed, waited-on, or served as a health endpoint.

Why use Goss?

  • Goss is EASY! - Goss in 45 seconds
  • Goss is FAST! - small-medium test suits are near instantaneous, see benchmarks
  • Goss is SMALL! - <10MB single self-contained binary

Installation

Note: For macOS…

Differences from Serverspec

As it is Serverspec alternative tool, there are some differences between them.

Pros of Goss

Easier to write as it is YAML

Tests can be defined by a single YAML file, easier to manage and doesn't require much time to learn.

Able to create test suite within a second.

Goss provides a command to define a test state automatically.

Easy to install

Goss comes with one single binary so no need to think about dependency.

Pros of Serverspec

Executable from remote

Like Ansible or Chef, able to execute from a remote node with SSH

More Resources

Goss supports about 20 Resources but Serverspec has twice (as of Mar 28th, 2019)

More flexible

Serverspec is more flexible as it allows us to code with Ruby.

Let's try

CentOS 7.5.1804 on Vagrant.
Goss v0.3.6.

Install

A script is prepared officially so it cannot be easier to install.
Also, dgoss which is a command for Docker container would be installed but I am not going to use it this time.

And please be noted that the script is not recommended for production environment.
Try manual install instead.

[vagrant@Vag2] ~
% curl -fsSL https://goss.rocks/install | sudo sh
Downloading https://github.com/aelsabbahy/goss/releases/download/v0.3.6/goss-linux-amd64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   606    0   606    0     0    808      0 --:--:-- --:--:-- --:--:--   809
100 8324k  100 8324k    0     0   236k      0  0:00:35  0:00:35 --:--:--  240k
Goss v0.3.6 has been installed to /usr/local/bin/goss
goss --version
goss version v0.3.6
Downloading https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dgoss/dgoss
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3803  100  3803    0     0   9722      0 --:--:-- --:--:-- --:--:--  9726
dgoss master has been installed to /usr/local/bin/dgoss
[vagrant@Vag2] ~
% which goss
/usr/local/bin/goss
[vagrant@Vag2] ~
%

Create a test suite

As I mentioned earlier, Goss has commands to create a test suite automatically.
goss.yaml will be created by goss autoadd or goss add [resource].

In this post, I will work on a host which HAProxy is installed.

[vagrant@Vag2] ~/work
% goss autoadd haproxy
Adding Group to './goss.yaml':

haproxy:
  exists: true
  gid: 188


Adding Package to './goss.yaml':

haproxy:
  installed: true
  versions:
  - 1.5.18


Adding Process to './goss.yaml':

haproxy:
  running: true


Adding Service to './goss.yaml':

haproxy:
  enabled: true
  running: true


Adding User to './goss.yaml':

haproxy:
  exists: true
  uid: 188
  gid: 188
  groups:
  - haproxy
  home: /var/lib/haproxy
  shell: /sbin/nologin


[vagrant@Vag2] ~/work
%

After goss autoadd, the created goss.yaml is here.

[vagrant@Vag2] ~/work
% ls -l goss.yaml
-rw-r--r-- 1 vagrant vagrant 347 Mar 23 03:55 goss.yaml
[vagrant@Vag2] ~/work
% cat goss.yaml
package:
  haproxy:
    installed: true
    versions:
    - 1.5.18
service:
  haproxy:
    enabled: true
    running: true
user:
  haproxy:
    exists: true
    uid: 188
    gid: 188
    groups:
    - haproxy
    home: /var/lib/haproxy
    shell: /sbin/nologin
group:
  haproxy:
    exists: true
    gid: 188
process:
  haproxy:
    running: true
[vagrant@Vag2] ~/work
%

Just a single command, below test items are created.

  • Test items vary on the target.

  • Installed packages

  • is-active, is-enabled of service

  • User definition

  • Group definition

  • Process status

You can use add [resource] command to specify each item one by one.

Test execution

Success

Then Let's try testing.
Of course, it is easy to execute.

[vagrant@Vag2] ~/work
% goss validate
.............

Total Duration: 0.033s
Count: 13, Failed: 0, Skipped: 0
[vagrant@Vag2] ~/work
%

Each dots(...) mean each test.
The speed of the test is incredible.
It takes only 0.033 sec to test 13 items.

Fail

So next, we let the test fail.
Stopped the process.

[vagrant@Vag2] ~/work
% sudo systemctl stop haproxy
[vagrant@Vag2] ~/work
% sudo systemctl is-active haproxy
inactive
zsh: exit 3     sudo systemctl is-active haproxy
[vagrant@Vag2] ~/work
%

Then retry.

[vagrant@Vag2] ~/work
% goss validate
..F.........F

Failures/Skipped:

Process: haproxy: running:
Expected
    <bool>: false
to equal
    <bool>: true

Service: haproxy: running:
Expected
    <bool>: false
to equal
    <bool>: true

Total Duration: 0.051s
Count: 13, Failed: 2, Skipped: 0
zsh: exit 1     goss validate
[vagrant@Vag2] ~/work
%

As expected, process/service checks failed.

Changing format

Goss has several formats to output the result.
It has like JSON, and tap is the most human readable I think.

[vagrant@Vag2] ~/work
% goss validate --format tap
1..13
ok 1 - Group: haproxy: exists: matches expectation: [true]
ok 2 - Group: haproxy: gid: matches expectation: [188]
not ok 3 - Process: haproxy: running: doesn't match, expect: [true] found: [false]
ok 4 - User: haproxy: exists: matches expectation: [true]
ok 5 - User: haproxy: uid: matches expectation: [188]
ok 6 - User: haproxy: gid: matches expectation: [188]
ok 7 - User: haproxy: home: matches expectation: ["/var/lib/haproxy"]
ok 8 - User: haproxy: groups: matches expectation: [["haproxy"]]
ok 9 - User: haproxy: shell: matches expectation: ["/sbin/nologin"]
ok 10 - Package: haproxy: installed: matches expectation: [true]
ok 11 - Package: haproxy: version: matches expectation: [["1.5.18"]]
ok 12 - Service: haproxy: enabled: matches expectation: [true]
not ok 13 - Service: haproxy: running: doesn't match, expect: [true] found: [false]
zsh: exit 1     goss validate --format tap
[vagrant@Vag2] ~/work
%

Check with http

Goss can serve http mode and work as Healthcheck endpoint.

[vagrant@Vag2] ~/work
% goss serve &
2019/03/23 04:00:20 Starting to listen on: :8080

[vagrant@Vag2] ~/work
% curl localhost:8080/healthz
2019/03/23 04:00:23 [::1]:48704: requesting health probe
2019/03/23 04:00:23 [::1]:48704: Stale cache, running tests
..F.........F

Failures/Skipped:

Process: haproxy: running:
Expected
    <bool>: false
to equal
    <bool>: true

Service: haproxy: running:
Expected
    <bool>: false
to equal
    <bool>: true

Total Duration: 0.044s
Count: 13, Failed: 2, Skipped: 0
[vagrant@Vag2] ~/work
%

Conclusion

As I tried, Goss is extremely great since it allows us to test within a minute.
In this post, it was only a simple test but it can be applied to production environment with more customize.

I assume Ansible can be a good match with Goss when comes to production use.
Or maybe it can extend monitoring accuracy with Goss healthcheck mode.

Discussion

pic
Editor guide