Amazon CodeCatalyst を使って Web サイトを EC2 にデプロイする手順

Amazon CodeCatalyst と AWS CodeDeploy を使い、Web サイト(Laravel を想定)を EC2 にデプロイする手順のメモ。

概要

AWS CodeCommit が 2024年7月25日 に「新規のお客様向けのアクセスを閉じることを決定」 してから新規の AWS プロジェクトが発生したので、請求を AWS アカウントにまとめるという要件に対応するため、今回 Amazon CodeCatalyst を使用してみました。

Amazon CodeCatalyst は Git レポジトリの管理と CI/CD によるデプロイが可能です。Issue や Pull Request の管理も可能で、AWS Cloud9 や AWS Toolkit for Visual Studio Code を使用して直接編集やデプロイすることもできるようです。あとは Amazon Q を利用して、自動的に問題を検出して Issue にするとかもできるそうです。

現在無料枠では月 2000 分のビルド時間、スペース毎に 10GB 分の容量が利用可能です。

https://codecatalyst.aws/explore/pricing

CodeCatalyst のドキュメント、ユーザーガイドは下記になります。

https://docs.aws.amazon.com/ja_jp/codecatalyst/latest/userguide/welcome.html

デプロイ要件とシステム構成

Laravel を使用した Web サイトへのデプロイで、最低限の環境を想定して進めます。

操作するサービスは CodeCatalyst, S3, EC2, CodeDeploy, IAM となります。ネットワークや DB などは除外します。

デプロイの流れ

デプロイの大まかな流れは下記のようになります。

  1. 指定ブランチへの git push を検出した CodeCatalyst が、設定されたワークフローに応じて処理を実行
  2. アセットファイルをビルドしたりパッケージなどをアーティファクトとして生成
  3. アーティファクトを ZIP に圧縮して S3 へアップロード
  4. CodeDeploy へデプロイを指示し、デプロイ先の EC2 で S3 のアーティファクトを展開して設置

Amazon CodeCatalyst の利用開始について

Amazon CodeCatalyst のサービスは AWS アカウントとは切り離されており、AWS アカウントと紐づけを行うことで請求をまとめ、利用を開始することができます。

また、CodeCatalyst へのログインには AWS Builder ID を使用します。つまり前提として AWS アカウントと Builder ID が必要ということです。

少し手間はかかりますが、下記 Sign Up から指示に従えば CodeCatalyst の Web コンソールにたどり着けるので Repository 登録までの話は端折ります。

https://codecatalyst.aws/explore

Amazon CodeCatalyst のワークフローを構築する

Repository の作成まで進んだら、Workflow の構築に入ります。

左のメニューから CI/CD > Workflows を選択してページを開いて Create workflow してください。

作成した Repository と、トリガー対象の Branch を選択します。今回は main ブランチにします。

すると下記のような画面が出てきます。今は Visual モードでワークフローの図が表示されていますが、今回は YAML モードを使用して作ります。

ワークフロー設定画面

ワークフローは Action と Gate で構成されています。各 Action 毎にビルドの処理を実行します。今回は使いませんが、Gate を使うことで後続の Action の実行に、特定のメンバーの承認を必須とすることができます。

下記は YAML モードにして Actions を選択した状態です。Actions パネルからやりたいことを探して Workflow に追加していきます。

ワークフロー設定画面:Actions パネル

各 Action の青色の名前をクリックすると解説を読むことができます。Documentation タブの下部の方に詳細なドキュメントリンクが貼ってあるので、大体はこのドキュメントとにらめっこしながらやりたいことを作っていく感じですね。Action の中には GitHub Actions で提供されているもの(uses)からも使用できますが、一部バージョンが古いことに注意が必要です。

Actions の一覧が見つけられなかったので、内容確認も兼ねて こちら にまとめました。

今回使用する Action は Build, Amazon S3 publish の二つだけです。

ワークフローの解説

さて、結果から述べると下記のような YAML となります。

内容は前述した デプロイの流れ と同じものです。

Actions は Build, Composer, Zip, Upload, Deploy で構成しました。この各アクションの名前は一意であれば好きな名前にできます。

Name: deploy-prod
SchemaVersion: "1.0"

Triggers:
  - Type: Push
    Branches:
      - main

Actions:
  Build:
    Identifier: aws/build@v1.0.0
    Inputs:
      Sources:
        - WorkflowSource
    Outputs:
      Artifacts:
        - Name: ASSETS
          Files:
            - "public/build/**/**"
    Configuration:
      Steps:
        - Run: npm install
        - Run: npm run build
      Container:
        Registry: CODECATALYST
        Image: CodeCatalystLinuxLambda_x86_64:2024_03
    Compute:
      Type: Lambda

  Composer:
    Identifier: aws/build@v1.0.0
    Inputs:
      Sources:
        - WorkflowSource
    Outputs:
      Artifacts:
        - Name: VENDOR
          Files:
            - "vendor/**/**"
    Configuration:
      Steps:
        - Run: composer install --no-dev --prefer-dist --no-interaction --optimize-autoloader
      Container:
        Registry: DockerHub
        Image: composer:2.8.6

  Zip:
    Identifier: aws/build@v1.0.0
    Inputs:
      Artifacts:
        - ASSETS
        - VENDOR
    Configuration:
      Steps:
        - Run: mv $CATALYST_SOURCE_DIR_ASSETS/public/build ./public
        - Run: mv $CATALYST_SOURCE_DIR_VENDOR/vendor ./
        - Run: zip -r artifact.zip ./ -x "*.git*"
      Container:
        Registry: CODECATALYST
        Image: CodeCatalystLinuxLambda_x86_64:2024_03
    Compute:
      Type: Lambda
    Outputs:
      Artifacts:
        - Name: ZIPPED
          Files:
            - ./artifact.zip

  Upload:
    Identifier: aws/s3-publish@v1
    Inputs:
      Artifacts:
        - ZIPPED
    Environment:
      Name: Production
    Configuration:
      DestinationBucketName: "my-s3-artifact-bucket"

  Deploy:
    Identifier: aws/build@v1.0.0
    DependsOn:
      - Upload
    Environment:
      Name: Production
    Configuration:
      Steps:
        - Run: aws deploy create-deployment --application-name my-application-name --deployment-group-name my-deployment-group-name --s3-location bucket=my-s3-artifact-bucket,key=artifact.zip,bundleType=zip --deployment-config-name CodeDeployDefault.AllAtOnce --region ap-northeast-1
      Container:
        Registry: CODECATALYST
        Image: CodeCatalystLinuxLambda_x86_64:2024_03
    Compute:
      Type: Lambda

Visual モードで見ると、こんな感じです。ページ下部に Warnings が出ていますがこれは後で解説します。

ワークフロー設定画面:完成図

それぞれの Action を見ていきますが、是非 ユーザーガイド も併せて参照してください。

Build

最新の Laravel (vite) はビルドファイルをデフォルトで public/build/ ディレクトリに出力します。

下記はビルドを実行したその結果を ArtifactsASSETS という名前で加える、というものです。

Build:
  Identifier: aws/build@v1.0.0
  Inputs:
    Sources:
      - WorkflowSource
  Outputs:
    Artifacts:
      - Name: ASSETS
        Files:
          - "public/build/**/**"
  Configuration:
    Steps:
      - Run: npm install
      - Run: npm run build
    Container:
      Registry: CODECATALYST
      Image: CodeCatalystLinuxLambda_x86_64:2024_03
  Compute:
    Type: Lambda

aws/build@v1.0.0 というのは、Docker コンテナ内でビルドやテストを行うための Action を提供します。

Inputs.SourcesWorkflowSource を指定することで、レポジトリのソースが展開された環境で Configuration.Steps のコマンドを実行することができます。

Outputs.Artifacts を指定することにより、後続のアクションで参照することできます。対象のファイルは public/build/**/** のようにすることで再帰的に選択することができます。

Docker のイメージは、「CodeCatalyst が提供するもの」と「カスタムランタイム環境の Docker」から自由に選べます。後者は Amazon ECR や Docker Hub からダウンロードして使えます。

前者のイメージのタイプには Lambda と EC2 (Amazon Linux 2, Windows) があり、Node.js 以外にも AWS CLI や Git, Go などのツールが予めインストールされていますが、イメージのバージョンによってツールのバージョンも異なるので注意が必要です。

Compute.Type で Lambda を指定するだけでなく、 Container.Image であえて CodeCatalystLinuxLambda_x86_64:2024_03 をイメージを指定しています。デフォルトでは CodeCatalystLinux_x86_64:2022_11 が選択されて、Node.js のバージョンが古くなってしまうからです。

なお、今回は CodeCatalystLinuxLambda_x86_64:2024_03 を選択したことで Node.js のバージョンは 18.19.0 になりますが、22.x などの最新バージョンを使いたい場合は次の Action で行うように Docker Hub などからイメージをダウンロードする形になります。

ただし EC2 や カスタムランタイム環境はセットアップに時間がかかるため、目的に適っているのなら出来るだけ Lambda を選択したほうがいいです。

インストール済みのツールは ランタイム環境イメージの指定 を参照してください。

参照

補足

Actions から GitHub Actionsaws/github-actions-runner@v1.0.0 を使用して actions/setup-node で最新のバージョン指定を試みましたが、結論この方法では最新の Node.js バージョンをインストールすることはできませんでした。

この aws/github-actions-runner@v1.0.0 が内部で実行する actions/runner のバージョンが v2.300.2 となっており actions/setup-nodev4 に対応していないため v3 を使うところまではできますが EC2 イメージの OS である Amazon Linux 2 は Node.js 20 以降の要件にあたる GLIBC_2.27 に対応していないためです

Composer

前述の Build 同様に Artifacts を生成することが目的です。今回は PHP のパッケージをデプロイ毎にインストールさせています。

Composer:
  Identifier: aws/build@v1.0.0
  Inputs:
    Sources:
      - WorkflowSource
  Outputs:
    Artifacts:
      - Name: VENDOR
        Files:
          - "vendor/**/**"
  Configuration:
    Steps:
      - Run: composer install --no-dev --prefer-dist --no-interaction --optimize-autoloader
    Container:
      Registry: DockerHub
      Image: composer:2.8.6

Lambda や EC2 のイメージには PHP が入っていないようなので、 Composer を使用するために Container.RegistryDockerHub からダウンロードするよう指示しています。

やはり数十秒とか1分程度でセットアップが完了する Lambda に比べるとだいぶ時間がかかります(私の環境では約4-5分かかりました)。

現状、GitHub Actions の if のように Action 単位で実行可否を操作することができないようなので、ワークフローを独立させるなどの工夫が必要です。

今後、Gate に Approval 以外の条件が加わるか、アクションごとに if 構文を指定ができることを期待します。

Zip

前述で作成した Artifacts を取得して zip で圧縮し再度 Artifacts に加えます。

Zip:
  Identifier: aws/build@v1.0.0
  Inputs:
    Artifacts:
      - ASSETS
      - VENDOR
  Configuration:
    Steps:
      - Run: mv $CATALYST_SOURCE_DIR_ASSETS/public/build ./public
      - Run: mv $CATALYST_SOURCE_DIR_VENDOR/vendor ./
      - Run: zip -r artifact.zip ./ -x "*.git*"
    Container:
      Registry: CODECATALYST
      Image: CodeCatalystLinuxLambda_x86_64:2024_03
  Compute:
    Type: Lambda
  Outputs:
    Artifacts:
      - Name: ZIPPED
        Files:
          - ./artifact.zip

Inputs.Artifacts によってすでに生成されたアーティファクトを取得します。

ちなみに Action の実行順は DependsOn によって指定できますが、この Inputs.Artifacts を設定すると自動で出力元に依存してくれるようです。

Run の中で zip コマンドを実行していますが、この zip も古いイメージには入っていなかったので CodeCatalystLinuxLambda_x86_64:2024_03 を使用しています。

Upload

前述で圧縮した zip を受け取って S3 にアップロードします。

バケットの直下に artifact.zip が設置され、EC2 内の CodeDeploy エージェントからアクセスできるようになります。

Upload:
  Identifier: aws/s3-publish@v1
  Inputs:
    Artifacts:
      - ZIPPED
  Environment:
    Name: Production
  Configuration:
    DestinationBucketName: "my-s3-artifact-bucket"

ここで初めて Environment が登場しましたが、これは AWS アカウント側の環境を操作(今回は S3 に設置)する際に必要な設定です。

詳しくは後ほど説明します。

Deploy

前述した通り CodeCatalyst から提供されてるイメージには AWS CLI がインストールされているので、aws deploy コマンドによってデプロイメントを実施して EC2 内エージェントにデプロイを実行させることができます。

Deploy:
  Identifier: aws/build@v1.0.0
  DependsOn:
    - Upload
  Environment:
    Name: Production
  Configuration:
    Steps:
      - Run: aws deploy create-deployment --application-name my-application-name --deployment-group-name my-deployment-group-name --s3-location bucket=my-s3-artifact-bucket,key=artifact.zip,bundleType=zip --deployment-config-name CodeDeployDefault.AllAtOnce --region ap-northeast-1
    Container:
      Registry: CODECATALYST
      Image: CodeCatalystLinuxLambda_x86_64:2024_03
  Compute:
    Type: Lambda

こちらについても Upload と同様 AWS 環境へアクセスするために Environment を設定しています。

以上簡単な解説となります。

Warnings は出たままですが、一旦コミットします。ワークフローは実行されますが、途中でエラーが発生して失敗します。

CodeCatalyst での Environment 設定

前述のとおり各 Action の中で AWS サービスにアクセスするためには Environment の設定が必要です。

下記は左のメニューの CI/CD > Environments を開き Create environment をしたページです。

ワークフロー設定画面:Actions パネル

Environment name に先ほど Action の中で Environment.Name に指定した通り Production と入力します。勿論一致していればなんでもOKです。

Environment type では Production を指定してください。

Environment propertiesAWS account connection ではデプロイ先の AWS アカウント ID を選択します。表示されない場合は、その下のリンクの Connect to an AWS account から追加してください。

選択すると Default IAM role が表示されるので IAM ロールを選ぶ必要がありますが、これは AWS 側で別途作成する必要があります。

手順が分かりづらいため、以下のステップで解説します。

  1. AWS 側でデプロイ用のロールを作成
  2. AWS 側の CodeCatalyst ページに移り、[1] で作成したロールを有効化
  3. Amazon CodeCatalyst に移り、 Environment propertiesDefault IAM role で [2] を選択

まずロール作成画面で 信頼されたエンティティを選択カスタム信頼ポリシー を選択して下記を入力してください。

このプリンシパル設定がないと CodeCatalyst で選択対象として認識されません。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "codecatalyst-runner.amazonaws.com",
          "codecatalyst.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

許可ポリシーには、S3 と CodeDeploy の操作権限が必要です。権限は絞った方がいいですが、今回は分かりやすく以下の 2 つのポリシーを割り当てます。

  • AmazonS3FullAccess
  • AWSCodeDeployFullAccess

最後にロール名 CodeCatalystProductionDeployRole としてロール作成を完了します。

続いて AWS の CodeCatalyst ページに移動し、対象の Space を選択したら下記の通り進めます。

  1. IAM roles available to CodeCatalystAdd IAM role をクリック
  2. Add an existing role you have created in IAM を選択し Select existing IAM role で先ほど作成したロール CodeCatalystProductionDeployRole を選択
  3. Amazon CodeCatalyst に移って Environment propertiesDefault IAM role で同様に CodeCatalystProductionDeployRole を選択して作成

※なお、今回は Default IAM role を設定していますが Action の中の Environment.Connections.Role で直接設定することもできます

改めてワークフローの画面に行くと Warnings が消えていることが確認できます。これでようやくワークフローが正常に実行されるはずです。

CodeCatalyst でコミットするなり、プッシュするなりして確認してみてください。

参考

Actions一覧

Amazon CodeCatalyst

Action Name説明Identifierersion (2025/03 時点)AuthorDescription
BuildDocker コンテナ内で成果物をビルドし、ユニットテストを実行します。aws/build1.0.0AWSBuild your artifacts and run your unit tests in a Docker container.
Testアプリケーションや成果物に対して統合テストやシステムテストを実行します。aws/managed-test1.0.0AWSRun integration and system tests against your application or artifacts.
Deploy to Kubernetes clusterアプリケーションを Kubernetes クラスタにデプロイします。aws/kubernetes-deploy1.1.1AWSDeploys an application to a Kubernetes cluster.
Render Amazon ECS task definitionAmazon ECS タスク定義 JSON ファイルにコンテナイメージ URI を挿入し、新しいタスク定義ファイルを作成します。aws/ecs-render-task-definition1.0.5AWSInserts a container image URI into an Amazon ECS task definition JSON file, creating a new task definition file.
Deploy AWS CloudFormation stackAWS CloudFormation Stacks をデプロイします。aws/cfn-deploy1.1.0AWSDeploys AWS CloudFormation Stacks.
Deploy to Amazon ECSAmazon ECS タスク定義を登録し、ECS サービスにデプロイします。aws/ecs-deploy1.1.0AWSRegisters an Amazon ECS task definition and deploys it to an ECS service.
AWS CDK deployAWS Cloud Development Kit(CDK)アプリを合成してデプロイします。aws/cdk-deploy2.0.2AWSSynthesize and deploy an AWS Cloud Development Kit (CDK) app.
AWS CDK bootstrapAWS CDK が CDK アプリをデプロイするために必要なリソースをプロビジョニングします。aws/cdk-bootstrap2.0.1AWSProvision the resources that the AWS CDK needs to deploy your CDK app.
Amazon S3 publishアプリケーションの成果物を Amazon S3 バケットにコピーします。aws/s3-publish1.1.1AWSCopy your application artifacts to an Amazon S3 bucket.
AWS Lambda invokeAWS Lambda 関数を呼び出します。aws/lambda-invoke1.1.0AWSInvoke an AWS Lambda function.
Invoke Workflow別のワークフローを条件付きで呼び出します。codecatalyst-labs/invoke-workflow-action1.0.38CodeCatalyst LabsThis action allows you to conditionally invoke another workflow in the same project.
Amazon Inspector Scanアプリケーションの脆弱性スキャンを実行します。codecatalyst-labs/amazon-inspector-scan1.0.18CodeCatalyst LabsGenerates a Software Bill of Materials (SBOM) for archives, containers, directories, systems, and compiled binaries, then scans the SBOM for vulnerabilities.
Terraform Community EditionTerraform Community Edition を使用してインフラを適用します。codecatalyst-labs/provision-with-terraform-community1.0.2CodeCatalyst LabsExecutes Terraform Community Edition plan and apply operations.
Scan with Amazon CodeGuru SecurityAmazon CodeGuru Security でコードスキャンを実行します。codecatalyst-labs/scan-with-codeguru-security1.1.0CodeCatalyst LabsUses Amazon CodeGuru Security to execute a code scan.
Deploy to Amazon CloudFront and Amazon S3Amazon CloudFront と Amazon S3 にアプリケーションをデプロイします。codecatalyst-labs/deploy-to-cloudfront-s31.1.0CodeCatalyst LabsDeploys an application to Amazon CloudFront and Amazon S3.
Publish to AWS CodeArtifactAWS CodeArtifact にパッケージをパブリッシュします。codecatalyst-labs/publish-to-codeartifact1.1.0CodeCatalyst LabsPublishes packages to AWS CodeArtifact repository.
Invalidate Amazon CloudFront CacheAmazon CloudFront キャッシュを無効にします。codecatalyst-labs/invalidate-cloudfront-cache1.1.0CodeCatalyst LabsInvalidates an Amazon CloudFront cache for a given set of paths.
Publish to Amazon SNSAmazon SNS を利用して通知を送信できます。codecatalyst-labs/publish-to-sns1.1.0CodeCatalyst LabsAllows users to integrate with Amazon SNS by creating a topic, publishing to a topic, or subscribing to a topic.
Deploy to AWS App RunnerAWS App Runner に最新のイメージをデプロイします。codecatalyst-labs/deploy-to-app-runner1.1.0CodeCatalyst LabsDeploys the latest image in a source image repository to AWS App Runner.
Outgoing WebhookHTTPS リクエストを送信して外部サービスと連携します。codecatalyst-labs/outgoing-webhook1.0.1CodeCatalyst LabsSends messages within workflow to an arbitrary web server using HTTPS request.
Deploy with AWS SAMAWS SAM を使用してサーバーレスアプリケーションをデプロイします。codecatalyst-labs/deploy-with-sam1.1.0CodeCatalyst LabsDeploys your serverless application with AWS Serverless Application Model (AWS SAM).
Push to Amazon ECRDocker イメージをビルドし、Amazon ECR にパブリッシュします。codecatalyst-labs/push-to-ecr1.1.0CodeCatalyst LabsBuilds and publishes a Docker image to an Amazon Elastic Container Registry (ECR) repository.
Deploy to AWS Amplify HostingAWS Amplify Hosting にアプリケーションをデプロイします。codecatalyst-labs/deploy-to-amplify-hosting1.1.0CodeCatalyst LabsDeploys an application to AWS Amplify Hosting.
Mend SCAMend SCA でオープンソースの脆弱性を分析します。mend/mendsca1.0.9MendAnalyze your project for open source security vulnerabilities with Mend SCA.
SonarCloud ScanSonarCloud でコード品質をスキャンします。sonar/sonarcloud-scan1.0.7SonarScan your projects with SonarCloud and help developers produce Clean Code.

GitHub

Action Name説明IdentifierVersionAuthorDescription
GitHub Actionsワークフローに GitHub アクションを追加しましょう。GitHub Marketplace にあるアクションなら何でも使えます。aws/github-actions-runner1.0.0AWSAdd a GitHub Action to your workflow. You can use any action in the GitHub Marketplace.
TruffleHog OSSTruffleHog で Github アクションをスキャンするtrufflesecurity/trufflehog3.47.0trufflesecurityScan Github Actions with TruffleHog
Super-Linterbash で書かれた様々なリンターのシンプルな組み合わせで、ソースコードの検証を支援します。super-linter/super-linter5.2.0githubIt is a simple combination of various linters, written in bash, to help validate your source code
yq - portable yaml processoryaml で作成、読み込み、更新、削除、マージ、検証、その他いろいろなことができる。mikefarah/yq4.34.2mikefarahcreate, read, update, delete, merge, validate and do more with yaml
GitHub ScriptGitHub クライアントを使った簡単なスクリプトの実行actions/github-script2.1.0actionsRun simple scripts using the GitHub client
Build and push Docker imagesBuildx を使った Docker イメージのビルドとプッシュdocker/build-push-action4.1.1dockerBuild and push Docker images with Buildx
SSH Remote Commandsリモート ssh コマンドの実行appleboy/ssh-action1.0.0appleboyExecuting remote ssh commands
Is Website Vulnerable公開されている JavaScript ライブラリの脆弱性について URL をスキャンするlirantal/is-website-vulnerable1.14.8lirantalScans a URL for publicly known JavaScript library vulnerabilities
slack-sendチャンネルでメッセージを公開したり、Slack Workflow Builder に JSON ペイロードを送信するslackapi/slack-github-action1.24.0slackapiPublish a message in a channel or send a JSON payload to the Slack Workflow Builder
Serverlessこのアクションはサーバーレスフレームワークをラップし、一般的なサーバーレスコマンドを可能にするserverless/github-action3.2.0ServerlessThis Action wraps the Serverless Framework to enable common Serverless commands
Dependency Checkこのアクションは OWASP Dependency-Check ツールに基づいており、プロジェクトの依存関係に含まれる一般に公開された脆弱性の検出を試みるソフトウェア構成分析(SCA)ツールです。dependency-check/Dependency-Check_Action1.1.0dependency-checkThis action is based upon the OWASP Dependency-Check tool, a Software Composition Analysis (SCA) tool that attempts to detect publicly disclosed vulnerabilities contained within a project’s dependencies.
CycloneDX Python Generate SBOMPython 用の CycloneDX SBOM を生成する GitHub アクションCycloneDX/gh-python-generate-sbom1.0.1CycloneDXGitHub action to generate a CycloneDX SBOM for Python
Liquibase Update ActionLiquibase Update を GitHub アクションワークフローで実行する公式 GitHub アクションliquibase-github-actions/update4.23.0liquibase-github-actionsOfficial GitHub Action to run Liquibase Update in your GitHub Action Workflow