diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..24a8e87 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md index 17d86a0..7a2ddaa 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,5 @@ -# Terraform +# Yandex Cloud K8S -## Prerequisites +Terraform + cloud-init configuration for one click partialy managed HA K8S cluster. -Ensure you have the following installed on your system: - -- [Terraform](https://developer.hashicorp.com/terraform) (latest version recommended) - -## Main (`./main`) - -Main Terraform module for infrastructure - -## Service (`./service`) - -Terraform module to create service account for [Main](#main-main) terraform module. - -## CheatSheet - -```bash -# Init Terraform module -../scripts/init - -# Set required variables for terraform from dotenv file -export $(grep -v '^#' ./.env | xargs) - -# Unset required variables for terraform from dotenv file -unset $(grep -v '^#' ./.env | sed 's/=.*//' | xargs) -``` +![arch](./assets/img/arch.png) diff --git a/assets/img/arch.png b/assets/img/arch.png new file mode 100644 index 0000000..28420a3 Binary files /dev/null and b/assets/img/arch.png differ diff --git a/ci/scripts/upload-frontend b/ci/scripts/upload-frontend new file mode 100755 index 0000000..7b51a0a --- /dev/null +++ b/ci/scripts/upload-frontend @@ -0,0 +1,87 @@ +#!/bin/bash + +set -euo pipefail + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + echo "Example: $0 ./build s3://my-bucket/optional/basepath" + exit 1 +fi + +SOURCE_DIR=${1%/} +DEST_S3_URI=$2 + +BUCKET="${DEST_S3_URI#s3://}" +BUCKET="${BUCKET%%/*}" + +BASE="${DEST_S3_URI#s3://$BUCKET}" +BASE="${BASE#/}" +BASE="${BASE%/}" + +prefix_for() { + local p="$1" + if [ -n "$BASE" ]; then + printf "%s/%s" "$BASE" "$p" + else + printf "%s" "$p" + fi +} + +LOCK_KEY="$(prefix_for deploy.lock)" +NEW_PREFIX="$(prefix_for new)" +CUR_PREFIX="$(prefix_for current)" +OLD_PREFIX="$(prefix_for old)" + +if ! command -v yc >/dev/null 2>&1; then + echo "Error: yc CLI not found" + exit 1 +fi + +while true; do + LOCK_COUNT=$(yc storage s3api list-objects --bucket "$BUCKET" --prefix "$LOCK_KEY" --max-keys 1 --format json --jq '((.Contents? // .contents?) | length)') + if [ "${LOCK_COUNT:-0}" -eq 0 ]; then + break + fi + sleep 2 +done + +TMP_LOCK=$(mktemp) || { echo "mktemp failed"; exit 1; } +trap 'yc storage s3 rm "s3://'"$BUCKET"'/'"$LOCK_KEY"'" >/dev/null 2>&1 || true; rm -f "$TMP_LOCK"' EXIT + +printf '%s\n' "$$ $(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$TMP_LOCK" +yc storage s3 cp "$TMP_LOCK" "s3://$BUCKET/$LOCK_KEY" + +find "$SOURCE_DIR" -type f -print0 | while IFS= read -r -d '' FILE_PATH; do + RELATIVE_PATH=${FILE_PATH#"$SOURCE_DIR"/} + DETECTED_MIME=$(file --brief --mime-type "$FILE_PATH") + EXT="${FILE_PATH##*.}" + MIME_TYPE="$DETECTED_MIME" + + if [[ "$DETECTED_MIME" == "text/plain" || "$DETECTED_MIME" == "application/octet-stream" ]]; then + case "$EXT" in + css) MIME_TYPE="text/css" ;; + js) MIME_TYPE="application/javascript" ;; + html) MIME_TYPE="text/html" ;; + json) MIME_TYPE="application/json" ;; + svg) MIME_TYPE="image/svg+xml" ;; + png) MIME_TYPE="image/png" ;; + jpg|jpeg) MIME_TYPE="image/jpeg" ;; + gif) MIME_TYPE="image/gif" ;; + woff) MIME_TYPE="font/woff" ;; + woff2) MIME_TYPE="font/woff2" ;; + ttf) MIME_TYPE="font/ttf" ;; + eot) MIME_TYPE="application/vnd.ms-fontobject" ;; + *) MIME_TYPE="$DETECTED_MIME" ;; + esac + fi + + DEST="s3://$BUCKET/$NEW_PREFIX/$RELATIVE_PATH" + echo "Uploading $FILE_PATH -> $DEST (Content-Type: $MIME_TYPE)" + yc storage s3 cp "$FILE_PATH" "$DEST" --content-type="$MIME_TYPE" +done + +yc storage s3 rm "s3://$BUCKET/$OLD_PREFIX/" --recursive || true +yc storage s3 mv "s3://$BUCKET/$CUR_PREFIX/" "s3://$BUCKET/$OLD_PREFIX/" --recursive || true +yc storage s3 mv "s3://$BUCKET/$NEW_PREFIX/" "s3://$BUCKET/$CUR_PREFIX/" --recursive + +echo "Deploy finished. Serve from s3://$BUCKET/$CUR_PREFIX/"