Current section
Files
Jump to
Current section
Files
guides/0.introduction.md
# 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`
```elixir
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`
```elixir
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`
```elixir
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`
```elixir
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.
```elixir
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.