5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Lambda Web Adapterを使ってaxumを手軽にサーバーレス化

Posted at

目的

既にAWS Lambda Web Adapterに関する記事はたくさんあるので、どちらかというと備忘録的な目的になります。
ただ、自分が読んだ記事通りだとarm64アーキテクチャでランタイムエラーが起きてしまい試行錯誤することになったので、同じくうまくいかず躓いてしまったという人がいれば参考になるかもしれません。

前提

環境
OS Mac(M1)
Language Rust 1.89.0
Rust Edition 2024
FrameWork axum 0.8
IDE Zed 0.203.4

AWS Lambda Web Adapterの概要

WebアプリケーションをそのままLambda化できるツールです。
ツールといってもDockerfileに1行混ぜ込むだけで良いので、特に操作等は不要です。

Webアプリケーションを簡単にLambdaデプロイできるので、Lambdaから気軽に始めてアクセス負荷が高まったらECSに移行するみたいなことができるようです。

手順

全体の流れは下記の通りです。

  1. 普通にaxumを使ってWebアプリケーションを実装する
    ※AWS Lambda Web Adapterの学習目的なら他のフレームワークでもOK
  2. コンテナイメージ作成時にAWS Lambda Web Adapterをコピーするよう指定
  3. AWS ECRにコンテナイメージをアップロード
  4. AWS Lambda(arm64アーキテクチャ)としてWeb公開
  5. 動作確認

1. 普通にaxumを使ってWebアプリケーションを実装する

今回はAWS Lambda Web Adapterを使うこと自体が目的だったので適当です。

インフォメーション
処理は何でも大丈夫なんですが、AWS Lambda Web Adapterがデフォルトで認識するポート番号が8080なので、ポート番号は8080で合わせておくとお手軽です。
どうしてもポート番号を変えたい場合は一工夫必要になります。

use axum::{Router, routing::get};
use tower_http::trace::TraceLayer;

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(root_handler))
        .route("/health", get(health_handler))
        .layer(TraceLayer::new_for_http());

    let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
    tracing::debug!("listening on {}", listener.local_addr().unwrap());
    axum::serve(listener, app).await.unwrap();
}

async fn root_handler() -> &'static str {
    "Hello, axum!"
}

async fn health_handler() -> &'static str {
    "OK"
}

2. コンテナ作成時にAWS Lambda Web Adapterをコピーするよう指定

Dockerを使ってコンテナを定義します。
ここで、AWS Lambda Web Adapterをコピー指定します。バージョンは0.9.1を使用。

インフォメーション
自分が参考にした記事だとcargo buildtarget指定がなかったのですが、AWS Lambdaのアーキテクチャでarm64を指定したいなら必要です。

FROM rust:1.89.0-slim-bookworm as builder
WORKDIR /app
RUN rustup target add aarch64-unknown-linux-musl

COPY Cargo.toml Cargo.lock /app/
RUN mkdir src
RUN echo "fn main() {}" > src/main.rs
RUN cargo build --release --target aarch64-unknown-linux-musl
RUN rm -r src

COPY src /app/src
RUN cargo build --release --target aarch64-unknown-linux-musl

FROM gcr.io/distroless/cc-debian12
COPY --from=builder /app/target/aarch64-unknown-linux-musl/release/axum-test /app/
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.9.1 /lambda-adapter /opt/extensions/lambda-adapter

CMD ["/app/axum-test"]

3. AWS ECRにコンテナイメージをアップロード

コンテナイメージを作成してECRのリポジトリにアップロードします。

インフォメーション
ECRのプッシュコマンド表示を参考にしながら進めれば基本問題なしです。

push command

ただし、arm64向けビルドであればDockerイメージ作成時に--platform linux/arm64のオプションをつける必要があるのでそこだけ注意。

docker build

4. AWS Lambda(arm64アーキテクチャ)としてWeb公開

AWS Lambdaにて、下記条件で関数を作成します。
権限は新規作成するか、Lambda実行できるRoleが既にあればそちらを指定してください。

  • アーキテクチャをarm64に設定
  • 関数URLを有効化オプションにチェックを入れる

lambda1

今回はパッと動作確認したいので、認証タイプをNONE(パブリックURL化)にしました。

lambda2

5. 動作確認

生成された関数URLをクリックしてみて動作確認しましょう。
サンプル通りの場合、Hello, axum!と表示されれば成功です。

感想

ビルドアーキテクチャ間違えていたり、初期化の中でエラーが起きてしまったりすると、詳細なエラー情報が確認できなくて(Runtime.xxxError系で参考にならない)結構大変でした。

ただ、AWS Lambda Web AdapterによってLambda専用で処理を書く必要がなく、普通にWebアプリケーションとして実装すればそのままLambdaとしても使えるというのは非常に気持ちのいい体験でした。

Cold Start気にならないなら色々やれそうな気がしています。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?