DevelopersIOのフロントエンドをApp Runnerに変更してみた

当ブログサイトのフロントアプリケーションの実行基盤が AWS App Runner になりました。
2023.05.17

当ブログ(DevelopersIO)は、WordPress を ヘッドレスな CMSとして利用、 フロントアプリケーション(Nuxt.js) がサーバサイドレンダリング (SSR) したコンテンツを公開しています。

2023年4月後半より、ブログコンテンツのSSRを行うフロントエンドアプリケーションの実行環境として、AWS App Runner を利用する機会がありましたので 紹介させていただきます。

構成図

導入後

  • Nuxt.js のアプリケーション環境はコンテナ化しました。
  • ECRに格納したイメージを App Runner で利用する構成としました。

導入前

  • Amazon API Gateway と AWS Lambda を利用していました
  • Lambdaのデプロイは Serverless Framework (sls) を利用しました。
  • 静的コンテンツをビルド時に生成(generate)してS3に配置、CloudFrontのパスルーティングで配信を実施していました。

レスポンス改善

従来の環境、CloudFrontのキャッシュがヒットせず、SSR Lambda もコールドスタートした場合、ページ表示まで数秒の待ち時間が発生する事がありました。

レスポンス性能測定用の App Runnerと、Lambda 環境を用意、 CloudWatch Synthetics の API Canary を利用して、トップページ「/」コンテンツの応答速度を測定。

測定間隔20分、Lambdaのコールドスタートを誘発した状態で、平均応答時間は2.95秒から0.64秒まで改善を確認できました。

App Runner

Lambda + API Gateway

デプロイ改善

CI/CDに利用するGitHub Actionsの設定を簡略化できました。

検証環境

  • 認証情報の取得後、コンテナイメージの作成、ECR登録を行う設定としました。
    steps:
      - uses: actions/checkout@v3
      - uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          aws-region: ${{ vars.AWS_REGION }}
          role-to-assume: ${{ vars.AWS_ROLE_ECR_PUSH }}
      - uses: aws-actions/amazon-ecr-login@v1
        id: login-ecr
      - name: build and push docker image to ecr
        env:
          REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          REPOSITORY: ${{ vars.AWS_ECR_REPOSITORY }}
          IMAGE_TAG: "latest"
        run: |
          docker build . --tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
          docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
  • 検証環境の App Runnerは、ECRのイメージ更新をトリガーとして、自動デプロイする設定としました。

本番環境

本番環境の「App Runner」のデプロイのみ実施する Action設定を行いました。

    steps:
      - uses: actions/checkout@v3
      - uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          aws-region: ${{ vars.AWS_REGION }}
          role-to-assume: ${{ vars.AWS_ROLE_APPRUNNER_DEPLOY }}
      - name: deploy-apprunner
        run: |
          aws --region ${{ vars.AWS_REGION }} apprunner start-deployment --service-arn ${{ vars.AWS_APPRUNNER_ARN }}

旧環境

開発、本番環境それぞれのデプロイ時に都度ビルドを実施。 Serverless Framework (sls) による Lambda、 CLI による S3へのデプロイを行っていました

yarn install yarn build yarn generate aws s3 sync ... npx sls deploy ....

旧環境からの改善

  • コンテナイメージを再利用することで、本番環境のデプロイ時間を短縮。
  • ビルド時期の違いなどに起因するパッケージバージョンの不一致など、環境間の不整合も回避可能になりました。
  • ECRのイメージ世代管理機能を利用することで、リリース後の切り戻しが容易になりました。
  • Serverless Framework (sls) 実行環境の維持が不要となりました。
  • デプロイ環境(GitHub Actions)で利用するIAM権限 を最小化できました。

コスト比較

App Runner切替前後のコスト、コストエクスプローラを利用で確認しました。

App Runner

  • App Runner スペック: vCPU:0.5、メモリ1GB
  • 1日あたりの平均コスト: USD 1.87

App Runner の アクティブインスタンス数 は、2.5 前後で遷移していました。

Lambda+API Gateway

  • Lambda スペック: (x86、メモリ1GB)
  • 1日あたりの平均コスト: USD 10.87

※CPU性能を優先するため、メモリ割当は多めの設定としていました。

まとめ

App Runner、当ブログのフロント基盤として費用対効果に優れた利用ができることが確認できました。

常時一定規模のアクセスが発生、低レイテンシが望まれる場合には、App Runnerも候補としてご検討ください。