背景
- 月1度~2度リリースが発生するシステムの構築中
- 手動デプロイは工数がかかる上、危険
- せっかくなので自動デプロイにしたい
- Gitの場合はそのままAWS Codeシリーズと接続できるが、SVNで構築する資料があまりないので誰かの参考になれば……
環境
- VCS
- SVN
- 弊社はSVNがまだまだマジョリティ……
- SVN
- ビルダー
- Gradle
- インフラ
- EC2
- マルチAZの2台構成
- OSはAmazon Linux 2
- ALB
- EC2
- Jenkins
- 以下はチャット通知用なので任意用意でOK
- Microsoft Teams
- Microsoft PowerAutomate
- Gmail
やりたいこと
- 開発者がSVNリポジトリにコミット
- JenkinsがSVNをポーリングしてコミットを検知
- JenkinsがビルドしてS3へ資材をアップロード(検証環境・本番環境)
- AWS CodePipelineがS3のアップロードをトリガとしてパイプライン実行
- AWS CodeDeployが検証環境へローリングデプロイ
- AWS CodePipelineがGmailへ検証環境デプロイ完了・本番環境リリース承認メールを送信
- Microsoft PowerAutomate(Flow)がメールを検知してMicrosoft Teamsのチャンネルに投稿
- 開発者がチャンネルへの投稿を見て検証環境でテスト
- テストして問題なさそうであれば、開発者がAWS CodePipelineの画面より「本番環境リリース」をクリック
- AWS CodeDeployが本番環境へローリングデプロイ
この記事を読んでわかること
- 以下のCI環境構築・設定
- S3
- CodeDeploy
- CodePipeline
- Jenkins(設定のみ)
この記事で解説しないこと
- AWSアカウントの作成方法
- Gradleでのビルド方法
- Jenkinsサーバの構築方法
- 自動テスト周りの設定
前提
- ビルドはあらかじめGradleで作成したスクリプトで行う
- Jenkinsは構築済・ユーザ作成済
- 未構築の場合はEC2のAWS MarketplaceにBitnamiが出しているJenkinsのAMIがあるのでそれを使うとスムーズに構築できる
手順
S3
S3バケットの作成
リリース資材を格納するために必要。
AWSマネジメントコンソールのサービス一覧より「S3」で検索
「バケットを作成する」をクリック
バケット設定
以下を設定してバケットを作成しておく
- バケット名
- 任意のバケット名(今回はデプロイ先のURLと似た名称にしました)
- バージョニング
- 「オン」
- オンにすると同じファイル名でリリース資材を格納しても自動的に連携してくれるため
- 「オン」
CodeDeploy
エージェントのインストール
対象インスタンスにSSHし、以下のコマンドを実行してエージェントをインストールしておく
参考:CodeDeploy エージェントのインストールまたは再インストール - AWS CodeDeploy https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install.html
$ sudo yum install -y ruby
$ mkdir [作業用ディレクトリ]
$ cd [作業用ディレクトリ]
$ wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto
以下のコマンドで起動しているか確認する
$ sudo service codedeploy-agent status
appspec.ymlの作成
プロジェクトのルートに「appspec.yml」を作成する
内容は以下のようにした
version: 0.0
os: linux
files:
# 展開するファイル
- source: sample.war
# 展開する場所
destination: /opt/apache-tomcat/webapps
サービスロールの作成
ロールの作成
以下を参照してロールを作成しておく
ステップ 3: CodeDeploy のサービスロールを作成する - AWS CodeDeploy https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/getting-started-create-service-role.html
ロールのアタッチ
AWSマネジメントコンソールより、対象のインスタンスを右クリック→「インスタンスの設定」→「IAM ロールの割り当て/置換」
作成したIAMロールをアタッチし、インスタンスを再起動する
IAMインスタンスプロファイルの作成
以下を参照してロールを作成しておく
ステップ 4: Amazon EC2 インスタンス用の IAM インスタンスプロファイルを作成する - AWS CodeDeploy https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/getting-started-create-iam-instance-profile.html
アプリケーションの作成
AWSマネジメントコンソールにログインし「CodeDeploy」で検索
アプリケーションの作成
- アプリケーション名:任意のアプリケーション名
- コンピューティングプラットフォーム:EC2/オンプレミス
上記を記載して「作成」をクリック
デプロイグループの作成
デプロイグループとは
デプロイグループ = 対象環境にような概念。
今回は検証環境と本番環境で2グループ作成する。
作成
「アプリケーション」画面より「デプロイグループの作成」をクリックし、以下を入力して「デプロイグループの作成」をクリック
- サービスロール
- 作成したサービスロールを選択
- デプロイタイプ
- 任意で選択(今回はインプレースデプロイにしました)
- 環境設定
- 「Amazon EC2 インスタンス」にチェックし、Nameタグで対象インスタンスを指定
- Auto Scalingは設定していないため割愛
- デプロイ設定
- 「デプロイ設定の作成」をクリック
- デプロイ設定名
- 任意
- 正常なホストの最小数
- 2台構成のため、1台生きていればよいので「数値」として「1」
- デプロイ設定名
- 「デプロイ設定の作成」をクリック
- ロードバランサー
- 「ロードバランシングを有効にする」にチェック
- 「ALB・NLB」か「CLB」を選択
- 今回はALB
- ターゲットグループを選択
- 詳細 - オプション
- 一旦デフォルトのままにした
- (ロールバック機能が気になる)
- 一旦デフォルトのままにした
これを検証環境・本番環境の両方で作成しておく。
CodePipeline
サービスを「CodePipeline」で検索し、「パイプラインを作成する」をクリック
パイプラインの設定
- パイプライン名
- 任意のパイプライン名
- サービスロール
- 「新しいサービスロール」を選択し、ロール名を記載する
- 「AWS CodePipeline がサービスロールを作成できるようになるため、この新しいパイプラインでの使用が可能になります。」にチェック
- 高度の設定
- 一旦デフォルトのままにした
ソースの設定
- ソースプロバイダ
- 今回はS3を選択
- バケット
- 先ほど作成したバケットを選択
- S3オブジェクトキー
- リリース資材を含んだZIPファイルの名称を入力
- 今回は「test.zip」とした
- 検出オプションを選択する
- Amazon CloudWatch Events を選択
ビルドステージの選択
今回は手動でビルドするためスキップ
デプロイステージの選択
「ソースの設定」とほぼ同様
- アクションプロバイダー
- AWS CodeDeploy
- アプリケーション名
- CodeDeployの設定で作成したアプリケーション名を入力
- S3 オブジェクトキー
- CodeDeployの設定で作成したデプロイグループを入力(検証)
レビュー
内容を確認し「パイプラインを作成する」をクリック
修正
現状、S3から検証環境への自動デプロイができるように設定されている。
これに「手動テストによる検証環境での確認・承認」と「本番環境への自動デプロイ」を追加する。
「ステージを追加する」より以下を追加する
- Manual approval(メールでの通知が必要な場合は設定する。今回はGmailへの通知メール受信をトリガとしてMicrosoft TeamsのWebHookを叩くフローをMicrosoft PowerAutomateで別途作成したが省略)
- 本番環境へのデプロイ(設定内容は上記Pipelineとほぼ同様。本番環境のS3とCodeDeployを呼ぶようにする)
Jenkins
EC2 AMIにJenkinsがあったためそれをベースに新規構築した。
今回はJenkinsのユーザの作成まで終わっている前提。
新規ジョブの作成
以下を入力
- ソースコード管理:Subversion
- Repository URL:チェックアウトするディレクトリのURL
- Credentials:ユーザ認証情報
- チェックアウト方式:svn revertしてからsvn updateを実行
- revertは必須ではないが気休め程度に
ビルド・トリガ
SVMをポーリングを選ぶ。
5分に1度ポーリングするように設定する。
※念のためタイムゾーンをJSTにしておく
TZ=Asia/Tokyo
H/5 * * * *
ビルド
シェルの実行(検証環境ビルド)
ビルドスクリプトを実行し、検証環境をビルドする。
※Gradleの場合は実行権限の付与を行う
※「#WORKSPACE」はJenkinsのワークスペースを指す環境変数
chmod +x $WORKSPACE/gradlew
sudo $WORKSPACE/gradlew clean bootWar generateDeployZip -Penv=stg
Gradleの引数などはプロジェクトごとに異なるので、上記コマンドは参考程度にお願いします。
シェルの実行(本番環境ビルド)
検証環境のビルドとほぼ同様。
変数envが異なるくらい。
chmod +x $WORKSPACE/gradlew
sudo $WORKSPACE/gradlew clean bootWar generateDeployZip -Penv=prd
シェルの実行(S3へアップロード)
検証環境・本番環境の資材をS3コマンドを利用して該当のバケットへアップロードする。
sudo s3cmd put $WORKSPACE/deploy/test_stg.zip s3://staging.deploy.test.co.jp
sudo s3cmd put $WORKSPACE/deploy/test_prd.zip s3://production.deploy.test.co.jp
完成
SVNリポジトリにテストコミットして動くか試してみる。
Jenkins→S3→CodePipeline→CodeDeployと走ればOK。