Mgmt Config - Fast, Real-time, Closed-Loop Automation.

Next Steps

Medium Example

Let’s next write something less abstract, and more concretely useful.

More resources and functions:

Here we’ll introduce the pkg resource which manages the installation of system packages (think .rpm and .deb via your package manager) and the svc resource which starts and stops systemd services. We’ll also see a templating function in the golang package, which runs the standard golang templating engine for us to produce a string. This function makes use of the built-in magic $hostname variable, which should generally be a unique property of every running mgmt instance in your cluster. Finally we see Depend and Before relationships between resources. These “edges” let you specify the order in which the mgmt engine will change the desired state. By default, every resource will run in parallel with each other, which may cause errors if that sequence is not logical.

Example:

Put the following into a nginx0.mcl file:

import "golang"

pkg "nginx" {
	state => "installed",
}

file "/usr/share/nginx/html/index.html" {
	content => golang.template("This is nginx on {{ . }} managed by mgmt!\n", $hostname),
	state => "exists",

	Depend => Pkg["nginx"],
	Before => Svc["nginx"],
}

file "/etc/nginx/nginx.conf" {
	content => "# this is nginx.conf
events {}

http {
	server {
		listen 80;
		location / {
			root /usr/share/nginx/html;
			index index.html;
		}
	}
}\n",
	state => "exists",

	Depend => Pkg["nginx"],
}

svc "nginx" {
	state => "running",
	startup => "enabled",

	Depend => File["/etc/nginx/nginx.conf"],
}

Run: sudo mgmt run --tmp-prefix lang nginx0.mcl to try out this medium example! You’ll need root permissions since most systems require special permissions to install packages, edit files in /etc/ and to start system services. Amidst the output generated by the engine, you should see some lines that resemble:

19:48:06 engine: pkg[nginx]: Check: pkg[nginx]
19:48:06 engine: pkg[nginx]: Apply: pkg[nginx]
19:48:06 engine: pkg[nginx]: Set(installed): pkg[nginx]...
19:48:14 engine: pkg[nginx]: Set(installed) success: pkg[nginx]
19:48:14 engine: file[/etc/nginx/nginx.conf]: copy 141 bytes
19:48:14 engine: file[/usr/share/nginx/html/index.html]: copy 40 bytes
19:48:15 engine: svc[nginx]: event: started

These lines represent the installation of the package, the setup of the two files, and finally the starting of the service. You may need to edit the above example slightly if your GNU+Linux distribution packages the nginx software differently.

You can now browse to http://localhost:80 to see the test page!

More details:

You have just specified the state parameter inside the pkg resource to declare that you want the package to be installed. If you instead specified the “newest” value, then it would ensure the package is at the latest available version. You can also specify the precise version string that you want, or even “uninstalled”. For the svc resource, you declared that you want the unit to be in the “running” state. Within the same resource, you also specified the startup field to be “enable”, so that the will run automatically via systemd when the machine turns on.

Note that the Depend and Before fields are capitalized. Regular resource parameters are not capitalized, but these are special keywords that can be used with any resource. You can list any number of them per resource. They refer to a unique resource kind and name as shown. If the reference is not available, or if they form a loop, then the engine will error.

You’ll note that it’s a bit messy to include the contents of the nginx.conf file inline. Stay tuned, you’ll soon learn how to pull in data from other files.

Congratulations on writing some more mcl code!