AWS Beanstalk環境における、Blue/Greenデプロイの実装によるデプロイ作業の簡略化
17228 ワード
- Beanstalkで構築した環境で動くRailsアプリのデプロイを毎回手作業で行っていた
- コンソール上でデプロイする場合、いちいちアプリを圧縮し手作業でUPしないといけない
- デプロイだけなら上記手順で済むが、環境そのものの設定を変更したいときは一から作り直し。。。
- CodeCommitのリポジトリを参照してBeanstalkをビルドし、デプロイ処理を実行するパイプラインを作れば、デプロイ自動化できる!ということを教えていただきましたので備忘録として書き記します
- AWSに関してはかなり初心者(片手間で3ヵ月くらいしか触ってません)なので、おかしな部分があればご指摘いただければ幸いです
利用したAWSサービス:
- Elastic Beanstalk
- CodePipeline
- CodeCommit
- CodeBuild
- CloudFormation
Blue/Greenデプロイとは
In place: インスタンスはそのままに、新しいリビジョンのアプリのみをその場で反映させる
Blue/Green: 新しいリビジョンのアプリ用に、新しいインスタンスを構築して入れ替える
そして、実現方法とは別の軸で、反映のスピードで大まかに以下の3つの分類ができます。
All at once: 全台を一斉に新しいリビジョンでデプロイする
One by one: 1台ずつ新しいリビジョンをデプロイする
Batch: 数台(例えば半数)ずつ新しいリビジョンをデプロイする
参考:
https://aws.typepad.com/sajp/2015/12/what-is-blue-green-deployment.html
https://dev.classmethod.jp/cloud/operation-blue-green-deployment/
- 今回利用したのは、Blue/GreenによるAll at Onceの方式です
- 新しいインスタンスを構築し、全てのインスタンスにおいて一斉にデプロイを行う流れになります
デプロイの流れ
- 何らかのアプリを修正or環境(インスタンスタイプとか)を修正
- CodeCommitにPushする
- Pushされたリポジトリを元にCodeBuildを実行
- 新しい環境でアプリが立ち上がる
手順
事前準備
アプリが入ったディレクトリと、環境設定ファイルが入ったディレクトリを用意する
※※※-APPと※※※-ENVってなってるやつ
APPの方はアプリを入れるだけ
ENVの方は、.ebextensionsフォルダを作成し、環境の設定をしておく。
buildspec.ymlを作成する(CodeBuildするときに実行される)
buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
python: 3.7
pre_build:
commands:
- echo awsebcli install
- pip install --upgrade pip
- pip install awsebcli
- pip --version
- eb --version
build:
commands:
- echo Build started on `date`
- mkdir app_build
- cd app_build
# プラットフォームを指定
- eb init api-dev1 --platform "ruby-2.6-(puma)" --region ap-northeast-1
# SourceAPP(アプリが入ってるディレクトリ)をコピー
- cp -a ${CODEBUILD_SRC_DIR_SourceAPP}/* ./
- cp -a ../dev1/apiweb/.ebextensions ./../dev1/apiweb/.ebextensions/00.vpc.config > ./.ebextensions/00.vpc.config
- cat .ebextensions/00.vpc.config
- touch public/alive.html
- envpre=`aws elasticbeanstalk describe-environments --application-name api-dev1 | jq '.Environments[] | select((.Status != "Terminated") and (.CNAME == "api-dev1-pre.ap-northeast-1.elasticbeanstalk.com"))' | jq -r '.EnvironmentName'`
- echo ${envpre}
# 既にBeanstalk環境が作成されていた場合、その環境をterminateし、新しく作り直す。
# 詳しくは後ほど解説
- if [ "te" != "te"${envpre} ]; then eb terminate ${envpre} --force; fi
- envdate=`date +"%Y%m%d%H%M%S" --date='9 hours'`
- eb create api-${envdate} -c api-dev-pre --timeout 30
- CodeCommitでリポジトリを作成し、クローンする
- 参考:https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ssh-unixes.html
- クローンしたディレクトリにそれぞれアプリと環境ファイルを入れ、Pushする
こんな感じで、
アプリ用リポジトリ
と環境用リポジトリ
で2つ分ける
1. CloudFormationのテンプレートでCodePipeLineとCodeBuildを作る
- CloudFormationを使う前提となります
- CodePipelineのIAMを設定する(かなり多いので割愛)
- CodeBuildのIAMを設定する(こちらも割愛)
- デプロイ設定を記載する(下記参照)
deployment.yml
# デプロイ設定
CodeBuildImage:
Type: String
Default: "aws/codebuild/amazonlinux2-x86_64-standard:1.0"
Description: Image used for CodeBuild project.
CodeBuildApiWeb:
Description: Creating AWS CodeBuild project
Type: AWS::CodeBuild::Project
Properties:
#Artifactのタイプを指定する
Artifacts:
Type: CODEPIPELINE
Description: !Sub Building stage for apiweb.
# Buildするコンテナを指定する
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: !Ref CodeBuildImage
Type: LINUX_CONTAINER
Name: codebuild-dev-apiweb
ServiceRole: !GetAtt BuildIam.Arn
# Buildspec(ビルドの際に実行される処理が書かれたymlテンプレート)の場所を指定
Source:
BuildSpec: dev/apiweb/buildspec.yml
Type: CODEPIPELINE
PipelineApiWeb:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
//Artifactのストアを指定
Location: !Ref ArtifactBucket
Type: S3
Name: !Sub codepipeline-dev-apiweb
RestartExecutionOnUpdate: false
RoleArn: !GetAtt PipeLineIam.Arn
Stages:
-
Name: Source
# ビルドするソースを指定する
Actions:
-
Name: Source1
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: 1
OutputArtifacts:
-
# 先にbeanstalkの環境を設定するファイルを持つリポジトリを指定
Name: SourceENV
Configuration:
PollForSourceChanges: false
RepositoryName: dev-Env
BranchName: master
RunOrder: 1
-
Name: Source2
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: 1
OutputArtifacts:
-
Name: SourceAPP
Configuration:
PollForSourceChanges: false
RepositoryName: dev-App
BranchName: master
RunOrder: 1
-
#CodeBuildの設定
Name: Build
Actions:
-
Name: Build
InputArtifacts:
-
Name: SourceENV
-
Name: SourceAPP
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
Configuration:
ProjectName: !Ref CodeBuildApiWeb
PrimarySource: SourceENV
RunOrder: 1
2. CloudFormationでスタックを作成する
3. CodePipelineが出来上がると同時に、CodeBuildが実行される
- この時点でCodeBuildが失敗した場合、yamlファイルの修正を行い再度スタックを作成すれば、新しいスタックが作られ古いスタックは削除される
- スタックには問題がなくて、アプリ側の問題(アプリの設定がおかしくてデプロイできない・環境設定の
builspec.yml
がおかしい、など。おそらくbuilspec.yml
がおかしいパターンが多い)の場合は、スタックを再度作成するのではなく、以下の動きとなる- エラーを修正してCodeCommitにPush
- CodePipelineで
変更をリリースする
を押下 - CodeBuildが実行される
4. beanstalkの環境がbuildspecに基づき、.ebextensionの設定値で作成される
- この段階で作成される環境のURL名にはBlue/Greenデプロイ的な使い方をするために
pre
という名前がついている(以下pre環境
とする)
5. 出来上がったpre環境をクローンする
6. 本番環境が出来上がったら、pre環境を削除する
- これで本番環境のみがBeanstalk上に存在する状態となる
運用時のデプロイ手順
- 基本的には上述の手順と同じ
1. アップデートしたアプリor環境設定ファイルをリポジトリにPUSHする
2. codepipelineで、変更をリリースする
を選択
3. リポジトリが読み込まれ、新しいEBの環境が作成される
- この段階で作成された環境は、
pre環境
となる
4. pre環境にて、動作確認を行う
5. URLをスワップ
で、本版環境のURLとpre環境のURLを入れ替える
6. 問題なければ入れ替わったpre環境を削除する
7. デプロイ作業完了
てな感じ
所感
メリット
- アプリ運用中でも、URLのスワップでほとんどダウンタイムなし(2~3秒程度)で入れ替えを行うことができる
- スワップ後に問題が発生した場合でも、再度URLをスワップすれば元の状態に戻せる
- Beanstalk環境を壊すだけでクリアな状態になるので、やり直しが楽
デメリット
- pre環境を残しておいたままにすると、当然ながら2倍の料金がかかるので注意
- Beanstalkの立ち上げに時間がかかる(約15分〜20分)ので、緊急時の対応に若干の時間がかかる可能性がある
- 大規模アーキテクチャだと運用は難しい?
備考
- おかしな記述や不明瞭な部分があればコメントいただければ幸いです!
Author And Source
この問題について(AWS Beanstalk環境における、Blue/Greenデプロイの実装によるデプロイ作業の簡略化), 我々は、より多くの情報をここで見つけました https://qiita.com/jabberwocky3376/items/f939a06f146afcf6104e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .