Cloud-Init

Based on Shell reusable shell functions for typical Cloud-Init user-data usage scenarios.

  • Storage
  • Utilities for storage handling

  • Lego
  • Utilities for LetsEncrypt certificate creation with lego

  • Usage
  • Usage examples

Architecture

To work around the size limitation of user-data scripts and also make the scripts easier to maintain and test, Solidblocks cloud init is distributed as a compressed archive, that automatically gets downloaded and extracted to /solidblocks/... on the cloud VM. After running the bootstrap_solidblocks function all library functions can be used, like shown in the example below.

Testing

To ensure functionality of all library functions a full integration test for x86 and the arm platform is executed from test using testinfra asserting the results in test/test_cloud_init.py

Kitchen Sink Usage Example



#!/usr/bin/env bash

set -eu -o pipefail

DIR="$(cd "$(dirname "$0")" ; pwd -P)"

export SOLIDBLOCKS_DIR="${SOLIDBLOCKS_DIR:-/solidblocks}"
export SOLIDBLOCKS_DEVELOPMENT_MODE="${SOLIDBLOCKS_DEVELOPMENT_MODE:-0}"

SOLIDBLOCKS_VERSION="v0.2.5"
SOLIDBLOCKS_CLOUD_CHECKSUM="d9446dd6bc753d45a40e9792d7370f28ea165d0b1f10cd001d7c9b1adde47932"

function bootstrap_package_update {
  apt-get update
}

function bootstrap_package_update_system() {
    apt-get \
        -o Dpkg::Options::="--force-confnew" \
        --force-yes \
        -fuy \
        dist-upgrade
}

function bootstrap_package_check_and_install {
	local package=${1}

	echo -n "checking if package '${package}' is installed..."

	if [[ $(dpkg-query -W -f='${Status}' "${package}" 2>/dev/null | grep -c "ok installed") -eq 0 ]];
	then
		echo "not found, installing now"
		while ! DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -qq -y "${package}"; do
    		echo "installing failed retrying in 30 seconds"
    		sleep 30
    		apt-get update
		done
	else
		echo "ok"
	fi
}

function bootstrap_solidblocks() {
  bootstrap_package_update
  bootstrap_package_check_and_install "unzip"

  groupadd solidblocks
  useradd solidblocks -g solidblocks

  # shellcheck disable=SC2086
  mkdir -p ${SOLIDBLOCKS_DIR}/{templates,lib,secrets}

  chmod 770 ${SOLIDBLOCKS_DIR}
  chown solidblocks:solidblocks ${SOLIDBLOCKS_DIR}

  chmod -R 770 ${SOLIDBLOCKS_DIR}
  chown -R solidblocks:solidblocks ${SOLIDBLOCKS_DIR}

  chmod -R 700 ${SOLIDBLOCKS_DIR}/secrets

  local temp_file="$(mktemp)"

  curl -v -L "${SOLIDBLOCKS_BASE_URL:-https://github.com}/pellepelster/solidblocks/releases/download/${SOLIDBLOCKS_VERSION}/solidblocks-cloud-init-${SOLIDBLOCKS_VERSION}.zip" > "${temp_file}"
  echo "${SOLIDBLOCKS_CLOUD_CHECKSUM}  ${temp_file}" | sha256sum -c

  (
    cd "${SOLIDBLOCKS_DIR}" || exit 1
    unzip "${temp_file}"
    rm -rf "${temp_file}"
  )

  source "${SOLIDBLOCKS_DIR}/lib/storage.sh"
  source "${SOLIDBLOCKS_DIR}/lib/lego.sh"
}

bootstrap_solidblocks

storage_mount "/dev/sdb1" "/data1"

export HETZNER_API_KEY="${hetzner_dns_api_token}"
export HETZNER_HTTP_TIMEOUT="10"

lego_setup_dns "/data1/ssl" "contact@example.com" "test1.example.com test2.example.com" "hetzner"