AWS | さゆフィクション http://it.kensan.net aws wordpress などなどゆるーく書いてます Fri, 02 Jan 2026 22:17:40 +0000 ja hourly 1 https://wordpress.org/?v=6.9 https://it.kensan.net/wp-content/uploads/2023/03/cropped-icon-32x32.png AWS | さゆフィクション http://it.kensan.net 32 32 Fargate上のRailsアプリを高速でオートスケールさせる https://it.kensan.net/high-speed-fargate-auto-scale.html Fri, 02 Jan 2026 22:17:40 +0000 https://it.kensan.net/?p=2284 Fargate上のRailsアプリを高速でオートスケールさせてみます。

FargateをCPUやメモリなどの標準メトリクスでオートスケールさせると、CloudWatchにメトリクスが送られるまで1~2分程度の遅延が発生すると思います。

さらにCloudWatchアラームでの評価に1分程度かかり

さらにコンテナ起動まで(オートスケール完了まで)1~2分程度かかります。

そのため、オートスケールを設定していてもスケールまで5分程度かかります。

このままですと急なアクセス増に対応できないため、オートスケールの時間を減らしたいと思います!!

どのようにオートスケールを早くするか

以下のような感じで対応していきます。

  1. コンテナからカスタムメトリクスの空きスレッド数をCloudWatchへ送る
  2. Fargateのタスク定義・クラスター・サービスを作成
  3. CloudWatchアラームで高解像度の監視をする
  4. アラームに応じてFargateのオートスケールをする

これで、1~3分程度でスケール可能となります。(起動の時間がアプリケーションによって異なると思いますが、大体この範囲に収まると思います!)

やってみる!

RailsコンテナからカスタムメトリクスをCloudWatchへ送る

Gemfileの修正

以下を追記します。

gem 'aws-sdk-cloudwatch'

cloudwatch_metrics.rbの作成

「config/initializers/cloudwatch_metrics.rb」を以下の内容で作成します。


# config/initializers/cloudwatch_puma_metrics.rb
require 'aws-sdk-cloudwatch'
require 'net/http'
require 'json'

CLOUDWATCH = Aws::CloudWatch::Client.new(region: 'ap-northeast-1')


Thread.new do
  loop do
    begin
      sleep 10
      Rails.logger.info("Sending Puma metrics to CloudWatch")
      uri = URI('http://127.0.0.1:9293/stats')
      res = Net::HTTP.start(uri.host, uri.port, open_timeout: 1, read_timeout: 1) do |http|
        http.get(uri.request_uri)
      end

      stats = JSON.parse(res.body)
      Rails.logger.info(stats.inspect)
      capacity = stats['pool_capacity']

      CLOUDWATCH.put_metric_data(
        namespace: 'Custom/Puma',
        metric_data: [
          {
            metric_name: 'ThreadPoolCapacity',
            value: capacity,
            unit: 'Count',
            storage_resolution: 1,
            dimensions: [
              { name: 'Cluster', value: ENV['ECS_CLUSTER'] || 'default' },
              { name: 'Service', value: ENV['ECS_SERVICE_NAME'] || 'rails' }
            ]
          }
        ]
      )
     
    rescue => e
      Rails.logger.error("CloudWatch Puma metric error: #{e.class}: #{e.message}")
    end
  end
end

lib/request_counter.rbの作成

lib/request_counter.rbを以下の内容で作成します。


class RequestCounter
  def initialize(app)
    @app = app
  end

  def call(env)
    REQUEST_COUNTER.increment
    @app.call(env)
  end
end

config/puma.rbの編集

config/puma.rbに以下を追記します。

activate_control_app 'tcp://127.0.0.1:9293', { no_token: true }

RailsのコンテナイメージをECRにPush

以下のコマンドで、AWSの接続設定をしておきます。

aws configure

次にECRログインします。


aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com

以下のコマンドでリポジトリを作成します。


aws ecr create-repository \
        --repository-name rails \
        --image-scanning-configuration scanOnPush=true \
        --region ap-northeast-1

Railsアプリのタグ作成します

docker tag rails-demo:latest {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

Railsアプリのpushです

docker push {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

Fargateのタスク定義・クラスター・サービスの作成

タスク定義

以下の設定でタスク定義を作成します。

  • イメージ URIにECRのURI
  • コンテナポートを3000

クラスター

以下の設定でクラスターを作成します。

  • コンピューティングキャパシティの取得方法を選択でfargateのみを選択

サービス

以下の設定でサービスを作成します。

  • タスク定義ファミリーで作成したタスク定義を指定
  • ロードバランシング – オプション
    • ロードバランシングを使用にチェック
    • 新しいロードバランサーの作成にチェック
    • 新しいリスナーを作成にチェック
    • 新しいターゲットグループの作成にチェック
      • ポートは3000に設定

CloudWatchアラームで高解像度の監視をする

アラームの作成を以下の設定で作成します

  • メトリクス:ThreadPoolCapacity
  • 統計:最小
  • 期間:10秒
  • 条件
    • ThreadPoolCapacityが3より小さい

アラームに応じてFargateのオートスケールをする

Fargateのサービスの画面からサービスの自動スケーリングの設定をします。以下のような流れで設定します。

  1. スケーリングポリシーを作成
  2. ステップスケーリングを指定
  3. カスタムオプションを指定
  4. スケールアウトを指定
  5. CloudWatch アラームで作成したアラームを指定

    1. 「調整」でスケールするタスク数などを指定

動作確認

JmeterでロードバランサのエンドポイントにHTTPリクエストを送りアラーム状態にすると、90秒程度でコンテナ起動する(ロードバランサのターゲットに登録されるところまで90秒程度)ことが確認できました。

通常5分程度かかるスケーリングが90秒程度でできたので効果ありと思っています。

なお、本検証は以下のSOCI対策を入れた状態で行いました!

AWS ECS-FagateをSeekable OCIを使って高速起動してみる
AWS ECS-FagateをSeekable OCIを使って高速起動してみます。 AWS SOCI (Seekable OCI) は、Fargateのコンテナ起動時間を短縮するための技術です。 Railsのような比較的大きなイメージ(数百
]]>
AWS ECS-FagateをSeekable OCIを使って高速起動してみる https://it.kensan.net/aws-ecs-fagate-seekable-oci.html Sun, 28 Dec 2025 01:45:52 +0000 https://it.kensan.net/?p=2245 AWS ECS-FagateをSeekable OCIを使って高速起動してみます。

AWS SOCI (Seekable OCI) は、Fargateのコンテナ起動時間を短縮するための技術です。

Railsのような比較的大きなイメージ(数百MB〜1GB)を使う場合、従来は「イメージの全ダウンロード完了」を待ってから起動していましたが、Seekable OCIを使うと「必要な部分だけ先にダウンロードして即起動(Lazy Loading)」が可能になります。

今回は「ECRにプッシュしたら勝手にインデックスを作ってくれる仕組み(Lambda)」 を用意して、実際にコンテナを立ち上げてみます。

Seekable OCIを使ってみる

「ECRにプッシュしたら勝手にインデックスを作ってくれる仕組み(Lambda)」 は、AWS SOCI Index BuilderというAWS公式のCloudFomaritonテンプレートが用意されています。

これを使って「ECRにプッシュしたら勝手にインデックスを作ってくれる仕組み(Lambda)」 を構築します。

「ECRにプッシュしたら勝手にインデックスを作ってくれる仕組み(Lambda)」の構築

以下のCloudFormationファイルを使用します。

https://aws-quickstart.s3.us-east-1.amazonaws.com/cfn-ecr-aws-soci-index-builder/templates/SociIndexBuilder.yml

以下のようにスタック作成してリソースを作成します。(パラメータは必要に応じて変更)

今回はRails8.1のコンテナイメージをPushしてみます。

Railsコンテナイメージの作成

ローカルにRailsインストールして、Railsアプリを作成してみます。

以下のコマンドでRailsインストール

sudo gem install rails

以下のコマンドでRailsアプリ作成して、作成したディレクトリに移動

rails new my-app
cd my-app

バージョン確認

rails -v
Rails 8.1.1

Dockerfileも作成されているので「vi Dockerfile」で確認できます。

今回はテスト用なので、Dockerfileを以下のように変更します。

「ENV RAILS_ENV="production"」をコメントアウトして、「ENV RAILS_ENV=development」を追記します。
#ENV RAILS_ENV="production" \
ENV RAILS_ENV=development\

以下のようにENTRYPOINTをコメントアウト
#ENTRYPOINT ["/rails/bin/docker-entrypoint"]

以下のようにEXPOSEとCMDを変更
#EXPOSE 80
#CMD ["./bin/thrust", "./bin/rails", "server"]

EXPOSE 3000
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

config/environments/development.rbに以下を追記します。これがないとFargateで確認時にエラーになります。

config.hosts.clear

コンテナイメージの動作確認

まずはビルドします。

docker build -t rails-demo .

次にコンテナ起動です。

docker run -d -p 3000:3000 \
  -e RAILS_MASTER_KEY=$(cat config/master.key) \
  --name my-app \
  rails-demo

http://localhost:3000/にアクセスして以下のwelcome画面が出ればokです。

Rails8.1のコンテナイメージをECRにPush

以下のコマンドで、AWSの接続設定をしておきます。

aws configure

次にECRログインします。


aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com

以下のコマンドでリポジトリを作成します。


aws ecr create-repository \
        --repository-name rails \
        --image-scanning-configuration scanOnPush=true \
        --region ap-northeast-1

Railsアプリのタグ作成します

docker tag rails-demo:latest {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

Railsアプリのpushです

docker push {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

Push結果

Pushしてしばらくすると、以下のようにECRにSoci Indexが追加されます。

このSoci Indexがコンテナ立ち上げを高速化してくれます。

ECS-Fargateでコンテナを立ち上げてみる

ECS-Fargateの設定は以下をご参照ください

Rails7.1をfargateで動かしてみる
Rails7.1をECS(Amazon Elastic Container Service)-Fagateにデプロイします!!! 以下の順で進めていきます。今回はとりあえずFargate上で動くことをゴールにしますので、MySQLは使いませ

コンテナのパブリックIPにアクセスして以下のように表示されればOKです。

起動時間を見てみる

Seekable OCIの場合

以下のコマンドで確認します。

aws ecs describe-tasks \
  --cluster <クラスター名> \
  --tasks <タスクID> \
  --query "tasks[0].{CreatedAt:createdAt, PullStarted:pullStartedAt, PullStopped:pullStoppedAt, StartedAt:startedAt}"

以下の結果が返ってきました。

{
    "CreatedAt": "2025-12-28T10:39:06.054000+09:00",
    "PullStarted": "2025-12-28T10:39:17.362000+09:00",
    "PullStopped": "2025-12-28T10:39:27.310000+09:00",
    "StartedAt": "2025-12-28T10:39:28.900000+09:00"
}

作成からスタートまで21秒程度です。

Seekable OCIなしの場合

Seekable OCIなしの場合は以下の結果でした。

{
    "CreatedAt": "2025-12-28T10:35:07.750000+09:00",
    "PullStarted": "2025-12-28T10:35:22.546000+09:00",
    "PullStopped": "2025-12-28T10:35:34.311000+09:00",
    "StartedAt": "2025-12-28T10:35:37.096000+09:00"
}

作成からスタートまで30秒です。

まとめ

Seekable OCIでコンテナ起動の高速化をやってみました。

実際の本番運用するRailsアプリでどのくらい高速化するかやってみたいと思います!

]]>
Railsのassetsファイルをサーバで配信した場合の負荷を検証してみる https://it.kensan.net/rails%e3%81%aeassets%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92%e3%82%b5%e3%83%bc%e3%83%90%e3%81%a7%e9%85%8d%e4%bf%a1%e3%81%97%e3%81%9f%e5%a0%b4%e5%90%88%e3%81%ae%e8%b2%a0%e8%8d%b7%e3%82%92%e6%a4%9c.html Sat, 27 Dec 2025 08:41:28 +0000 https://it.kensan.net/?p=2249 Railsのassetsファイルなどの静的ファイルをサーバで配信した場合の負荷を検証してみます。

私はassetsファイルなどの静的ファイルをサーバで配信することが多いのですが、本当はS3において、さらにCloudFrontなどのCDNでキャッシュした方が良いよなと思っていました。

が、、ちょっと面倒で後回しになっていたので、実際にサーバ負荷を確認して、静的ファイルをS3に移動させる労力に見合う結果が得られそうか確認したいと思います。

今回の検証では、サーバはECS Fargateで、1vCPU/2GBを使います。

ECS Fargateは以下の記事のようにたてられます。

AWS ECS-Fagate-Express モードで簡単にコンテナアプリケーションをデプロイしてみる
AWS ECS-Fagate-Express モードで簡単にコンテナアプリケーションをデプロイしてみます! ECS-Fagate-Express モードでは以下のような設定が簡単に行えます。 ACM ALB ECS オートスケール設定 以下

 

assets/images配下に、100KBの画像を格納して、その画像ファイルにjmeterで大量アクセスした際の負荷を検証してみます。

準備

以下のようにFargateコンテナを立ち上げます。

AWS ECS-Fagate-Express モードで簡単にコンテナアプリケーションをデプロイしてみる
AWS ECS-Fagate-Express モードで簡単にコンテナアプリケーションをデプロイしてみます! ECS-Fagate-Express モードでは以下のような設定が簡単に行えます。 ACM ALB ECS オートスケール設定 以下

assets/images配下に100KBの画像を格納します。

以下のコマンドでビルドします。

docker build -t rails-demo .

以下のコマンドでコンテナ起動します。

docker run -d -p 3000:3000 \
  -e RAILS_MASTER_KEY=$(cat config/master.key) \
  --name my-app \
  rails-demo

100KBの画像のパスを取得するため、コンテナにbashで入ります

<コンテナID確認>
docker ps -a
<コンテナにbashではいる>
docker exec -it {コンテナID} /bin/bash

以下のコマンドでパスを取得できます。

bundle exec rails c
helper.asset_url("100KB.png")

jmeter準備

macの場合以下のコマンドでインストールできます

brew install jmeter

インストールしたら

jmeter

とターミナルに打ち込むとjmeterが起動します。

jmeter設定

以下の設定で1分間かけて50スレッド立ち上がるようにします。そのあとは4分間継続して負荷を描けます

Thread Group
  Number of Threads:50
  Ramp-up:60
  Duration:300

 

以下の設定で3000アクセスに設定します。1分で3000アクセスなので、秒間50アクセスです。

Constant Throughput Timer
 Target throughput:3000

以下の設定で画像にアクセスするようにします。

HTTP Request
  protocol:https
  Server Name or ip:ECSのドメイン
  Path:{helper.asset_url("100KB.png")の結果}

確認結果

秒間50アクセスを5分間継続したところ、CPU使用率は14%程度になりました。

サーバはECS Fargateで、1vCPU/2GBです。

14%とそれほど高いとも言えず、何とも言えない結果ですが、利用者数が増えるほど無視できない負荷になることも考えられると思います。

そのため、以下のような対応が必要と思われます…!

  • CloudFrontなどのCDNでのキャッシュ
  • そもそもassetsファイルはS3などにおき、サーバにリクエストが来ないようにする
    • S3に置いたうえで、CDNでキャッシュもした方が良さそう
]]>
AWS ECS-Fagate-Express モードで簡単にコンテナアプリケーションをデプロイしてみる https://it.kensan.net/aws-ecs-fagate-express-mode-rails.html Sat, 27 Dec 2025 06:27:56 +0000 https://it.kensan.net/?p=2243 AWS ECS-Fagate-Express モードで簡単にコンテナアプリケーションをデプロイしてみます!

ECS-Fagate-Express モードでは以下のような設定が簡単に行えます。

  • ACM
  • ALB
  • ECS
  • オートスケール設定

以下の記事を試してみる感じです。

Amazon ECS Express Mode を使用して、インフラストラクチャを複雑化することなく、本番環境に対応したアプリケーションを構築 | Amazon Web Services
コンテナ化されたアプリケーションを本番環境にデプロイするには、ロードバランサー、自動スケーリングポリシー、ネッ

ざっくり以下のような感じでECS-Fagate-Express モードを試してみます!

  1. テスト用のコンテナイメージをECRにPush
    1. 試しにRails8.1のコンテナイメージをPushします
  2. ECSコンソールに移動して、Expressモードを選択して、設定してみる

テスト用のコンテナイメージをECRにPush

テスト用のコンテナイメージをECRにPushします。

今回はRails8.1のコンテナイメージをPushします。

Railsコンテナイメージの作成

ローカルにRailsインストールして、Railsアプリを作成してみます。

以下のコマンドでRailsインストール

sudo gem install rails

以下のコマンドでRailsアプリ作成して、作成したディレクトリに移動

rails new my-app
cd my-app

バージョン確認

rails -v
Rails 8.1.1

Dockerfileも作成されているので「vi Dockerfile」で確認します。

以下のようになっていると思います。

# syntax=docker/dockerfile:1
# check=error=true

# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
# docker build -t my_app .
# docker run -d -p 80:80 -e RAILS_MASTER_KEY= --name my_app my_app

# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.4.2
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

# Rails app lives here
WORKDIR /rails

# Install base packages
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl libjemalloc2 libvips sqlite3 && \
    ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Set production environment variables and enable jemalloc for reduced memory usage and latency.
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development" \
    LD_PRELOAD="/usr/local/lib/libjemalloc.so"

# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build gems
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential git libyaml-dev pkg-config && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install application gems
COPY Gemfile Gemfile.lock vendor ./

RUN bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
    # -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495
    bundle exec bootsnap precompile -j 1 --gemfile

# Copy application code
COPY . .

# Precompile bootsnap code for faster boot times.
# -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495
RUN bundle exec bootsnap precompile -j 1 app/ lib/

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile




# Final stage for app image
FROM base

# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
    useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash
USER 1000:1000

# Copy built artifacts: gems, application
COPY --chown=rails:rails --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --chown=rails:rails --from=build /rails /rails

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start server via Thruster by default, this can be overwritten at runtime
EXPOSE 80
CMD ["./bin/thrust", "./bin/rails", "server"]

今回はテスト用なので、Dockerfileを以下のように変更します。

「ENV RAILS_ENV="production"」をコメントアウトして、「ENV RAILS_ENV=development」を追記します。
#ENV RAILS_ENV="production" \
ENV RAILS_ENV=development\

以下のようにENTRYPOINTをコメントアウト
#ENTRYPOINT ["/rails/bin/docker-entrypoint"]

以下のようにEXPOSEとCMDを変更
#EXPOSE 80
#CMD ["./bin/thrust", "./bin/rails", "server"]

EXPOSE 3000
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

config/environments/development.rbに以下を追記します。これがないとFargateで確認時にエラーになります。

config.hosts.clear

コンテナイメージの動作確認

まずはビルドします。

docker build -t rails-demo .

次にコンテナ起動です。

docker run -d -p 3000:3000 \
  -e RAILS_MASTER_KEY=$(cat config/master.key) \
  --name my-app \
  rails-demo

http://localhost:3000/にアクセスして以下のwelcome画面が出ればokです。

Rails8.1のコンテナイメージをECRにPush

以下のコマンドで、AWSの接続設定をしておきます。

aws configure

次にECRログインします。


aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com

以下のコマンドでリポジトリを作成します。


aws ecr create-repository \
        --repository-name rails \
        --image-scanning-configuration scanOnPush=true \
        --region ap-northeast-1

Railsアプリのタグ作成します

docker tag rails-demo:latest {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

Railsアプリのpushです

docker push {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

ECSコンソールに移動して、Expressモードを選択して、設定してみる

  1. ECSコンソールに移動します
  2. Expressモードを選択します
    1. イメージ URIでは先ほどpushしたECRのイメージを選択します
    2. その他の設定のコンテナポートは3000を指定します。
  3. 作成ボタン押下

Expressモードで作成時はCPUアーキテクチャを設定できないようです。

ARMを使う場合は、作成後にタスク定義からCPUアーキテクチャを変更する必要あがあります。

動作確認

ECSコンソールのアプリケーション URLにアクセスすると以下のようにRailsが起動できました!

以下のようにオートスケールも自動的に設定されています。

素晴らしいー

]]>
Laravel 11をAWS Lambdaで動くようにして簡単なAPIを作ってみる https://it.kensan.net/laravel-11-aws-lambda.html Sat, 21 Dec 2024 01:56:12 +0000 http://43.207.185.157/it/?p=2180 Laravel 11をAWS Lambdaで動くようにして簡単なAPIを作ってみます。

ちなみに私は割とPHP初心者です。

初心者ですが、これからAPI作成するならPHPが良いと思っています。

PHPが良い理由は、実装できる人が多いと思っていて、いざとなれば他の人(他の会社)に協力を仰ぎやすそうだからです。インターネット上に情報もいっぱいあるというアドバンテージもあると思います。

フレームワークは、PHPの中で一番ポピュラーという理由からLaravel!と考えています。

まずは、作成する環境について記載していきます。

 

 

作成する環境の構成

以下の構成で動かしてみます。

  • プログラム
    • Laravel
  • AWSリソース
    • API Gateway
    • Lambda

実際に、Laravel 11をAWS Lambdaで動かしてみます!!

Laravel 11をAWS Lambdaで動かしてみる

まずはLaravelプロジェクトを作成します。

Laravelプロジェクトの作成

以下のコマンドでLaravelプロジェクトを作成します。

composer create-project laravel/laravel lambda_test

プロジェクト作成ができたら、Laravelバージョンを確認します

cd lambda_test/
php artisan -V
Laravel Framework 11.36.1

上記のようにLaravelバージョンが確認できればOKです。

AWSにデプロイする準備

以下のコマンドでAWSのアクセスキーとシークレットキーを設定します

aws configure

アクセスキーとシークレットキーを設定後は、以下のような簡単なコマンドを使用して(以下はバケットの一覧を表示する例)、設定に成功しているか確認できます。

aws s3 ls

次にserverless frameworkをインストールします。

npm install -g serverless

次にbrefをインストールします。

composer require bref/bref bref/laravel-bridge --update-with-dependencies

次に serverless.yamlを生成します。

php artisan vendor:publish --tag=serverless-config

serverless.yamlのregionを以下の通り変更しておきます。(これで、デプロイ先を東京リージョンに変更しています。)

region: ap-northeast-1

serverless.yamlのruntimeも以下の通り変更しておきます。

    web:
        runtime: php-84-fpm
    artisan:
        runtime: php-84-console

 

修正後のserverless.yamlの全体は以下です。


service: laravel

provider:
    name: aws
    # The AWS region in which to deploy (us-east-1 is the default)
    region: ap-northeast-1
    # Environment variables
    environment:
        APP_ENV: production # Or use ${sls:stage} if you want the environment to match the stage
        SESSION_DRIVER: cookie # Change to database if you have set up a database

package:
    # Files and directories to exclude from deployment
    patterns:
        - '!node_modules/**'
        - '!public/storage'
        - '!resources/assets/**'
        - '!storage/**'
        - '!tests/**'
        - '!database/*.sqlite'

functions:

    # This function runs the Laravel website/API
    web:
        handler: public/index.php
        runtime: php-84-fpm
        timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
        events:
            - httpApi: '*'

    # This function lets us run artisan commands in Lambda
    artisan:
        handler: artisan
        runtime: php-84-console
        timeout: 720 # in seconds
        # Uncomment to also run the scheduler every minute
        #events:
        #    - schedule:
        #          rate: rate(1 minute)
        #          input: '"schedule:run"'

plugins:
    # We need to include the Bref plugin
    - ./vendor/bref/bref

デプロイしてみる

以下のコマンドでデプロイできます

serverless deploy

以下が出てきた場合はLogin/Registerを選択するとWEBブラウザが開くと思うので、ログイン(アカウントを持っていない場合作成)します。


Please login/register or enter your license key: … 
❯ Login/Register
  Get A License
  Enter A License Key
  Explain Licensing Basics

デプロイができると以下のようにエンドポイントが表示されます。

endpoint: ANY - ****************

動作確認

エンドポイントにアクセスし、以下のように画面表示されればOKです。

簡単なAPIを作ってみる

以下のコマンドでコントローラを作成

php artisan make:controller ApiProductController

コントローラを以下のとおり実装


namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ApiProductController extends Controller
{
    public function index()
    {
        $products = [];
        $products['id'] = 1;
        $products['name'] = '商品名';
        return response()->json($products, 200);
    }
}

ルーティング(routes/web.php)ファイルに以下を追加

Route::get('/api', 'App\Http\Controllers\ApiProductController@index');

以下のコマンドでデプロイできます

serverless deploy

「エンドポイント/api」にアクセスして、以下のレスポンスが返って来れば成功です。


{
  "id": 1,
  "name": "商品名"
}

Laravelで作ったAPIをLambdaで動かす際に使うと良さそうAWSサービスは何か

API Gatewayは不要?

まず、Lambda関数URLがあるので、API GatewayはなくてもAPIの公開は可能で、この方がAPI Gateway分のコスト削減が可能とは思います。

しかし、API Gatewayを使用した方が、リクエストの認証(IAM、Cognito、APIキーなど)などが使える点で有利かと思います。

DBは?

RDSなら、RDS Proxy × Aurora Serverless v2という選択肢があると思います。

RDS Proxyを使うことで、データベースへの接続をプロキシすることで、データベースへの負荷を軽減できますが、8ACU分の料金がかかります。

費用を抑えたい場合、かつ同時接続数が少ない場合は、RDS ProxyなしでもOKかな。Aurora Serverless v2はゼロキャパシティのスケーリングをサポートしています。

Amazon Aurora Serverless v2 がゼロキャパシティへのスケーリングをサポート - AWS
AWS の新機能についてさらに詳しく知るには、 Amazon Aurora Serverless v2 がゼロキャパシティへのスケーリングをサポート

ユースケースによっては、Aurora Serverless v2とElastiCacheという組み合わせで、ElastiCacheでRDSの情報をキャッシュしてRDSの負荷を抑えるというのもありかと。

もしくは、DynamoDBという選択肢もあると思いますが、設計の難易度が高い…ですね。

まとめ

DBの選択肢など迷うことも多くありますが、プログラムとしてはLaravel(PHP)がいいと思っています!!

]]>
ALB(ロードバランサー)でCloudFront経由のアクセスに絞るときは、カスタム HTTP ヘッダーとマネージドプレフィックスリストを併用する https://it.kensan.net/alb-cloudfront-accesss.html Sun, 30 Jun 2024 07:40:39 +0000 http://35.77.216.202/it/?p=2095 ALB(ロードバランサー)でCloudFront経由のアクセスに絞る方法として、以下の方法があると思います。

  • マネージドプレフィックスリスト(managed prefix list)によりアクセスを絞る
  • カスタム HTTP ヘッダーによりアクセスを絞る

    上記はよく知られた方法かと思いますので、詳細は割愛します。

    本記事で記載したいことは、上記2つを併用した方が安心だよということです。

    まずは、用語の説明からです。

    用語の説明

    マネージドプレフィックスリスト(managed prefix list)とは

    AWS Managed Prefix Listは、AWSによって管理されるIPアドレスのプレフィックスリストです。特定のAWSサービス(例えばCloudFrontやAmazon S3など)のIPアドレス範囲を含んでおり、ネットワーク設定やセキュリティ設定を簡素化するために使用されます。

    本記事では、「マネージドプレフィックスリスト=CloudFrontのIP」として記載します。

    カスタム HTTP ヘッダー

    カスタム HTTP ヘッダーは、HTTP リクエストやレスポンスに含まれるユーザー定義のヘッダーであり、標準の HTTP ヘッダーではカバーされない追加の情報を送信するために使用されるものです。

    なぜ併用した方がいいのか

    ALB(ロードバランサー)でCloudFront経由のアクセスに絞る際に、マネージドプレフィックスリストとカスタム HTTP ヘッダーを併用する場合、以下のようになります。

    • マネージドプレフィックスリスト(managed prefix list)によるアクセス制限
      • IP制限により、CloudFront経由のアクセスを絞る
        • CloudFront経由であれば、別アカウントのものでも許可してしまう
    • カスタム HTTP ヘッダーによるアクセス制限
      • カスタムHTTPヘッダーにより、CloudFront経由にアクセスを絞る
        • 自分が作成したCloudFrontのみにアクセスを絞ることができる
    • →マネージドプレフィックスリストとカスタム HTTP ヘッダーを併用することで、自分が作成したCloudFrontのみにアクセスを絞ることができる

    マネージドプレフィックスリスト(managed prefix list)だけでは、CloudFrontのIP制限のため、CloudFrontからの接続であれば、別アカウントのものでも許可してしまいます。

    そのため、カスタム HTTP ヘッダーも併用が必要となります。カスタム HTTP ヘッダーにより、自分が作成したCloudFrontのみにアクセスを絞ることができます。

    2段階で網をかけておいた方が安心ですね。

    カスタム HTTP ヘッダーとマネージドプレフィックスリストの設定方法

    公式記事に詳しく書いてあるので、以下の公式の記事をご参照ください。

    Application Load Balancer へのアクセスを制限する - Amazon CloudFront
    Amazon CloudFront でカスタムオリジンヘッダーを使用して、ユーザー(閲覧者)が Application Load Balancer に直接アクセスできないようにします。

    まとめ

    ALB(ロードバランサー)でCloudFront経由のアクセスに絞るときは、カスタム HTTP ヘッダーとマネージドプレフィックスリストを併用するのが良いです。

    マネージドプレフィックスリスト単体でも、https(443)の通信にしているから問題とならないケースもあると思いますが、基本的にはカスタム HTTP ヘッダーとマネージドプレフィックスリストを併用した方が安心かと思います。

    ]]>
    AWS API Gatewayの統合タイムアウト制限の29秒が、30秒以上に引き上げ可能になった https://it.kensan.net/amazon-api-gateway-limit-29.html Wed, 05 Jun 2024 04:44:34 +0000 http://35.78.77.41/it/?p=2023 AWS API Gatewayの統合タイムアウト制限の29秒が、30秒以上に引き上げ可能になったようです。

    以下の記事に詳細記載されています。

    Amazon API Gateway 統合のタイムアウト制限が 29 秒から引き上げ - AWS
    AWS の新機能についてさらに詳しく知るには、 Amazon API Gateway 統合のタイムアウト制限が 29 秒から引き上げ

    以下要約です。

    • タイムアウト延長: 以前の29秒からそれ以上に設定可能。
    • 対象API: リージョナルREST APIおよびプライベートREST API。
    • 使用例: Generative AIなど、長時間処理を必要とするワークロードに対応。
    • 追加費用: 追加費用なしで利用可能。
    • 制限: アカウントレベルでクォータ制限の調整が必要。

    要するに、統合タイムアウトは29秒のままだけど、30秒以上に引き上げは可能になったよということです。

    Service Quotasを確認すると以下の通り、統合タイムアウトが、アカウントレベルでの引き上げリクエスト可能になっています。

     

    ]]>
    EC2のcronバッチを「EventBridgeをトリガーにStep Functionsを起動」に置き換えると、エラーハンドリングが快適になる https://it.kensan.net/eventbridge-stepfunctions-ec2-batch.html Mon, 03 Jun 2024 04:08:30 +0000 http://35.79.221.73/it/?p=2013 AWSのEC2で定期的なタスクを自動化するために、cronを使用しているケースも多いと思います。

    しかし、Amazon Linux 2023ではcronがデフォルトで無効になっています。これはcron以外に、cronのようなバッチ実行・定期実行する仕組みがあるということなのかと思い、cronを使わずにE2上でバッチ実行・定期実行する仕組みを考えてみました。

    そして、Amazon EventBridge、AWS Step Functions、およびAWS Systems Manager startAutomationExecutionを組み合わせて、EC2インスタンス上でバッチ・定期実行を試してみましたので、紹介します。

    特に、Step Functionsを使用することで、エラーハンドリングや通知が容易になり、安全にバッチ実行できるようになります。

    エラーハンドリングは以下の状態を把握したいという意味合いです。

    • 成功
    • 失敗
    • タイムアウト(バッチ実行に想定以上に時間がかかっている状態)

    使用するAWSサービスの概要

    Amazon EventBridge

    EventBridgeは、さまざまなAWSサービスやアプリケーションからのイベントをルーティングするサービスです。特定のイベントに基づいてStep Functionsをトリガーするのに適しています。

    AWS Step Functions

    Step Functionsは、複数のAWSサービスを連携させるワークフローを構築するためのサービスです。ワークフロー内でのエラーハンドリングやリトライ処理が容易であり、信頼性の高いタスク管理が可能です。

    AWS Systems Manager startAutomationExecution

    SSM オートメーション ドキュメントに則った処理をしてくれます。

    実際に試してみる

    EC2の準備

    EC2の起動

    バッチ実行環境のEC2を起動します。

    • Amazon Linux 2023 AMIを指定
    • インスタンスタイプは、t4g.nanoなど安いやつを選びます
    • ネットワーク設定で「からの SSH トラフィックを許可」を指定する
      • セキュリティを考慮して、アクセス元は絞った方がいい
    • EC2へはEC2 Instance Connectで接続するため、キーペアはなしでOK

    EC2の中に入る

    • 諸々設定するため、以下の流れで起動したEC2の中に入ります
      • AWSコンソールのEC2の一覧で、該当のEC2を選択して、接続を押下
        • EC2 Instance Connectタブの接続を押下

    EC2上でテスト用のスクリプトを作成

    vi test.sh

    <スクリプトの中身>

    exit 0;

    スクリプトに実行権限をつける

    chmod u+x test.sh

    Step Functionsの準備

    まず、Step Functionsでワークフローを作成します。このワークフローでは、Systems Manager startAutomationExecutionを使用してEC2インスタンス上でバッチジョブを実行します。

    Step Functionsのステートマシンを用意

    以下は、EC2インスタンス上でバッチジョブを実行するようになっています。

    プログラムが異常終了・時間以内(60秒)に終わらない場合、異常終了となります。

    
    {
      "Comment": "A description of my state machine",
      "StartAt": "StartAutomationWaitForCallBack",
      "States": {
        "StartAutomationWaitForCallBack": {
          "Type": "Task",
          "Resource": "arn:aws:states:::aws-sdk:ssm:startAutomationExecution.waitForTaskToken",
          "Parameters": {
            "DocumentName": "SfnRunCommandByInstanceIds",
            "Parameters": {
              "InstanceIds": [
                "{インスタンスID}"
              ],
              "taskToken.$": "States.Array($$.Task.Token)",
              "workingDirectory": [
                "/"
              ],
              "Commands": [
                "/test.sh"
              ],
              "executionTimeout": [
                "60"
              ],
              "deliveryTimeout": [
                "60"
              ],
              "shell": [
                "Shell"
              ]
            }
          },
          "End": true
        }
      }
    }

    以下のポリシーをアタッチします。

    
    {
    	"Version": "2012-10-17",
    	"Statement": [
    		{
    			"Effect": "Allow",
    			"Action": "ssm:StartAutomationExecution",
    			"Resource": "*"
    		}
    	]
    }

    SSM オートメーション ドキュメントの作成

    以下の「SfnRunCommandByInstanceIds」を使用させていただきます。

    GitHub - aws-samples/amazon-stepfunctions-ssm-waitfortasktoken: This pattern implements an automation document wrapper around AWS-RunShellScript execution for a AWS Step Functions waitForTaskToken integration.
    This pattern implements an automation document wrapper around AWS-RunShellScript execution for a AWS Step Functions waitForTaskToken integration. - GitHub - aws...

    SfnRunCommandByInstanceIds」はCloudFormationで作成できます。

    このファイルをダウンロードして、CloudFormationで実行すれば作成できます。

    EventBridgeの設定

    次に、EventBridgeを設定して、Step Functionsの実行をトリガーします。

    1. EventBridgeのルール作成: EventBridgeのダッシュボードに移動し、「ルールを作成」をクリックします。
    2. ルールの設定:
      • イベントソース: スケジュール(例えば、毎日午前2時に実行)を選択し、cron式を設定します。例えば、cron(0 2 * * ? *)
      • ターゲット: ターゲットとして、Step Functionsのステートマシンを選択します。
    3. ターゲットの設定: Step FunctionsのステートマシンのARNを指定します。

    動作確認

    • EC2のtest.shに「exit 0」を記載した状態で実行
      • StepFunctionsが成功していればOK
    • EC2のtest.shに「exit 1」を記載した状態で実行
      • StepFunctionsが失敗していればOK
    • EC2のtest.shに「sleep 61」と「exit 0」を記載した状態で実行
      • タイムアウトするので、StepFunctionsが失敗していればOK

    上記記載の方法のメリットとデメリット

    メリット

    • 柔軟なスケジューリング: EventBridgeを使用することで、定期的なスケジュール設定が容易になります。
    • 詳細なエラーハンドリング: Step Functionsを使用することで、ジョブの成功、失敗、遅延に対する詳細なエラーハンドリングと通知が可能です。

    デメリット

    • 設定の複雑さ: EventBridge、Step Functions、Systems Manager の設定が必要なため、設定手順が複雑になる可能性があります。
    • コスト: 複数のAWSサービスを使用するため、コストが増加する可能性があります。

    まとめ

    Amazon Linux 2023ではcronがデフォルトで無効になっているため、AWSのサービスを組み合わせて定期的なタスクを実行する方法を検討してみました。

    EventBridge、Step Functions、Systems Manager startAutomationExecutionを使用することで、EC2インスタンス上で定期的なバッチジョブを実行し、エラーハンドリングを実現できました。

    エラーの場合、通知するようにしておけばEC2でのバッチ実行も安心かなと思います!

    バッチの実行は他にもいろいろな方法がありますので、気になる方は以下のリンクをクリックくださーい

    https://it.kensan.net/it/aws-batch-method.html
    ]]>
    API Gateway不要!? Lambda関数URLでのAPI構築について考える https://it.kensan.net/lambdafunctionurl-api-gateway.html Sat, 25 May 2024 04:03:57 +0000 http://35.78.183.95/it/?p=1944

    Lambda関数URLで、HTTPリクエストを介して直接Lambda関数を呼び出すことが可能になりました。

    これまで、Lambda関数をAPI経由で実行するためにはAPI Gatewayを使用する必要がありました。しかし、Lambda関数URLの登場により、API Gatewayを使わずにLambda関数を直接実行できるようになりました。

    Lambda関数URLを使うと、API Gatewayのセットアップや管理の手間を省けます。また、API Gatewayが引き起こす遅延やコストも削減できます。

    ただし、API Gatewayには多くの利点もあります。

    この記事では、Lambda関数URLの利用方法とその利点、注意点について詳しく解説します。Lambda関数とAPI Gatewayのどちらを選ぶか迷っている方は、ぜひ参考にしてください。

    Lambda関数URLとは

    Lambda関数URLは、Lambdaで提供される機能の一つで、直接HTTPリクエストを受け取ることができるエンドポイントURLをLambda関数に対して自動的に生成するものです。

    この機能により、API Gatewayなどの中間サービスを使用せずに、簡単にLambda関数をウェブリクエストに対応させることができます。

    主な特徴

    1. 直接アクセス可能: Lambda関数に対して直接HTTPリクエストを送信可能なURLが生成されます。
    2. 簡易な設定: API Gatewayを設定する必要がなく、簡単にHTTPエンドポイントを作成できます。
    3. セキュリティ設定: IAM(Identity and Access Management)ポリシーを使用して、アクセス制御を行うことができます。

    Lambda関数URLの利点

    Lambda関数URLを使用することによる利点は次のとおりです。

    1. 簡単なセットアップ: API Gatewayを使用せずにLambda関数を呼び出すため、API Gatewayのセットアップと管理の手間が省けます。Lambda関数URLは、Lambda関数を公開するための単一のエンドポイントです。
    1. 遅延の低減: API Gatewayを経由せずにLambda関数を直接呼び出すため、API Gatewayによる遅延がなくなります。これにより、リクエストとレスポンスの処理が高速化されます。
    1. コストの削減: Lambda関数URLを使用することでAPI Gatewayのコストを削減することができます。

    次はAPI Gatewayについて記載していきます。

    API Gatewayとは

    API Gatewayは、APIの作成、デプロイ、管理を簡単に行えるツールです。API Gatewayを利用することで、RESTful APIやWebSocket APIを構築し、バックエンドサービスにアクセスするためのエンドポイントを提供することができます。

    主な特徴

    1. API作成とデプロイ: APIのエンドポイントを簡単に作成し、デプロイできます。これにより、フロントエンドとバックエンドの間でデータをやり取りするためのインターフェースを構築できます。
    2. トラフィック管理: スロットリング(リクエスト制限)、キャッシング、モニタリングなどのトラフィック管理機能を提供します。
    3. セキュリティ: IAMポリシー、Cognito、APIキー、OAuth 2.0などを使った認証・認可をサポートし、APIのセキュリティを強化します。
    4. 統合: Lambda関数、EC2、DynamoDB、S3などのAWSサービス、さらにはオンプレミスのシステムとも統合できます。
    5. スケーラビリティと可用性: 自動スケーリングと高可用性が保証されており、大規模なトラフィックにも対応可能です。

    API Gatewayの利点

    API Gatewayの利点は次のとおりです。

    1. セキュリティ: API Gatewayは、APIの認証や承認を行うためのセキュリティ機能を提供します。APIキー、IAMロール、カスタム認証などを使用して、APIのアクセスを制御することができます。
      1. アクセス制御: API Gatewayは、APIのエンドポイントへのアクセス制御を行うための機能を提供します。IP制限、ユーザー認証、アクセスポリシーなどを使用して、APIの使用を管理することができます。これにより、APIの不正利用や過度の負荷を防ぐことができます。

      それでは、次にLambda関数とAPI GatewayでどのようにAPIを構築すれば良いか記載していきます。

        どのようにLambdaのAPIを構築すればいいか

        LambdaのAPIは

        • Lambda関数URLを使用
        • API Gatewayを使用してLambdaを実行

        などいろいろな構築方法があります。実際に構築方法を5つ紹介し、それぞれ特徴やメリットとデメリットについて記載していきます。

        方式 使用するAWSサービス 概要
        API Gateway×Lambda API Gateway

        Lambda

        最もオーソドックスな方式

        API Gatewayの利点を活かせる

        API Gatewayのタイムアウトの上限は29 秒(上限緩和申請可能)なので、29秒以上の処理はエラーとなる

        API Gateway×Step Functions×Lambda API Gateway

        Step Functions

        Lambda

        API Gatewayの利点を活かせる

        API Gatewayのタイムアウトの上限の29 秒(上限緩和申請可能)を超えた処理を実行できる

        Lambda関数URL Lambda Lambda関数URLのエンドポイントURLにアクセスすることで簡単にLambdaを実行できる

        簡単にLambda実行できるので、セキュリティ面が懸念

        タイムアウトはLambdaのタイムアウトの15分

        CloudFront×Lambda関数URL CloudFront

        Lambda

        CloudfrontのOAC を利用して Lambda関数URLを実行する

        Lambda関数URLの実行をCloudFront経由のみに絞れる(CloudFront経由以外はエラーにできる)

        CloudFrontのWAF設定等を活かせる

        タイムアウトはCloudFrontのタイムアウトの60秒(上限緩和申請可能)

        Lambda関数URL(署名付きURL化) Lambda S3の署名付きURLと同じことを、Lambdaの関数URLでやるイメージ

        署名付きURLの場合のみLambdaを実行可能

        タイムアウトはLambdaのタイムアウトの15分

        5つのAPI実行方式の詳細

        API Gateway×Lambda

        使用するAWSサービス

        API Gateway

        Lambda

        概要

        最もオーソドックスな方式

        API Gatewayの利点を活かせる

        API Gatewayのタイムアウトの上限は29 秒(上限緩和申請可能)なので、29秒以上の処理はエラーとなる

        2024.6.4に、タイムアウトの上限は、引き上げ可能となりました。詳細は以下の記事をご参照ください。

        https://it.kensan.net/it/amazon-api-gateway-limit-29.html

        メリット

        最もオーソドックスな方式のため、実装難易度が低い

        API Gatewayの利点を活かせる

        デメリット

        API Gatewayのタイムアウトの上限は29 秒(上限緩和申請可能)なので、29秒以上の処理はエラーとなる

        API Gatewayのコストがかかる

        API Gateway×Step Functions×Lambda

        使用するAWSサービス

        API Gateway

        Step Functions

        Lambda

        概要

        API Gatewayの利点を活かせる

        API Gatewayのタイムアウトの上限の29 秒(上限緩和申請可能)を超えた処理を実行できる

        メリット

        API Gatewayの利点を活かせる

        API Gatewayのタイムアウトの上限の29 秒(上限緩和申請可能)を超えた処理を実行できる。基本的にLambdaのタイムアウトの上限15分までは実行可能。

        Step Functionsの機能を活かせる。Lambdaを複数呼び出したり

        デメリット

        API Gateway/Step Funcstionsのコストがかかる

        Step Funcstionsが入る分、実装難易度が高い

        Lambda関数URL

        使用するAWSサービス

        Lambda

        概要

        Lambda関数URLのエンドポイントURLにアクセスすることで簡単にLambdaを実行できる

        簡単にLambda実行できるので、セキュリティ面が懸念

        タイムアウトはLambdaのタイムアウトの15分

        メリット

        実装難易度が低い

        API Gatewayのタイムアウトの上限の29 秒(上限緩和申請可能)を超えた処理を実行できる。Lambdaのタイムアウトの上限15分までは実行可能。

        デメリット

        セキュリティ面が懸念。独自に対策する必要がある

        CloudFront×Lambda関数URL

        使用するAWSサービス

        CloudFront

        Lambda

        概要

        CloudfrontのOAC を利用して Lambda関数URLを実行する想定

        Lambda関数URLの実行をCloudFront経由のみに絞れる(CloudFront経由以外はエラーにできる)

        CloudFrontのWAF設定等を活かせる

        タイムアウトはCloudFrontのタイムアウトの60秒(上限緩和申請可能)

        メリット

        実装難易度が低い

        CloudFrontのWAF設定等を活かせる

        デメリット

        タイムアウトはCloudFrontのタイムアウトの60秒(上限緩和申請可能)

        構築方法参照URL

        CloudfrontのOAC を利用した Lambdaの 関数URL実行を試してみた | DevelopersIO
        Cloudfront OAC が Lambda関数URLをサポート。 オリジンのLambda関数URLが第三者により直接実行される事を簡単に回避できるようになりました。

        Lambda関数URL(署名付きURL化)

        使用するAWSサービス

        Lambda

        概要

        S3の署名付きURLと同じことをLambdaの関数URLでやるイメージ

        署名付きURLの場合のみLambdaを実行可能

        タイムアウトはLambdaのタイムアウトの15分

        メリット

        実装難易度が低い

        比較的に安全にLambdaを実行できる。(署名付きURLを持っている場合のみLambdaを実行できる)

        タイムアウトはLambdaのタイムアウトの15分

        デメリット

        署名付きURLを発行する仕組みが別途必要

        構築方法参照URL

        実はLambdaの関数URLは署名付きURL化できるよ、29秒の壁も越えられるよ、という話 - Qiita
        この記事を2行で S3の署名付きURLと同じことが、Lambdaの関数URLにもできます Lambdaの署名付きURLを使えば、APIGatewayの29秒タイムアウトを超えてLambdaを実行できます 何が嬉しいの? AIのように時間のかかる処理を、Lambda...

        どのサービスを使えばよいか

        29秒以内に処理が終わる場合

        以下のいずれかを選択するのが良いかと思われます。

        • API Gateway×Lambda
        • CloudFront×Lambda関数URL

        API GateWayの機能を活かしたい場合は「API Gateway×Lambda」を選択しましょ

        30秒〜60秒以内に処理が終わる場合

        実装難易度とセキュリティ面から「CloudFront×Lambda関数URL」が良いと思われます。

        1分〜15分処理に時間がかかる場合

        以下のいずれかを選択するのが良いかと思われます。

        • API Gateway×Step Functions×Lambda
        • Lambda関数URL(署名付きURL化)

        API GateWayの機能を活かしたいか、Step Functionsの実装コストをどう捉えるかを検討して、上記の中から選択するのが良いと思います。

        テスト用にとにかく簡単に動かしたい

        実装難易度の面から「Lambda関数URL」が良いと思われます。

        ]]>
        Rails7.1をfargateで動かしてみる https://it.kensan.net/rails7-1-fargate.html Sat, 18 May 2024 06:53:21 +0000 http://43.206.130.170/it/?p=1931 Rails7.1をECS(Amazon Elastic Container Service)-Fagateにデプロイします!!!

        以下の順で進めていきます。今回はとりあえずFargate上で動くことをゴールにしますので、MySQLは使いません。

        1. ローカルでRails7.1を立ち上げる
        2. ECR(Amazon Elastic Container Registry)にRailsイメージをpushする
        3. ECRのイメージを使って、ECS(Amazon Elastic Container Service)-Fagateにデプロイ

        まずは、ローカルでRails7.1を起動していきます。

        ローカルでRialsを動かしてみる

        アプリケーションの作成

        以下のコマンドでアプリケーションを作成して、作成したアプリケーションのフォルダに移動します。

        rails new test_app
        
        cd test_app/

         

        まずはDockerfileを修正します。

        Dockerfileの修正

        Rails newで作成されたDockerfileを修正します。

        vi Dockerfile

        以下の2点変更します。

        <変更①>「ENV RAILS_ENV="production"」をコメントアウトして、「ENV RAILS_ENV=$ENVIROMENTS」を追記します。
        #ENV RAILS_ENV="production" \
        ENV RAILS_ENV=$ENVIROMENTS \
        <変更②>
        5行目のFORMの後に以下を追加
        ARG ENVIROMENTS

        上記変更を加えることで、Railsを以下の指定をして、起動できるようになります。

        • production
        • development
        • tesst

        コンテナを立ち上げて動作確認

        以下のコマンドでビルドします。

        docker build . -t test_app --build-arg ENVIROMENTS='development'

        以下のコマンドでコンテナを起動します。

        docker run -it -p 3000:3000 --env RAILS_MASTER_KEY=`cat config/master.key` test_app bin/rails server -b 0.0.0.0

        http://localhost:3000/にアクセスし、以下の画面が表示されれば、動作確認OKー

         

        ECR(Amazon Elastic Container Registry)にRailsイメージをpush

        以下のコマンドで、AWSの接続設定をしておきます。

        aws configure

        次にECRログインします。

        
        aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com

        以下のコマンドでリポジトリを作成します。

        
        aws ecr create-repository \
                --repository-name rails \
                --image-scanning-configuration scanOnPush=true \
                --region ap-northeast-1 

        Railsアプリのタグ作成します

        docker tag test_app:latest {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

        Railsアプリのpushです

        docker push {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest

         

        次に、Fagateにデプロイします!

        ECS(Amazon Elastic Container Service)-Fagateにデプロイ

        クラスターの作成

        以下の設定で作成します。指定箇所以外は任意の値で大丈夫です。

        • インフラストラクチャ:AWS Fargate (サーバーレス)

        タスク定義の作成

        以下の設定で作成します。指定箇所以外は任意の値で大丈夫です。

        • インフラストラクチャの要件
          • 起動タイプ:AWS Fargate
          • オペレーティングシステム/アーキテクチャ:自分のPCと一致するもの(基本はx86_64でOK、M1/M2 MacはARM64を選択)
            • この設定に誤りがあると「exec /usr/local/bin/start-container: exec format error」エラーになります。
          • タスクサイズ
            • CPU:.5 vCPU
            • メモリ:1GB
        • コンテナ – 1
          • 名前:app
          • イメージURI:{AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/rails:latest
          • コンテナポート:3000
          • アプリケーションプロトコル:HTTP
          • 環境変数
            • キー:RAILS_MASTER_KEY
            • 値:「config/master.key」の値を直接入力
              • cat config/master.key」を入力すると「ArgumentError: key must be 16 bytes (ArgumentError)」エラーになる
          • Docker設定
            • コマンドに以下を設定
              • /rails/bin/rails,server,-b,0.0.0.0

        タスク起動

        作成したクラスターのタスクタブにある「新しいタスクの実行」を押下

        • コンピューティング設定:起動タイプ
        • デプロイ設定
          • ファミリー:先ほど作成したタスクを設定
          • リビジョン:最新
        • ネットワーキング
          • セキュリティグループ:ポート3000の許可を追加

        動作確認

        作成したクラスターのタスクタブの任意のタスクの詳細を開きます。

        パブリックIPが表示されるので、http://パブリックIP:3000でブラウザからアクセスします。

        以下の画面が表示されればOKです。

        ]]>