🧆

コンテナで作ったAPIをGitHub ActionsからAmplify Gen2にDeployする

2024/09/02に公開

はじめに

Amplify Gen2の開発体験は素晴らしいのですが、CI/CD環境でdockerコマンドが使えない制約があるのがツラいです。
https://zenn.dev/ncdc/articles/f959131cf5f4b5
という記事を書いたところ、カスタムパイプラインを使えばできるというコメントをいただきましたので、GitHub ActionsからのDeployを試してみます。

Amplify Gen2のカスタムパイプラインのドキュメントはこちらになります。
https://docs.amplify.aws/react/deploy-and-host/fullstack-branching/custom-pipelines/

ですが、ドキュメントの通りやるとフロントエンド側はAmplifyを使ったデプロイになってしまいます。docker問題を回避したいだけならそれで十分ですが、今回は折角なのでバックエンドだけでなくフロントエンドも全てGitHub Actionsからのデプロイをしてみました。
同様の方法でローカルPCを含むAmplify Gen2がサポートしていない環境からのデプロイも可能だと思います。

作ったGitHubレポジトリ

折角なのでAmplifyのホスティングではデプロイ出来ないAppRunnerのAPIと、それを呼び出すフロントエンドを作りました。(あくまでサンプルでありAPIやフロントエンドの中身はとても適当なのでご了承ください)
https://github.com/k-ibaraki/amplify-gen2-github-actions/tree/1.0.0

試したい場合は、forkしたり適当にコピーして使ってください。

GitHub Actionsからのデプロイを実施する

空のAmplifyのアプリを作る

webのコンソールからだと空のアプリを作れなそうなので、aws-cliを使用して以下のコマンドでAmplifyのアプリを作ります。(amplify-cliではなくaws-cliなのでご注意ください)

aws amplify create-app --name {好きなアプリ名} --profile {AWS_PROFILE}

成功すると空のAmplifyのアプリが作られます。

続いてブランチを作ります。今回はmainとします。

aws amplify create-branch --app-id {作成されたアプリのappId} --branch-name main

GitHub Actionsのvariablesを設定します。

以下の値をGitHub Actionsのvariablesに設定します

  • AMPLIFY_APP_ID : AmplifyのappID
  • AWS_IAM_ROLE_ARN : AWSにデプロイを実行するためのIAMロールのARN

AMPLIFY_APP_ID は前述のコマンドで作成したAmplifyアプリのIDです。
AWS_IAM_ROLE_ARN は、GitHub ActionsからAWSにOIDC認証で接続するときのIAMロールARNにです。この記事ではGitHub ActionsからAWSへ認証の解説しません。よく分からない場合はこちらの記事などを参考にするとよいかと思います。

GitHub Actionsを動かします。

Amplify(Gen2)にデプロイする為のGitHub Actionsを書いたので動かします。
https://github.com/k-ibaraki/amplify-gen2-github-actions/blob/1.0.0/.github/workflows/deploy.yaml

しばらく待つとデプロイ完了です。

dockerに依存するのでAmplify標準ではデプロイできないAppRunnerも問題なくデプロイできました。

フロントエンドからAppRunner上のAPIを呼び出して表示することも出来ています。

GitHub Actionsの中身の解説

デプロイを実行する処理を簡単に解説します。

バックエンドのデプロイ

  • まずはnpm ciで必要なnpmのパッケージをインストールします。

https://github.com/k-ibaraki/amplify-gen2-github-actions/blob/main/.github/workflows/deploy.yaml#L32-L36

  • npx ampx pipeline-deployコマンドでバックエンドリソースをデプロイします。

https://github.com/k-ibaraki/amplify-gen2-github-actions/blob/main/.github/workflows/deploy.yaml#L37-L40

注意点としては、このコマンドは環境変数CI=1が設定されている環境でのみ動きます。GitHub Actionsではデフォルトで設定されているので今回は何もしていません。他の環境からデプロイする時は必要に応じて自分で設定しましょう。
引数の--branch--appIdは必須なので、最初にaws-cliで作成したものを指定しましょう。また--debugをつけないとログが少なすぎてエラー時の調査が困難になるので基本的につけたほうが良いです。

フロントエンドのデプロイ

  • フロントエンドをビルドして、成果物をzipで固めます。

https://github.com/k-ibaraki/amplify-gen2-github-actions/blob/main/.github/workflows/deploy.yaml#L41-L45

  • 続いて固めたzipをAmplifyにdeployすればデプロイ完了ですが、これはちょっと複雑です。

https://github.com/k-ibaraki/amplify-gen2-github-actions/blob/main/.github/workflows/deploy.yaml#L46-L55

1. `aws amplify create-deployment` コマンドでDeploymentのjobを作成します。
2. `jobId` と `zipUploadUrl` が返ってきます。
3. `zipUploadUrl` に先ほどビルドしたzipファイルをPUTします。
4. `aws amplify start-deployment` コマンドに`jobID`を指定してデプロイを実行します。

以上の処理を実行することでデプロイが完了し、Webアプリを利用することが出来ます。

実際に試して感じたメリデメ

メリット

  • Amplifyがサポートしていない環境からでもデプロイできる
  • コンテナが使える
    • とにかくこれが重要
  • フロントエンドとバックエンドを分けることができる
    • 普通にAmplifyでデプロイするとフロントエンドとバックエンドが同時にデプロイされるので、レポジトリもライフサイクルも統一されることになります。ですが、今回の方法であれば分離することもできます。
    • 必ずしも分けたほうが良いわけでは無いですが、選択肢が増えるのは良いことです。

デメリット

  • 面倒くさい
    • GitHub Actionsを書く必要があることも面倒くさいですし、日々の運用における管理も普通にAmplify Gen2を使うより断然面倒くさいです。
  • Amplifyのプレビュー環境が使えない
    • Amplifyの超便利機能であるプレビュー機能は使えません。
      (GitHub Actionsを頑張って書いて自力でプレビュー環境を構築することはできるかもしれません)
  • SSRのデプロイが出来ない
    • 少なくとも今回の方法ではフロントエンドをSSRにした場合はデプロイすることは出来ません。
      (最初うっかり素のRemixで作ってしまい、Remix SPA Modeで作り直しました。。。)

以上です!

そこまでしてAmplifyを使わなくてもよくない?と思わなくもないですか、いろいろな環境制約等でAmplify Gen2を使えていないという方がいれば試していただいてもいいかなと思います。

なお、今回はフロントエンドも無理やりGitHub Actionsからデプロイしましたが、docker使えない問題の解決さえできれば良い場合は、バックエンドのみGitHub Actionsでフロントは普通にAmplifyを使用したDeployで問題ないかと思います。

NCDCエンジニアブログ

Discussion