CodeDeploy Agentから知るCodeDeployの処理の流れ

2015.11.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS CodeDeployとは

AWS CodeDeployはサーバへのアプリケーションデプロイプロセスを自動化するためのサービスです。と書くと固く見えますが、やってくれていることはそれほど分かりづらいものではありません。

  • アプリケーションのソースコードを
  • 配置すべき場所に
  • 決められた手順で

配置する、というプロセスを自動化してくれるのがCodeDeployです。デプロイ関連のシステムを実装されたことがある方ならイメージがつくかと思いますが、デプロイ関連の仕組みは自前で実装しようと思うと複雑になりがちです。

  • タイムアウト処理はどうする?
  • 想定外のエラーが発生したら後続処理はどうする?
  • Push型(各サーバがデプロイのコマンドを実行する)のではなく、Pull型(一つの命令に対して、全てのサーバがデプロイ処理を実施する)にはどうする?
  • ロールバックをどうやって行う?

など、考えなければいけない点が大量にあります。上に記載した面倒な点をユーザから隠して、デプロイを簡単に自動化してくれるのがAWS CodeDeployです。

過去に弊ブログでCodeDeployの記事はいくつか投稿されています。どれもわかりやすい記事ですのでCodeDeployに入門される方は一度目を通しておくと良いと思います。

CodeDeploy Agent

CodeDeployを動作させるためにはデプロイ対象となるサーバ上でCodeDeploy AgentというRuby製のデーモンを起動しておく必要があります。これが動いていると、Management ConsoleやAPIでDeployを実行した時にエージェントがそれを検知し、appspec.ymlに書かれたデプロイが走る、という順序です。

codedeploy_1

CodeDeployのデプロイの全体の流れを紹介します。

CodeDeployの実行には、デプロイ対象となるアプリケーションと、デプロイの流れを抑えたappspec.ymlファイルが必要になります。これらをまとめたものをバンドルと呼びます。それをS3かGithubに保存し、その情報をCreateDeployment API実行時にパラメータとして渡します。

APIコールが成功すると、デプロイ対象サーバのCodeDeploy Agentが対象のバンドルをローカルにダウンロードし、appspec.ymlの記述に基づいて一定のフローでデプロイを行います。デプロイのフローに関しては以下の図も参照下さい。黄色になっているステップではhookという、独自の処理を挟みこむことが可能です。

codedeploy_2

CodeDeploy Agentは、CreateDeployment APIが実行されたことをどうやって把握しているのでしょうか。CodeDeploy Agentのログ(Amazon Linuxの場合は、デフォルトでは/var/log/aws/codedeploy-agent/codedeploy-agent.logに吐かれています)を見てみると、以下のようなログが大量に見つかります。

2015-11-10 21:38:54 INFO  [codedeploy-agent(25188)]: [Aws::CodeDeployCommand::Client 200 60.061954 0 retries] poll_host_command(host_identifier:"arn:aws:ec2:us-west-2:xxxxxxxxxxxxxxx:instance/i-01234567")

CodeDeploy AgentがCodeDeployのAPIエンドポイントに対して、何か実行するべき処理がないかをポーリングしているようです。

このAPIに関してはDocumentに記載はありませんでしたが、agent内のapi.jsonに記述がありました。見たところCodeDeploy Agent用の拡張のようです。

このポーリングで何かしらのコマンドが渡ってきた時に処理が開始されるようです。逆に言うと、このAPIエンドポイントへの通信ができない状態ではデプロイ処理は失敗するということです。CodeDeployのDocumentにも外向きHTTPSの通信が必須であることが記載されています。

The AWS CodeDeploy agent communicates outbound using HTTPS over port 443.

実際にManagement Consoleからデプロイを行ってみましょう。すると、CodeDeploy agentのログに以下のような記載を見ることができます。

2015-11-10 20:44:18 INFO  [codedeploy-agent(25188)]: [Aws::CodeDeployCommand::Client 200 23.578797 0 retries] poll_host_command(host_identifier:"arn:aws:ec2:us-west-2:xxxxxxxxxxxxx:instance/i-12345678")
2015-11-10 20:44:18 INFO  [codedeploy-agent(25188)]: [Aws::CodeDeployCommand::Client 200 0.074842 0 retries] put_host_command_acknowledgement(diagnostics:nil,host_command_identifier:"WyJjb20uYW1hem9uLmFwb2xsby5kZXBsb3ljb250cm9sLmRvbWFpbi5Ib3N0Q29tbWFuZElkZW50aWZpZXIiLHsiZGVwbG95bWVudElkIjoiQ29kZURlcGxveS91cy13ZXN0LTIvUHJvZC9hcm46YXdzOnNkczp1cy13ZXN0LTI6MDE5OTMwNTAyOTM1OmRlcGxveW1lbnQvZC0wWFNBWk1MNkMiLCJob3N0SWQiOiJhcm46YXdzOmVjMjp1cy13ZXN0LTI6MDE5OTMwNTAyOTM1Omluc3RhbmNlL2ktNWMzMmQ3ODYiLCJjb21tYW5kTmFtZSI6IkFwcGxpY2F0aW9uU3RvcCIsImNvbW1hbmRQb3NpdGlvbiI6MSwiY29tbWFuZEF0dGVtcHQiOjF9XQ==")
2015-11-10 20:44:18 INFO  [codedeploy-agent(25188)]: [Aws::CodeDeployCommand::Client 200 0.023894 0 retries] get_deployment_specification(deployment_execution_id:"CodeDeploy/us-west-2/Prod/arn:aws:sds:us-west-2:019930502935:deployment/d-0XSAZML6C",host_identifier:"arn:aws:ec2:us-west-2:xxxxxxxxxxxxx:instance/i-12345678")
2015-11-10 20:44:18 INFO  [codedeploy-agent(25188)]: [Aws::CodeDeployCommand::Client 200 0.031055 0 retries] put_host_command_complete(command_status:"Succeeded",diagnostics:{format:"JSON",payload:"{\"error_code\":0,\"script_name\":\"\",\"message\":\"Succeeded\",\"log\":\"\"}"},host_command_identifier:"WyJjb20uYW1hem9uLmFwb2xsby5kZXBsb3ljb250cm9sLmRvbWFpbi5Ib3N0Q29tbWFuZElkZW50aWZpZXIiLHsiZGVwbG95bWVudElkIjoiQ29kZURlcGxveS91cy13ZXN0LTIvUHJvZC9hcm46YXdzOnNkczp1cy13ZXN0LTI6MDE5OTMwNTAyOTM1OmRlcGxveW1lbnQvZC0wWFNBWk1MNkMiLCJob3N0SWQiOiJhcm46YXdzOmVjMjp1cy13ZXN0LTI6MDE5OTMwNTAyOTM1Omluc3RhbmNlL2ktNWMzMmQ3ODYiLCJjb21tYW5kTmFtZSI6IkFwcGxpY2F0aW9uU3RvcCIsImNvbW1hbmRQb3NpdGlvbiI6MSwiY29tbWFuZEF0dGVtcHQiOjF9XQ==")

ポーリングをして、デプロイの実行があった時にはAgentがデプロイを実行しようとしているのがわかると思います。PutHostCommandAcknowledgementは、デプロイ命令を受理したよ、ということをCodeDeploy側に通知するためのAPIです。そのあと、そのデプロイの内容を読み取り、コマンドを一つづつ実行していくことになります。

まとめ

本当はhookのあたりにも触れようと思いましたが長さが中途半端になりそうなのでまた後日書きます。CodeDeployを試してみたいと思った方は、CodeDeployのManagement Consoleを開くとチュートリアル的に機能を試すことができるようになっているので、まずは一度お試し下さい!

参考