Design & Development
The overall design of Solidblocks cloud is led by the following rules
- Only basic building blocks that are widely available across the majority of cloud providers are used, e.g. VM, storage disks, DNS and private networking to keep the setup simple and portable
- Instead of complex container schedulers or API driven control-planes Solidblocks clouds relies on plain Unix services and docker containers started with systemd
- No extra or intermediary state is used, the source of truth is the configuration file. Resources are identified solely based on its name
- Apart from the data and backup disks, every created resource must be treated as ephemeral. It must always be possible to re-provision from scratch and get the same system-state as before
- The created VMs can survive standalone, it must always be possible to use them without Solidblocks cloud
- It is open for integration of resources that are managed out of band with other IaC tools
- It optimizes for MTTR over MTBF, instead of complicated failover or rolling update processes, short outages during service deployments are acceptable
Overview
Solidblocks cloud uses a cyclic process starting with a high level configuration that is transformed into a runtime model defining all resources that are needed to implement the services. During the plan phase this model is compared with the running state inside the cloud, and a diff is created containing all missing or changed resources. Based on this diff during the apply phase the running state is diverged towards the intended model derived from the configuration.
Provisioning Process
Configuration to model
The configuration is read and transformed into an internal model. This model expands the configuration into the different infrastructure components that are needed to fulfill the requested service configuration. E.g. a service of the type docker is built from:
- a VM running the service
- a disk holding the services data
- a backup disk holding the data backups
- a DNS entry pointing to the service
- a firewall rule restricting access to the service
- …
Running state to diff
The infrastructure resources from the created model that should be running are compared with the currently running state. From this comparison a diff is created containing the resources that need to be created or modified.
Diff to Resources
The changed resources from the diff are then created or modified to achieve the desired state from the model.
Provisioning Methods
Different methodologies are used to provision services.
⓿ Infrastructure API calls
At the lowest layer, cloud resources are created using the public API of the underlying cloud provider.
❶ Cloud-Init
The created machines are started using a service specific cloud-init script that will bootstrap the desired service.
❷ VM Management
If needed VM management tasks are executed over SSH. This could be service start/restart, system updates, file provisioning etc.
❸ Service Configuration
When the VM is started via cloud init, all further service configuration is done via an SSH tunnel port forward to prevent potential sensitive APIs from being exposed on the internet. This could for example be the creation of users and schemas on a database.
Resource Identity
The model and the created resources are linked using a predictable resource names. E.g. for the cloud named cloud1 and the service webservice1 the resource name for the virtual machine will be cloud1-default-webservice1-0 following the pattern <cloud_name>-<envrionment_name>-<service_name>-<index>
Info
Environment (<envrionment_name>) and multiple instance support (<index>) are not yet implemented, but already incorporated in the naming scheme to allow for a smooth transition in the future, see roadmap.
Providers
Providers enable Solidblocks cloud to create all the needed resources like virtual machines, storage volumes, DNS entries or secrets to implement a service. For a minimal cloud configuration at least one of the four different provider types is needed:
SSH key provider Used to load SSH keys that are used for cloud VM management via SSH.
Secret Provider To provision and manage services, secrets are needed for API keys, database users, etc. The secret provider is used to store and retrieve secrets.
Cloud Provider The cloud provider implements the creation of the needed cloud resources like virtual machines, storage volumes, firewall, etc.
Backup Provider Manages the resources needed to store and retrieve backups for disaster recovery purposes.
Development
This chapter gives an overview over the internal structure and core concepts of the Solidblocks Cloud project sources
Configuration Parsing
de.solidblocks.cloud.configuration.ConfigurationFactorys are used to transform the configuration YAML into *Configuration data objects. Each factory defines a list of keywords that it understands where each de.solidblocks.cloud.configuration.Keyword includes name, constraints (range, max length, optional, etc.) and a help that is used to validate the configuration YAML and generate a help for the configuration file format.
For polymorphic lists that can contain different types, the type keyword is used to find the appropriate ConfigurationFactory.
Configuration Validation
When the whole configuration YAML is parsed, the resulting *Configuration data objects are validated by
de.solidblocks.cloud.CloudManager.validatede.solidblocks.cloud.providers.ProviderManager.validateConfigurationde.solidblocks.cloud.services.ServiceManager.validateConfiguration
During validation the data is also enriched (e.g. some providers take parts of their configuration from environment variables) and transformed into *ConfigurationRuntime data objects which are the objects all later processing and provisioning happens on.
Service and Provider Registrations
All the different ConfigurationFactorys, ProviderManagers and ServiceManagers manager are registered and linked by de.solidblocks.cloud.providers.ProviderRegistration respectively de.solidblocks.cloud.services.ServiceRegistration registrations that define
- the
typeof the specific provider or service used to lookup factories during YAML parsing - what kind of
*Configurationclass it understands - what kind of
*ConfigurationRuntimeclass it understands - which
ConfigurationFactoryto use for parsing - which
ProvidderManager/ServiceManagerto use
Infrastructure Provisioners
Each type of resource that is handled like VMs, storage volumes or database users is defined by a triple of the following classes
de.solidblocks.cloud.api.resources.BaseInfrastructureResource(name, dependsOn, ...)- defines the desired state of the resource
de.solidblocks.cloud.api.resources.BaseInfrastructureResourceRuntime(name, ...)- represents the currently running state of the resource
de.solidblocks.cloud.api.resources.InfrastructureResourceLookup(name, dependsOn, ...)- key for looking up a resource
all types share the name attribute which is used to link the model to the running resources (see Resource Identity).
The heavy lifting of resource provisioning and configuration is then handled by
de.solidblocks.cloud.api.InfrastructureResourceProvisioner.diff(resource, ...)- takes a desired resource state and calculates the diff against the current runtime state
de.solidblocks.cloud.api.InfrastructureResourceProvisioner.apply(resource, ...)- diverges the current runtime state towards the desired resource state
de.solidblocks.cloud.api.ResourceLookupProvider.lookup(lookup, ...)- get the current runtime state for a resource
The orchestration of all provisioners happens in de.solidblocks.cloud.provisioner.Provisioner where the plan and apply phases are planned.
Resource Creation and Cloud-Init
The aforementioned resources are created by the services de.solidblocks.cloud.services.ServiceManager.createResources(...) building up on the available InfrastructureResourceProvisioners. The Userdata scripts for VM provisioning via Cloud-Init are generated from the type-safe script and configuration file builders from de.solidblocks.shell.


