📝

Elastic Beanstalk にソースコードをデプロイして更新する処理を自動化してみた

に公開

Setting configuration options after environment creation - AWS Elastic Beanstalk
上記ドキュメントの手順を参考に Lambda で実装してみました。

前提

  • コマンド実行環境は CloudShell
  • Elastic Beanstalk 環境は作成済み
  • プラットフォーム: Node.js 22 running on 64bit Amazon Linux 2023/6.5.2

処理フロー

  1. ローカル端末で作成したソースバンドルを zip 化
  2. 1 の zip ファイルを S3 バケットにアップロード
  3. S3 イベント通知で Lambda 関数を起動
  4. Lambda 関数でアプリケーションバージョンの作成と環境の更新を実行

1. ローカル端末で作成したソースバンドルを zip 化

Tutorials and samples - AWS Elastic Beanstalk
今回は上記ドキュメントの Node.js のサンプルを使用しました。

$ wget https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/samples/nodejs.zip

$ unzip nodejs.zip
$ rm nodejs.zip

$ nano index.html
# 任意の内容に書き換え
<h1>Hello</h1>
<p>Hello</p>

$ zip sourcebundle.zip *

2. 1 の zip ファイルを S3 バケットにアップロード

この時点では S3 イベント通知を設定していないので、いったんアップロードできるかどうかだけの確認です。

$ aws s3 cp sourcebundle.zip s3://elasticbeanstalk-ap-northeast-1-123456789012/my-app/sourcebundle.zip

$ aws s3 ls s3://elasticbeanstalk-ap-northeast-1-123456789012/my-app/
2025-06-10 01:25:03       4453 sourcebundle.zip

3. S3 イベント通知で Lambda 関数を起動

S3 イベント通知を設定するために Lambda 関数を作成します。

  • ランタイム: Node.js 22.x
  • Lambda 実行ロールの権限: AdministratorAccess
  • タイムアウト: 30 秒
  • ソースコード: 以下の通り
index.js
const { ElasticBeanstalkClient, CreateApplicationVersionCommand, UpdateEnvironmentCommand } = require('@aws-sdk/client-elastic-beanstalk');

const ebClient = new ElasticBeanstalkClient();

const APPLICATION_NAME = 'test'; 
const ENVIRONMENT_NAME = 'Test-env'; 

exports.handler = async (event) => {
  try {
    // S3イベントから情報を取得
    const bucket = event.Records[0].s3.bucket.name;
    const key = event.Records[0].s3.object.key;

    // バージョンラベルの作成 (タイムスタンプを使用)
    const timestamp = new Date().getTime();
    const versionLabel = `v-${timestamp}`;

    console.log(`新しいアプリケーションバージョンを作成します: ${versionLabel}`);
    console.log(`S3バケット: ${bucket}, キー: ${key}`);

    // 1. CreateApplicationVersion APIを呼び出して新しいバージョンを作成
    const createVersionParams = {
      ApplicationName: APPLICATION_NAME,
      VersionLabel: versionLabel,
      Description: `Version ${versionLabel} deployed from Lambda`,
      SourceBundle: {
        S3Bucket: bucket,
        S3Key: key
      },
      AutoCreateApplication: false,
    };

    const createVersionResult = await ebClient.send(
      new CreateApplicationVersionCommand(createVersionParams)
    );

    console.log('アプリケーションバージョンが作成されました:', createVersionResult);
    await new Promise(resolve => setTimeout(resolve, 10000))

    // 2. UpdateEnvironment APIを呼び出して環境を新しいバージョンで更新
    const updateEnvParams = {
      ApplicationName: APPLICATION_NAME,
      EnvironmentName: ENVIRONMENT_NAME,
      VersionLabel: versionLabel
    };

    const updateEnvResult = await ebClient.send(
      new UpdateEnvironmentCommand(updateEnvParams)
    );

    console.log('環境の更新が開始されました:', updateEnvResult);

    return {
      statusCode: 200,
      body: JSON.stringify({
        message: `Successfully deployed version ${versionLabel} to ${ENVIRONMENT_NAME}`,
        createVersionResult,
        updateEnvResult
      })
    };
  } catch (error) {
    console.error('デプロイ中にエラーが発生しました:', error);
    throw error;
  }
};

関数作成後、S3 イベント通知を設定します。

  • プレフィックス: my-app/
  • サフィックス: .zip
  • イベントタイプ: すべてのオブジェクト作成イベント
  • 送信先: 上記 Lambda 関数

4. Lambda 関数でアプリケーションバージョンの作成と環境の更新を実行

再度 S3 バケットにソースバンドルをアップロードして動作確認します。

$ aws s3 cp sourcebundle.zip s3://elasticbeanstalk-ap-northeast-1-123456789012/my-app/sourcebundle.zip

Elastic Beanstalk 環境が更新されていれば成功です。

エラーが発生した場合は Lambda の実行ログを確認してください。

まとめ

今回は Elastic Beanstalk にソースコードをデプロイして更新する処理を自動化してみました。
どなたかの参考になれば幸いです。

参考資料

Discussion