Introduction to Realbook
Realbook is a simple, imperative DSL that helps you provision and set up linux-based servers.
If you have a linux based machine, you can use Realbook to make sure that the required software and soft assets are properly installed and configured on this machine. Because Realbook uses the BEAM under the hood, it is possible to provision multiple machines concurrently, which is a desirable feature for on-metal deployments.
Realbook is also useful for other deployments (like VMs), since it can produce reproducible environments (potentially across time) via its self-validation scheme.
Example
Amy wants to provision an Ubuntu 18.04 machine that will serve as a
DHCP server. To do this, she creates some realbook scripts in her
~/realbook-scripts
directory.
install_dhcp.exs
verify do
# verifies that isc-dhcp-server software exists by checking
# the existence of the software in the apt repository db
run!("apt list isc-dhcp-server", tty: true, stdout: :stream) =~ "installed"
end
play do
sudo_run! "apt-get install isc-dhcp-server"
end
configure_dhcp.exs
requires "install_dhcp"
@dhcp_conf_path "/etc/dhcp/dhcpd.conf"
# templates the /etc/dhcp/dhcpd.conf file to match the specifications
# for isc-dhcp-server. A more advanced example would use EEx templates
# to achieve this.
def dhcpd_conf do
"""
default-lease-time 600;
max-lease-time 7200;
option subnet-mask 255.255.255.0;
option broadcast-address #{get :broadcast};
option routers #{get :router};
# give the client either cloudflare or google DNS
option domain-name-servers 1.1.1.1 8.8.8.8;
option domain-name "amysdomain.local";
subnet #{get :subnet} netmask 255.255.255.0 {
range #{get :range_start} #{get :range_end};
}
"""
end
verify do
# checks that the system configuration matches the supplied
# configuration by comparing sha256sum. By doing this we
# can come back to the system later and use the same script
# to overwrite the configuration settings if they should change.
shasum = :sha256
|> :crypto.hash(dhcpd_conf())
|> Base.encode16(case: :lower)
run!("sha256sum #{@dhcp_conf_path}") =~ shasum
end
play do
sudo_run! "rm -rf #{@dhcp_conf_path}"
sudo_send! dhcpd_conf(), @dhcp_conf_path
end
enable_dhcp.exs
requires "configure_dhcp"
verify do
# try, five times, over 5 seconds, to see if the dhcp server
# is active. This is necessary because the systemctl command
# performs some things asynchronously.
wait_till count: 5 do
run! "systemctl is-enabled --quiet isc-dhcp-server"
end
end
play do
sudo_run! "systemctl enable isc-dhcp-server"
end
reset_dhcp.exs
requires "reset_dhcp"
# always reset the dhcp server (this is for the case when we didn't
# have to enable the dhcp server)
verify false
play do
sudo_run! "systemctl restart isc-dhcp-server"
end
Running the realbooks
Having defined the realbooks, Amy now needs to execute them on her remote server. In this example, she will simply use the iex shell to achieve this.
iex> Application.put_env(:realbook, :script_dir, "~/realbook-scripts")
iex> Realbook.connect!(:ssh, host: "amys.host.ip", user: "admin", identity: "~/my_key.pem")
iex> Realbook.set(
broadcast: "192.168.1.255",
router: "192.168.1.1",
subnet: "192.168.1.0",
range_start: "192.168.1.10",
range_end: "192.168.1.64")
iex> import Realbook
iex> ~B"requires ~w(install_dhcp configure_dhcp enable_dhcp reset_dhcp)"
If Amy had forgotten any of the required variables, then the script
would not run. If Amy would like to change the settings later, this
particular script's strategy lets her simply input different settings
in the Realbook.set
command and it will redo the dhcp configuration.