コンテンツにスキップ

Loco連携

Rust アプリケーション(Loco など)では、magic-pocket-rs crate を使って環境変数をセットアップします。 Django の set_envs() に相当する機能を Rust で提供します。


セットアップ

Cargo.toml に依存を追加します。

[dependencies]
magic-pocket-rs = { git = "https://github.com/worgue/magic-pocket.git" }
lambda_http = "0.14"
loco-rs = "0.14"
tokio = { version = "1", features = ["full"] }

Django では apig-wsgi が WSGI アプリを Lambda ハンドラーに変換しますが、Loco(axum)では lambda_http が axum Router を直接 Lambda ハンドラーとして使えます。フレームワーク側で完結するため、Lambda Web Adapter のような外部 Extension は不要です。


Lambda エントリポイント

src/bin/lambda.rs を作成します。

use loco_rs::boot::{create_app, StartMode};
use loco_rs::config::Config;
use loco_rs::environment::Environment;

use myapp::app::App;
use myapp::migration::Migrator;

#[tokio::main]
async fn main() -> Result<(), lambda_http::Error> {
    magic_pocket_rs::set_envs().await.unwrap();

    let environment: Environment = "production".parse().unwrap();
    let config = Config::new(&environment)?;
    let boot = create_app::<App, Migrator>(
        StartMode::ServerOnly,
        &environment,
        config,
    )
    .await?;

    lambda_http::run(boot.router.expect("no router")).await
}

set_envs()

set_envs() は、Secrets Manager / SSM からシークレットを取得し、CloudFormation Output から API Gateway のホスト情報を取得して、すべて環境変数にセットします。セットされる環境変数の一覧は「実行環境」を参照してください。

関数 説明
set_envs() シークレット + AWS リソース情報をすべてセット
set_envs_from_secrets(stage) シークレットのみセット
set_envs_from_resources(stage) AWS リソース情報のみセット

POCKET_STAGE が設定されていない場合、シークレット取得はスキップされます(ローカル環境での安全動作)。


pocket.toml の構成例

[general]
region = "ap-northeast-1"
stages = ["dev", "prod"]

[s3]

[neon]
project_name = "dev-myproject"

[awscontainer]
dockerfile_path = "pocket.Dockerfile"

[awscontainer.handlers.wsgi]
command = "myapp-lambda"

[dev.awscontainer.handlers.wsgi]
apigateway = {}

[awscontainer.secrets.managed]
LOCO_SECRET_KEY = { type = "password", options = { length = 50 } }
DATABASE_URL = { type = "neon_database_url" }

Dockerfile の例

FROM rust:1-bookworm AS builder
WORKDIR /app
COPY . .
RUN cargo build --release --bin myapp-lambda

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/myapp-lambda /usr/local/bin/
COPY --from=builder /app/config /app/config
COPY pocket.runtime.toml /app/pocket.runtime.toml
WORKDIR /app
CMD ["myapp-lambda"]

command は Docker の CMD をオーバーライドするため、Dockerfile では CMD のみを使用し ENTRYPOINT は設定しないことを推奨します。詳細は「設定ファイル - awscontainer.handlers」を参照してください。


注意点

production.yaml の環境変数クォート

magic-pocket が生成するシークレット(type = "password")には *, !, # 等の YAML 特殊文字が含まれる場合があります。Loco の設定テンプレートでは環境変数を必ずクォートで囲んでください。

# NG - SECRET_KEY に * が含まれると YAML パースが壊れる
secret: {{ get_env(name="SECRET_KEY") }}

# OK
secret: "{{ get_env(name="SECRET_KEY") }}"
database:
  uri: "{{ get_env(name="DATABASE_URL") }}"

static ミドルウェアの無効化

Loco のデフォルト production.yaml には static.must_exist: truefrontend/dist を参照する設定があります。Lambda コンテナにフロントエンドを含めない場合は無効にしてください。

static:
  enable: false

DB 接続タイムアウト

Neon がアプリケーションと異なるリージョンにある場合、デフォルトの接続タイムアウトでは不足する場合があります。クロスリージョン接続では余裕を持った値を設定してください。

database:
  connect_timeout: 5000
  idle_timeout: 5000

Neon のリージョン選択

Neon プロジェクトは Lambda と同じリージョン(または近いリージョン)に作成することを推奨します。レイテンシと接続タイムアウトの問題を回避できます。