4
0

More than 1 year has passed since last update.

後編:EC2にFabric1.xでデプロイされていたPlayFrameworkのプロジェクトをGitHub Actions+CodeDeployでのデプロイに変えてみた話

Posted at

この記事は株式会社サイバー・バズ Advent calendar 2021の記事です。

また、以下の記事の続きです。

続き

  1. 中間生成物用のS3バケットの作成
  2. GitHub Actionsのworkflow作成
  3. 必要なIAMの作成
  4. CodeDeploy用のappspec.ymlと各スクリプトの作成
  5. CodeDeployのセットアップ

前回は、大体3の途中くらいまでを解説しました。
今回は、以下の画像のオレンジ色の部分をメインに解説します。

image.png

必要なIAMの作成

前回の最後にも、S3に中間生成物をアップロードするCI用のユーザーを作成しました。
今回は、CodeDeployに必要なロールの作成です。

まずは、CodeDeployグループに必要なサービスロールを作成します。
AWSコンソールのIAMの画面から、以下の画像のようになるよう、ロールを作成します。

名称はなんでも良いですが、わかるようにCodeDeployServiceRole
ポリシーにはAWS管理ポリシーのAWSCodeDeployRoleをつけておけば問題ありません。

codedeployservicerole.png

もう一つ必要なIAMロールがありますが、CodePipelineの設定中に自動で作成させることができます。

CodeDeploy用のappspec.ymlと各スクリプトの作成

CodeDeployはデプロイに際してライフサイクルイベントを発火する作りになっており、
各イベントにフックさせるスクリプトを定義しておくことができます。
参考:AppSpec の「hooks」 - AWS CodeDeploy

中間生成物に含めておくことでデプロイ対象のEC2インスタンスが実行できるようになります。
今回は以下の3つのファイルを含めます。

├── appspec.yml
└── scripts
    ├── start.sh
    └── stop.sh

appspec.yml

CodeDeployが使用するファイルで、中間生成物のソースコード(前回作ってS3にアップロードしたzip)のルートに配置されている必要があります。

  • files ... 今回の場合、ダウンロードしたS3のファイル郡を解凍後どこに再配置するかを示します。今回はec2-userのホームディレクトリ直下のxxxxxxに配置します。
  • hooks ... ライフサイクルフックで呼ばれるスクリプトのパスとタイムアウト秒を定義しています。今回はアプリの停止と開始のスクリプトのみを指定しています。
appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/xxxxxx
file_exists_behavior: OVERWRITE
hooks:
  ApplicationStop:
    - location: scripts/stop.sh
      timeout: 60
  ApplicationStart:
    - location: scripts/start.sh
      timeout: 60

scripts/stop.sh, scripts/start.sh

アプリケーションの停止と終了を行うスクリプトです。
今回の目的はFabric1.xからの移管ということで、必要最低限の記述のみです。
scripts/stop.shではPlayFramework2.3.xでの起動アプリのプロセス停止を行い
scripts/start.shではPlayFrameworkアプリケーションのバックグラウンド実行を行っています。

scripts/stop.sh
#!/bin/bash

set -eo

ps=`ps -ef | grep "xxxxxx/target/universal/stage" | grep -v grep | wc -l`
if [ $ps -eq 1 ]; then
  kill `cat /home/ec2-user/xxxxxx/target/universal/stage/RUNNING_PID`
fi
scripts/start.sh
#!/bin/bash

set -eo

nohup /home/ec2-user/sinbad/target/universal/stage/bin/xxxxxx -Duser.timezone=JST -Dconfig.file=/home/ec2-user/xxxxxx/target/universal/stage/conf/application-prod.conf &>> /dev/null 2>&1 &

これらのファイルをソースコードのルートに含めた中間生成物のzipを解凍すると
下記のようなディレクトリ構成になっています。

├── appspec.yml
├── scripts
│   ├── start.sh
│   └── stop.sh
└── target
    ├── resolution-cache
    ├── scala-2.11
    ├── streams
    ├── universal
    └── web

CodeDeployのセットアップ

満を持してCodeDeployのセットアップを行なっていきます。
厳密には、CodeDeployおよびCodePipelineのセットアップが必要です。

まずは、新規にアプリケーションを作成しましょう。

画像
CodeDeployトップ image.png
アプリケーション作成画面 スクリーンショット 2021-12-06 20.20.21.png
 アプリケーション作成直後 スクリーンショット 2021-12-06 20.22.03.png

簡単ですね。

次に、デプロイグループを作ります。上記画像中の「デプロイグループの作成」から作成できます。
ここではいくつかの設定項目があるので、それぞれの設定項目について簡単に解説します。

項目 入力値  補足
デプロイグループ名の入力 xxxxxx-production なんでも良いです。本番やステージングの切り分けがある場合はそれがわかると良いでしょう。
サービスロール CodeDeployServiceRole 必要なIAMの作成 で作ったものを選択します
デプロイタイプ インプレース Blue/Greenデプロイの設定も可能ですが、今回は社内サービスのため、インプレース。インスタンス内のアプリケーションを直接更新します。 
環境設定 image.png 元々アプリケーションが稼働していたインスタンスについているタグを選択します(なければ付けましょう)。 タググループ1、2で絞り込んでいます。タググループが同一だとOR検索、異なるとAND検索になります。
AWS CodeDeploy エージェントのインストール 1回のみ インスタンスにCodeDeployエージェントがインストールさえされていれば問題ありません。
デプロイ設定 CodeDeployDefault.AllAtOnce インスタンスが1台の場合、このルールが適切です
Load balancer ロードバランシングを有効にする チェックを外す サーバー1台かつ社内サービスなので、今回は必要ありませんでした。が、1台でもデプロイ中にメンテナンス画面等を出したい場合等は必要になるので、チェックを入れデプロイ先インスタンスが紐づいているロードバランサを選択します。

少し項目が増えましたが、こちらも設定自体はシンプルです。

CodePipelineも設定

ここまでできたら、次はCodePipelineを設定します。
S3への中間生成物のアップロードをトリガーにして、先ほど作成したCodeDeployを走らせるために必要です。
以下が設定例になります。

画像 補足
CodePipelineトップ スクリーンショット 2021-12-06 20.44.06.png パイプラインの作成ボタンから開始できます。
パイプラインの設定 image.png ここのロールは自動作成してくれます。好きなロール名にしましょう
ソースステージの追加 image.png GitHub ActionsがアップロードしているS3バケット名と、zipのオブジェクトキーを入力しましょう
ビルドステージの追加 image.png ビルドはGitHub Actionsが済ませているので、今回はスキップです。
デプロイステージの追加 image.png デプロイステージはつい先ほど設定したアプリケーション名とデプロイグループを選択しましょう。

ここまで入力できれば、パイプラインは作成できます。

これで全体的な設定は完了となります。

デプロイできなかったら?

appspec.ymlやEC2インスタンスの設定を主に疑ってみましょう。疑うポイントは以下です。

  • appspec.ymlおよびスクリプトの設定
    • この設定ファイルがない、パスが誤っている、起動スクリプトが誤っている
  • EC2インスタンスのタグ
    • 先程のCodeDeployのセットアップの環境設定で設定したタグの条件と合っているか
  • EC2インスタンスのロール
    • EC2インスタンスについているIAMロールにS3へのアクセスロールがない場合など
  • EC2インスタンスにCodeDeployエージェントがインストールされていない

確認

GitHub ActionsでビルドからS3へのアップロードがうまくいったかは確認できます。
また、CodePipelineの実行がうまくいったかどうかは、AWSのコンソールから確認できます。

codepipeline-success.png

S3 + CodeDeploy + CodePipeline に乗っていれば簡単に部分的な再実行やデバッグもできるので、
トラブル時の対応もしやすくなることが期待できるでしょう。

おわりに

今回は、PlayFrameworkのプロジェクトのデプロイを
Fabric1.xから脱却しGitHub Actions+CodeDeployで自動化できたことで
GitHubが使える社員なら誰もがデプロイ作業を行えるようになりました。
GitHub+GitHub Actionsのおかげで、コード反映直前のレビューもPullRequestベースで行えるのは社内サービスといえども安心ですね。

仕組み自体は非常に簡単なので、うまく他のレガシーな社内サービスにも適用し、
極力運用を省力化していきたいと思います。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0