Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Delibird
Delibird is a URL shortening system with various features such as measurement, password protection, and redirects with digital signatures, in addition to simple redirection.

This application supports custom domains, enabling domain-specific management pages and user management, and can be implemented with a fully serverless architecture using AWS Lambda.

It allows you to deploy your own shortened link service with full access to all features, delivering far superior cost performance compared to existing cloud-based shortening services.

<img width="1512" height="753" alt="Delibird" src="https://github.com/user-attachments/assets/acbc692e-908d-42c7-b69a-53a24ea75231" />


## Requirements

Expand Down Expand Up @@ -51,4 +59,4 @@ make plan-{environment name}

```bash
make apply-{environment name}
```
```
98 changes: 98 additions & 0 deletions lambda/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/bin/bash
set -e

# このスクリプトのディレクトリを取得
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# LAMBDA_NAMEが指定されていればそれを使用、なければエラー
if [ -n "${LAMBDA_NAME}" ]; then
LAMBDA_NAME="${LAMBDA_NAME}"
else
echo "Error: LAMBDA_NAME environment variable is not set." >&2
exit 1
fi
LAMBDA_DIR="${SCRIPT_DIR}/${LAMBDA_NAME}"

# BUILD_OUTPUT_DIRが指定されていればそれを使用、なければエラー
if [ -n "${BUILD_OUTPUT_DIR}" ]; then
BUILD_DIR="${BUILD_OUTPUT_DIR}/${LAMBDA_NAME}"
else
echo "Error: BUILD_OUTPUT_DIR environment variable is not set." >&2
exit 1
fi

echo "Building Fuction: ${LAMBDA_NAME}..."
echo "Output directory: ${BUILD_DIR}"

# 既存のbuildディレクトリをクリーンアップ
rm -rf "${BUILD_DIR}"
mkdir -p "${BUILD_DIR}"

# requirements.txtから依存関係をインストール
if [ -f "${LAMBDA_DIR}/requirements.txt" ]; then
echo "Installing dependencies from requirements.txt..."
# Lambdaを/var/taskにマウントして、buildディレクトリを/delibird/outputにマウント
# /delibird/outputを通して、buildディレクトリにパッケージをインストール
docker run --rm \
-v "${LAMBDA_DIR}":/var/task \
-v "${BUILD_DIR}":/delibird/output \
public.ecr.aws/sam/build-python3.13:latest-arm64 \
pip install -r "requirements.txt" -t "/delibird/output" --upgrade
else
echo "Error: No requirements.txt found" >&2
exit 1
fi

# カスタムコード(ddb, utilなど)をコピー
echo "Copying custom code..."

# 除外するファイル/ディレクトリのパターン
EXCLUDE_PATTERNS=("__pycache__" "*.pyc" "*.pyo" "*.sh" "*.md" ".git" ".gitignore" "*.txt")

copied_count=0
for item in "${LAMBDA_DIR}"/*; do
if [ ! -e "$item" ]; then
continue # ファイルが存在しない場合はスキップ
fi

item_name=$(basename "$item")
should_exclude=false

# 除外パターンにマッチするかチェック
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
# shellcheck disable=SC2254
case "$item_name" in
$pattern)
should_exclude=true
break
;;
esac
done

if [ "$should_exclude" = false ]; then
echo "Copying: $item_name"
cp -r "$item" "${BUILD_DIR}/"
((copied_count++))
else
echo "Skipping: $item_name"
fi
done

# コピーされたファイルがあるか確認
if [ "$copied_count" -eq 0 ]; then
echo "Error: No custom code was copied to ${BUILD_DIR}" >&2
exit 1
fi

echo "Function ${LAMBDA_NAME} build completed successfully."

# ビルド成果物の内容を表示
echo ""
echo "Build output contents:"
echo "----------------------"
echo "Python packages:"
ls -lh "${BUILD_DIR}" | head -20
echo ""
echo "Total size:"
du -sh "${BUILD_DIR}"

8 changes: 7 additions & 1 deletion lambda/layers/common/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ mkdir -p "${PYTHON_DIR}"
# requirements.txtから依存関係をインストール
if [ -f "${LAYER_DIR}/python/requirements.txt" ]; then
echo "Installing dependencies from requirements.txt..."
pip install -r "${LAYER_DIR}/python/requirements.txt" -t "${PYTHON_DIR}" --upgrade
# Lambdaを/var/taskにマウントして、buildディレクトリを/delibird/outputにマウント
# /delibird/outputを通して、buildディレクトリにパッケージをインストール
docker run --rm \
-v "${LAYER_DIR}/python":/var/task \
-v "${PYTHON_DIR}":/delibird/output \
public.ecr.aws/sam/build-python3.13:latest-arm64 \
pip install -r "requirements.txt" -t "/delibird/output" --upgrade
else
echo "Error: No requirements.txt found" >&2
exit 1
Expand Down
44 changes: 42 additions & 2 deletions modules/aws_lambda/function.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,53 @@
# Lambda Layerのソースディレクトリとビルド出力先
locals {
lambda_dir = "${path.root}/../../lambda"
}

# build functions
resource "null_resource" "build_redirect_request" {
triggers = {
files = sha256(join("", [
for f in fileset("${local.lambda_dir}/redirect_request", "**/*") :
filesha256("${local.lambda_dir}/redirect_request/${f}")
]))
build_script = filesha256("${local.lambda_dir}/build.sh")
}

provisioner "local-exec" {
command = "chmod +x ${local.lambda_dir}/build.sh && LAMBDA_NAME=redirect_request BUILD_OUTPUT_DIR=${path.root}/.build ${local.lambda_dir}/build.sh"
working_dir = path.root
}
}

resource "null_resource" "build_admin_portal" {
triggers = {
files = sha256(join("", [
for f in fileset("${local.lambda_dir}/admin_portal", "**/*") :
filesha256("${local.lambda_dir}/admin_portal/${f}")
]))
build_script = filesha256("${local.lambda_dir}/build.sh")
}

provisioner "local-exec" {
command = "chmod +x ${local.lambda_dir}/build.sh && LAMBDA_NAME=admin_portal BUILD_OUTPUT_DIR=${path.root}/.build ${local.lambda_dir}/build.sh"
working_dir = path.root
}
}

data "archive_file" "redirect_request" {
type = "zip"
source_dir = "${path.root}/../../lambda/redirect_request"
source_dir = "${path.root}/.build/redirect_request"
output_path = "${path.root}/.build/redirect_request.zip"

depends_on = [null_resource.build_redirect_request]
}

data "archive_file" "admin_portal" {
type = "zip"
source_dir = "${path.root}/../../lambda/admin_portal"
source_dir = "${path.root}/.build/admin_portal"
output_path = "${path.root}/.build/admin_portal.zip"

depends_on = [null_resource.build_admin_portal]
}

resource "aws_lambda_function" "redirect_request" {
Expand Down