Contents
はじめに
AWSのサービスのひとつにCodeDeploy
というサービスがあります。
今回はこのCodeDeploy
を使う機会があったのでそれについて調べたことをまとめていこうと思います。
CodeDeploy
ではデプロイする元のソースはS3
かGitHub
ができますが今回はGitHub
で行います。
CodeDeployとは
CodeDeploy
とは、EC2インスタンスへのデプロイを自動化出来るサービスです。
デプロイをする際にはダウンタイムを最小限におさえるために多くの工程があるかとおもいますが、それを自動化し作業の効率化につながります。加えて、複数のEC2
インスタンスで冗長化等している場合にも、一元管理をしてくれて簡単にデプロイをすることができます。
今回はEC2インスタンスへの設定となりますがオンプレミス環境でもCodeDeploy
を使用することが出来るみたいです。
CodeDeployでできること
細かく上げるとたくさんありますが、僕的に使用する上で大きなメリットなると思ったものをあげると
1, shellスクリプトを実行することが出来る。
単純にgit pull origin master
的なことをして終わるだけではなくて、shellスクリプトを実行することが出来るのでキャッシュクリアであったり、再起動も自由に記述することが出来るわけです。なので実際なんでもできてしまいます。
2, ELBで複数台管理されてたとしてもうまくやってくれる
複数台のサーバーで構築されている場合に、デプロイ中は一旦ロードバランサーから切り離して、デプロイ完了したら接続し直して、次のデプロイを始めるというようなことも自動で行ってくれるのですごく便利です。
3, デプロイのトリガーを設定できる
今回は扱いませんが、例えばmasterブランチをプッシュしたときに自動でデプロイが走るようにする設定ができたりもします。
CodeDeployの仕組み
導入の手順を説明する前に、CodeDeploy
の仕組みを簡単に説明します。
EC2インスタンスにCodeDeployAgent
をインストールして起動します。
CodeDeployAgent
が何をするかというと、定期的にAWS側にデプロイの命令があるかどうかを問い合わせます。
もしここでデプロイの命令があればデプロイが開始します。
このような流れになっていて、この仕組を理解しておくと導入がスムーズになるので理解しておきたいところです。
導入手順
CodeDeployAgentの導入
まず先程説明したようにEC2インスタンスにCodeDeployAgent
をインストールします。
CodeDeployAgent
をインストールするためにはEC2内でaws cli
を使えるようにする必要があります。
sudo yum update
sudo yum install ruby
sudo yum install aws-cli
cd /home/ec2-user
aws s3 cp s3://aws-codedeploy-ap-northeast-1/latest/install . --region ap-northeast-1
chmod +x ./install
sudo ./install auto
導入がちゃんと出来てるかどうかは以下のコマンドで確認できます。
sudo service codedeploy-agent status
これでエラーが出る場合は導入の何処かでミスが有ると思われます。
コードデプロイエージェント関連で使う主要コマンドは、
sudo service codedeploy-agent status //ステータスの確認
sudo service codedeploy-agent start //起動
sudo service codedeploy-agent restart //再起動
vi /var/log/aws/codedeploy-agent/codedeploy-agent.log //ログの確認
ですね。
appspec.ymlを作成
github
で作成したリポジトリの一番上の階層にappspec.yml
を作成します。
これはデプロイの設定を書くファイルです。
version: 0.0
os: linux
files:
- source: ./
destination: /usr/share/nginx/html
hooks:
BeforeInstall:
- location: scripts/before.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/after.sh
timeout: 300
runas: root
このようなかんじで設定します。
いじるべき箇所はdestination
とhooks
の部分です。
destination
はデプロイを行う階層を設定します。この場合html以下に、普段git clone
したときに.gitファイル
が置かれる階層のファイルが並びます。(CodeDeploy
した際には.gitファイル
は作られません。これについては後述)
hooks
はデプロイする際に実行したいシェルスクリプトのファイルを指定することができます。セオリーとしてappspec.yml
と同じ階層にscripts
というフォルダを作成してその中にまとめておきます。
BeforeInstall
やAfterInstall
というのはCodeDeploy
のライフサイクルのことです。
AWSのページにのっていた図なのですが、ライフサイクル的にはこのようになっています。
左が通常のライフサイクルで、右はロードバランサーをかませてるときのライフサイクルです。ロードバランサーをかませている場合は、ロードバランサーから切り離したりと接続が増えるのでその分多くなっています。
先程の図の黒く塗られてない部分はフックとしてshell
を実行することができます。
各ライフサイクルの簡単な説明を書いておきます。
ApplicationStop | アプリケーションを正常にストップするための処理を書きます。 |
---|---|
DownloadBundle | CodeDeployAgent がアプリケーションリビジョンファイルを一時的な場所にコピーします。 |
BeforeInstall | インストールの直前に呼ばれ、現在のバージョンのバックアップの作成などの事前インストールタスクに使用します。 |
Install | CodeDeployAgent がリビジョンファイルをdestination に指定した場所にコピーします。 |
AfterInstall | インストールの直後に呼ばれ、アプリケーションの設定や、ファイルのアクセス権限の変更などのタスクに使用できます。 |
ApplicationStart | 通常、ApplicationStop中に停止したサービスを再起動する場合に、このデプロイライフサイクルイベントを使用します。 |
ValidateService | デプロイが正常に完了したことを確認するために使用されます。 |
BeforeBlockTraffic | ロードバランサーから登録解除される直前に呼ばれます。 |
BlockTraffic | ロードバランサーから登録解除されます。 |
AfterBlockTraffic | ロードバランサーから登録解除された直後に呼ばれます。 |
BeforeAllowTraffic | ロードバランサーに登録する直前に呼ばれます。 |
AllowTraffic | ロードバランサーに登録します。 |
AfterAllowTraffic | ロードバランサーに登録する直後に呼ばれます。 |
ここでApplicationStop
だけ注意なのですが、新しいリビジョンファイルのダウンロードの前に呼ばれるものなので、このイベントに関しては既存のappspec.yml
の設定に書かれているものが実行されるので注意です。それ以降のイベントに関してはデプロイするバージョンのappspec.yml
の設定が採用されます。
IAMを作成する
EC2
に設定する用と、CodeDeploy
の設定で作成するデプロイグループに設定する用のIAM
を作成しないといけません。
・EC2に設定するIAM
AmazonEC2RoleforAWSCodeDeploy
をアタッチ
信頼関係には以下を設定
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
・デプロイグループに設定するIAM
AWSCodeDeployRole
をアタッチ
信頼関係には以下を設定
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "codedeploy.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
以上の2つのIAM
を作成して、対象のEC2
に割り当てましょう。デプロイグループはこの後作成するのでその際に付けます。
IAMで注意
今回のようにCodeDeployAgent
の起動のあとにIAM
を作成して割り当てた場合にCodeDeployAgent
の権限のエラーが起こる場合があります。
vi /var/log/aws/codedeploy-agent/codedeploy-agent.log
でログが確認できますが、その際に
2017-12-13 11:56:56 INFO [codedeploy-agent(2604)]: Version file found in /opt/codedeploy-agent/.version with agent version OFFICIAL_1.0-1.1352_rpm.
2017-12-13 11:56:56 ERROR [codedeploy-agent(2604)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Missing credentials - please check if this instance was started with an IAM instance profile
このようなかんじのエラーがはかれていると思います。これはCodeDeployAgent
が定期的にデプロイがあるかどうかをAWS側に確認しに行く際にその権限がなくてエラーになっているというログです。
その場合には、
sudo service codedeploy-agent restart
を実行するようにしましょう。
その後ログを確認して先程のエラーが出てなければ大丈夫です。
CodeDeployの設定
ここからついにAWSのCodeDeploy
のコンソール画面で設定していきます。
CodeDeploy
の画面に行き「アプリケーションの作成」をクリックします。
アプリケーションごとに設定することができます
このような画面になるので、アプリケーション名を入力します。
コンピューティングプラットフォームは今回EC2インスタンスを使用するのでEC2/オンプレミスを選択します。
デプロイグループ名も設定してください。1つのアプリケーションに対して、デプロイグループを設定することができて、デプロイグループごとにどのインスタンスに対してデプロイするのかなど分けることができます。
デプロイタイプは今回は「インプレースデプロイ」にします。
これは同じインスタンスにデプロイするのか、その都度新しいインスタンスを作成して古いのを削除するのかのやりかたの違いです。
次にデプロイを行うEC2インスタンスを選択します。
対象のEC2がAutoScaling
グループとして既に設定されている場合はAutoScaling
グループを選択します。
そうでない場合はインスタンスを個別に設定することが出来るので設定しましょう。
ロードバランサーをかませている場合は「ロードバランシングを有効にする」にチェックを入れましょう。
加えてそのロードバランサーを選択します。
次にデプロイ設定です。
これは複数台合った場合にどの順番でデプロイするかを設定します。
CodeDeployDefault.AllAtOnce | 一回で全部のインスタンスにデプロイしようとします。 |
---|---|
CodeDeployDefault.HalfAtATime | 半分ずつデプロイします。 |
CodeDeployDefault.OneAtATime | 1つずつデプロイします。 |
このようになっていて、ロードバランサーを経由している場合はCodeDeployDefault.OneAtATime
で設定しておくといいと思います。
そしてサービスロールARN
は先程作成したCodeDeploy
用のIAM
を選択しましょう。
これで設定は完了になります。
実際にデプロイ
設定が完了したので実際にデプロイをしてみましょう。
CodeDeploy
の画面に行きデプロイしたいアプリケーションを選択します。
するとこのような画面になるので、デプロイしたいデプロイグループを選択して、新しいリビジョンのデプロイを選択します。
次の画面でデプロイの設定をしていきます。
デプロイするアプリケーションとデプロイグループが正しいことを確認し、今回はリポジトリタイプにGitHub
を選択します。
GitHub
にする場合には最初にアカウント認証が入ると思うので設定しておきます。
設定し終わったら対象のリポジトリとデプロイするコミットIDを入力します。
コミットIDで指定できるのでどのバージョンでもデプロイ出来ることがわかります。
なぜコミットID指定になっているかというと、CodeDeploy
では内部的にgit archive
をしています。git archive
はコミットIDを指定してZip形式で出力するものです。
なのでコミットID指定であるのとデプロイした後に.gitファイル
が作成されないのはこのためです。
あとはロールバックの設定をします。とりあえずこんなかんじにしました。
これで完了です。
うまく設定できていればこれで完了になって無事完了になります。
しかし今回は失敗してしまいました。失敗するとこのような画面になります。何か設定がミスってたみたいです。
まずエラーログをみたいので、その場合には「全てのインスタンスの表示」ボタンをクリックします。
このような画面になるので「イベントの表示」をクリックします。
この画面はエラーじゃなくても進行中の場合にどこまで進行しているか確認のために使うことができます。
先程のライフサイクルごとにどこまで進行したかがわかるようになっています。
ログを表示するをクリックします。
このような画面になりログが表示されます。今回はパスの指定が悪かったみたいです。
この画面で表示されるログは、
vi /var/log/aws/codedeploy-agent/codedeploy-agent.log
で表示されるログの直近のものを表示してくれる画面になっています。
修正してみたらうまくいきました。
今後の展望
今回CodeDeploy
を扱ってみましたが今回の内容は最低限必要な部分をまとめたというかんじでした。他にも細かい機能があるのでそのへんも今後使いこなせるようにしていけたらなと思います。