Tags: dda-managedvm-crate, howto, Convention over Configuration, clojure ide, composition, dda-pallet, phases
Our goal is a development environment properly set up straight away from the beginning - and additionally to be able to adjust your setup as you like. We are using dda-pallet to describe this infrastructure as clojure code. This blog is part of the "dda-pallet" series and will show step by step how to setup a clojure IDE:
Last time we cloned some git repositories into a created user home in our future IDE. Today we will proceed with the dda-managed-vm crate.
You can think of the dda-managed-vm as a base-vm already having some basic tools installed, like bookmarks, password-store, gpg keys, mail, LibreOffice, etc. But we will also find some more fine grained installations & configurations:
While applying the dda-managed-vm we will learn how Domain Driven Design fits into the functional DevOps world and why the separation of domain and infrastructure is important - even for infrastructure code.
As a result we should be able to log in to our virtual machine and be able to do various tasks like browsing the internet (for safety reasons using a vm for browsing the internet might be a good idea), use LibreOffice, password-store, GPG and many more. And we will be able to recreate our ready-to-use vm, whenever we want ...
We have the same preconditions as last time. We will start from a clean virtual machine having xubuntu 16.4.2LTS and ssh-server installed. You can find a more detailed description on how to create a vm in the first post of this series. Keep the used credentials in your mind for first time provisioning.
Let's start and clone the dda-managed-vm:
git clone -b dda-managed-vm-0.4.0 https://github.com/DomainDrivenArchitecture/dda-managed-vm.git
For your context, we use the following configuration schema defined in external_config.clj:
(def ExternalConfigSchema
{:provisioning {:ip s/Str
:login s/Str
:password s/Str}
:user {:name s/Str
:password s/Str
:email s/Str
(s/optional-key :ssh) {:ssh-pub-key s/Str
:ssh-prvate-key s/Str}
(s/optional-key :gpg) {:gpg-public-key s/Str
:gpg-private-key s/Str
:gpg-passphrase s/Str}}})
Now let's put your informations into the configuration file:
./dda-managed-vm/user-config.edn
ifconfig
on the remote virtual machine to find the IP - in our case it is 192.168.56.104) in the line::ip "192.168.56.104"
:login "initial"
:password "secure1234"
:name "test-user"
:password "xxx"
:email "test-user@mydomain.org"
:ssh {:ssh-pub-key "rsa-ssh kfjri5r8irohgn...test.key comment"
:ssh-prvate-key "123Test"}
:gpg {:gpg-public-key "-----BEGIN PGP PUBLIC KEY BLOCK----- ..."
:gpg-private-key "-----BEGIN PGP PUBLIC KEY BLOCK----- ..."
:gpg-passphrase "passphrase"}
Now it's time to bring our configuration to our virtual machine:
(use 'dda.pallet.dda-managed-vm.app.instantiate-existing)
(apply-install)
Your REPL should look somewhat as follows: In case of success, your REPL will finally show: ./logs/pallet.log
The log-level configuration you will find at: dev-resources/logback.xml
Domain Driven Design is quite important in object oriented application development. But why should Domain Driven Design be important in a DevOps world?
Let's think about what's cool and uncool:
user-config.edn
is cool, I think. The DevOps user will be able to easily use our components without being forced to dive deeply into ugly details (like the fact that virtual-box-guest utils are breaking xubuntu x-server since 16.04.02 ...).This thoughts lead us to the idea to strictly separate conventions (we call it domain) from low-level configurations (we call it infra). Both levels are represented through a data-driven API. And this way dda-pallet offers the best of both worlds: the convenience of an easy-to-use domain-level containing conventions e.g. for file locations, as well as the power of an infra-level, which allows you to adjust all kinds of configuration details in case of special or different needs.
Doing so we enable synergy in building an infra-level abstraction together with a world-wide community. The structure of Linux software will be similar enough across companies and countries.
On the domain-level everyone is free to implement his own abstractions and conventions. The domain layer transforms compact configuration data into large infra configuration data. As domain level is pure data transformation, modifying our predefined conventions or develop on your own will be an easy thing to do. Test driven development is one of our architecture goals, in the domain layer unit-tests are easy to implement.
You can find all these ideas in our code: