[アップデート] CodeDeploy Agentの自動インストール&スケジュールされたアップデートが、 AWS Systems Manager Distributor との統合により可能になりました!

AWS Systems Manager Distributor の パッケージに、 AWS CodeDeploy のエージェントに対応したものが追加されました!

コンバンハ、千葉(幸)です。

AWS CodeDeploy で、 CodeDeploy エージェントの自動インストールおよびスケジュールされた更新が、 AWS Systems Manager ディストリビューターとの統合により可能になりました!

Systems Manager との連携で、一元管理が捗る可能性がありますね!

目次

従来の CodeDeploy エージェントのインストール、更新

アップデート内容の確認の前に、従来はどのような作業を行う必要があったかを確認しましょう。まずはインストールについてです。

例えば Amazon Linux の場合、以下のように S3 バケットからインストーラをダウンロードして実行する必要がありました。

sudo yum install ruby
sudo yum install wget
cd /home/ec2-user
wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto

CodeDeploy エージェントのインストールまたは再インストール - AWS CodeDeploy

エージェントの更新について、ふたたび Amazon Linux の場合を例に取ると、従来のドキュメントでは以下の記載があります。

CodeDeploy エージェント (codedeploy-agent.noarch.rpm) がインスタンスにインストールされている場合は、新しいバージョンのリリースから 24 時間以内に更新されます。更新時間を簡単にキャンセルまたは再スケジュールすることはできません。更新中にデプロイが進行中の場合、現在のデプロイライフサイクルイベントが最初に終了します。更新が完了した後、次のデプロイライフサイクルイベントでデプロイが再開します。

Amazon Linux または RHEL での CodeDeploy エージェントの更新 - AWS CodeDeploy

ユーザー側でタイミングを指定することはできず、自動的に更新が適用されると読めます。

英語(つまり最新の内容)に切り替えると従来の記述は表示されなくなり、代わりに以下のような記述になります。

To configure automatic, scheduled updates of the CodeDeploy Agent using AWS Systems Manager, follow the steps in Install the CodeDeploy Agent with AWS Systems Manager.

自動的なアップデートについてはこのドキュメントを参照せよという記述に変わっています。ここでは、AWS Systems Manager ディストリビューターを使うことが書かれています。

AWS Systems Manager ディストリビューター とは

AWS Systems Manager Distributor は、独自のソフトウェアや AWS 提供のエージェントソフトウェアをパッケージという単位で管理し、 Systems Manager 管理下のインスタンスに対して適用することができる機能です。

一回のみ適用する場合は Run Command 、スケジュールで適用する場合はステートマネージャーと連携して機能します。

詳細は以下を確認してください。

AWS Systems Manager Distributor - AWS Systems Manager

やってみた

今回は Amazon Linux2 のインスタンスで試してみます。

前提として、Systems Manager のマネージドインスタンスとして正常に認識されている状態からスタートするものとします。

ディストリビューターによる一回限りのインストール

ディストリビューターの画面に遷移すると、パッケージの一覧が表示されます。 AWSCodeDeployAgent という AWS 管理のパッケージが今回のアップデートにより増えたものと思われます。

対象のパッケージを選択し、 [ 1回限りのインストール ] を押下します。

Run Command のコマンドの実行画面に遷移します。実行する Systems Manager ドキュメントとして、自動的に AWS-ConfigureAWSPackage が選択されています。

コマンドに引き渡すパラメータとして、先ほどのパッケージ名が入力されています。

適用するターゲットを選択します。以下の方法で指定することができます。

  • 特定のタグがアタッチされているインスタンスを対象とする
  • インスタンスIDを明示的に指定
  • リソースグループを指定

今回は1台のみ、インスタンスIDを直接指定します。

その他もろもろ指定することができます。実行内容を S3 や CloudWatch Logs に出力することができるのですが、これは対象インスタンスにアタッチされている IAM ロールが権限を持っている必要があることにご注意ください。

[ 実行 ] を押下すると、Run Command が実行されます。

コマンドの実行結果はこのように確認することができます。

対象のインスタンスに接続して確認すると、CodeDeploy エージェントがインストールされ、稼働していることが確認できました。

sh-4.2$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 3859
sh-4.2$

実行内容は以下のようになっていました。

折り畳み
Initiating AWSCodeDeployAgent 1.1.0 install
Plugin aws:runShellScript ResultStatus Success
install output: Running sh install.sh
Checking Yum Package Manager...
Checking Ruby install...
Installing Ruby...
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package ruby.x86_64 0:2.0.0.648-36.amzn2.0.1 will be installed
--> Processing Dependency: ruby-libs(x86-64) = 2.0.0.648-36.amzn2.0.1 for package: ruby-2.0.0.648-36.amzn2.0.1.x86_64
--> Processing Dependency: rubygem(bigdecimal) >= 1.2.0 for package: ruby-2.0.0.648-36.amzn2.0.1.x86_64
--> Processing Dependency: ruby(rubygems) >= 2.0.14.1 for package: ruby-2.0.0.648-36.amzn2.0.1.x86_64
--> Processing Dependency: libruby.so.2.0()(64bit) for package: ruby-2.0.0.648-36.amzn2.0.1.x86_64
--> Running transaction check
---> Package ruby-libs.x86_64 0:2.0.0.648-36.amzn2.0.1 will be installed
---> Package rubygem-bigdecimal.x86_64 0:1.2.0-36.amzn2.0.1 will be installed
---> Package rubygems.noarch 0:2.0.14.1-36.amzn2.0.1 will be installed
--> Processing Dependency: rubygem(rdoc) >= 4.0.0 for package: rubygems-2.0.14.1-36.amzn2.0.1.noarch
--> Processing Dependency: rubygem(psych) >= 2.0.0 for package: rubygems-2.0.14.1-36.amzn2.0.1.noarch
--> Processing Dependency: rubygem(io-console) >= 0.4.2 for package: rubygems-2.0.14.1-36.amzn2.0.1.noarch
--> Running transaction check
---> Package rubygem-io-console.x86_64 0:0.4.2-36.amzn2.0.1 will be installed
---> Package rubygem-psych.x86_64 0:2.0.0-36.amzn2.0.1 will be installed
---> Package rubygem-rdoc.noarch 0:4.0.0-36.amzn2.0.1 will be installed
--> Processing Dependency: ruby(irb) = 2.0.0.648 for package: rubygem-rdoc-4.0.0-36.amzn2.0.1.noarch
--> Processing Dependency: rubygem(json) >= 1.7.7 for package: rubygem-rdoc-4.0.0-36.amzn2.0.1.noarch
--> Running transaction check
---> Package ruby-irb.noarch 0:2.0.0.648-36.amzn2.0.1 will be installed
---> Package rubygem-json.x86_64 0:1.7.7-36.amzn2.0.1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package               Arch      Version                    Repository     Size
================================================================================
Installing:
 ruby                  x86_64    2.0.0.648-36.amzn2.0.1     amzn2-core     73 k
Installing for dependencies:
 ruby-irb              noarch    2.0.0.648-36.amzn2.0.1     amzn2-core     94 k
 ruby-libs             x86_64    2.0.0.648-36.amzn2.0.1     amzn2-core    2.8 M
 rubygem-bigdecimal    x86_64    1.2.0-36.amzn2.0.1         amzn2-core     85 k
 rubygem-io-console    x86_64    0.4.2-36.amzn2.0.1         amzn2-core     56 k
 rubygem-json          x86_64    1.7.7-36.amzn2.0.1         amzn2-core     81 k
 rubygem-psych         x86_64    2.0.0-36.amzn2.0.1         amzn2-core     85 k
 rubygem-rdoc          noarch    4.0.0-36.amzn2.0.1         amzn2-core    324 k
 rubygems              noarch    2.0.14.1-36.amzn2.0.1      amzn2-core    216 k

Transaction Summary
================================================================================
Install  1 Package (+8 Dependent packages)

Total download size: 3.8 M
Installed size: 13 M
Downloading packages:
--------------------------------------------------------------------------------
Total                                               14 MB/s | 3.8 MB  00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : ruby-libs-2.0.0.648-36.amzn2.0.1.x86_64                      1/9 
  Installing : rubygem-psych-2.0.0-36.amzn2.0.1.x86_64                      2/9 
  Installing : rubygem-json-1.7.7-36.amzn2.0.1.x86_64                       3/9 
  Installing : rubygem-bigdecimal-1.2.0-36.amzn2.0.1.x86_64                 4/9 
  Installing : rubygem-io-console-0.4.2-36.amzn2.0.1.x86_64                 5/9 
  Installing : ruby-irb-2.0.0.648-36.amzn2.0.1.noarch                       6/9 
  Installing : ruby-2.0.0.648-36.amzn2.0.1.x86_64                           7/9 
  Installing : rubygems-2.0.14.1-36.amzn2.0.1.noarch                        8/9 
  Installing : rubygem-rdoc-4.0.0-36.amzn2.0.1.noarch                       9/9 
  Verifying  : rubygem-rdoc-4.0.0-36.amzn2.0.1.noarch                       1/9 
  Verifying  : rubygem-psych-2.0.0-36.amzn2.0.1.x86_64                      2/9 
  Verifying  : rubygems-2.0.14.1-36.amzn2.0.1.noarch                        3/9 
  Verifying  : rubygem-json-1.7.7-36.amzn2.0.1.x86_64                       4/9 
  Verifying  : rubygem-bigdecimal-1.2.0-36.amzn2.0.1.x86_64                 5/9 
  Verifying  : ruby-irb-2.0.0.648-36.amzn2.0.1.noarch                       6/9 
  Verifying  : ruby-libs-2.0.0.648-36.amzn2.0.1.x86_64                      7/9 
  Verifying  : rubygem-io-console-0.4.2-36.amzn2.0.1.x86_64                 8/9 
  Verifying  : ruby-2.0.0.648-36.amzn2.0.1.x86_64                           9/9 

Installed:
  ruby.x86_64 0:2.0.0.648-36.amzn2.0.1                                          

Dependency Installed:
  ruby-irb.noarch 0:2.0.0.648-36.amzn2.0.1                                      
  ruby-libs.x86_64 0:2.0.0.648-36.amzn2.0.1                                     
  rubygem-bigdecimal.x86_64 0:1.2.0-36.amzn2.0.1                                
  rubygem-io-console.x86_64 0:0.4.2-36.amzn2.0.1                                
  rubygem-json.x86_64 0:1.7.7-36.amzn2.0.1                                      
  rubygem-psych.x86_64 0:2.0.0-36.amzn2.0.1                                     
  rubygem-rdoc.noarch 0:4.0.0-36.amzn2.0.1                                      
  rubygems.noarch 0:2.0.14.1-36.amzn2.0.1                                       

Complete!
Checking if codedeploy-agent is already present...
Installing codedeploy-agent...
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Examining ./codedeploy-agent-1.1.0-4.noarch.rpm: codedeploy-agent-1.1.0-4.noarch
Marking ./codedeploy-agent-1.1.0-4.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package codedeploy-agent.noarch 0:1.1.0-4 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package            Arch     Version   Repository                          Size
================================================================================
Installing:
 codedeploy-agent   noarch   1.1.0-4   /codedeploy-agent-1.1.0-4.noarch    25 M

Transaction Summary
================================================================================
Install  1 Package

Total size: 25 M
Installed size: 25 M
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
 
pre hook : 1
Checking the ruby version.
Checking if there is already a process named codedeploy-agent running.
  Installing : codedeploy-agent-1.1.0-4.noarch                              1/1 
 
post hook : 1
Check if there is a codedeployagent config file.
Start codedeploy-agent in post hook if this is a first install.
  Verifying  : codedeploy-agent-1.1.0-4.noarch                              1/1 

Installed:
  codedeploy-agent.noarch 0:1.1.0-4                                             

Complete!
Starting CodeDeploy Agent...
Starting codedeploy-agent:DONE

Successfully installed AWSCodeDeployAgent 1.1.0

ディストリビューターによるスケジュールに基づいたインストール(そして更新)

一回限りの適用の確認ができたので、続いてスケジュール化するパターンを確認します。

ディストリビューターの画面より、対象のパッケージを選択して [ スケジュールへのインストール ] を押下します。( Install on a schedule の訳です。)

今度はステートマネージャーの画面に遷移します。ステートマネージャーにおいては、関連付け( Association )というコンポーネントを作成します。「関連付け」により、「どの対象に」「どのドキュメントを」「どのようなスケジュールで」実行するかを定義します。

関連付け名は省略可能ですが、今回は Deploy-test-agent-package という名称を指定します。

ドキュメントは先ほどと同じように AWS-ConfigureAWSPackage が選択されています。

パラメータでパッケージ名として AWSCodeDeployAgent が選択されているのも先ほどと同じです。

インストールタイプとして以下が選択できます。

  • [Uninstall and reinstall (アンインストールと再インストール)]:
    • パッケージは完全にアンインストールされ、再インストールされます。再インストールが完了するまで、アプリケーションは利用できません。
  • [In-place update (インプレース更新)]:
    • update スクリプトに指定した指示に従って、新しいファイルまたは変更されたファイルのみが既存のインストールに追加されます。アプリケーションは、更新プロセス中も引き続き使用できます。

パッケージをインストールまたは更新する - AWS Systems Manager

今回のケースでは「アプリケーション」とは CodeDeploy エージェントのことを指します。updateスクリプトとは、パッケージに含まれるものです。 AWS が管理するパッケージに関してはその内容を確認することができません。(見つけられませんでした。)

ターゲットを選択します。基本的に先ほどと同じですが、「マネージドインスタンス全て」も選択肢として増えています。今回も変わらず特定のインスタンスを1台のみ指定してみます。

スケジュールを指定します。 CRON 式と Rate 式を選択できます。「関連付け」で指定できる内容には制限がありますので注意してください。

  • 関連付けは、次の cron 式のみをサポートします。1/2、1、2、4、8、または 12 時間ごと。毎日または毎週の特定の時間。
  • 関連付けは、30 分以上 31 日未満の間隔の rate 式のみをサポートします。
  • オプションの Seconds フィールドを指定した場合、その値は 0 (ゼロ) のみが可能です。例: cron(0 */30 * * * ? *)

リファレンス: Systems Manager の cron 式または rate 式 - AWS Systems Manager

ちなみに、上記で [ Apply association only at the next specified Cron interval (次に指定した Cron の間隔でのみ関連付けを適用する)] にチェックを入れないと、関連付けの作成と同時にその適用が実行されます。 チェックを入れると次のスケジュールまで実行は保留されます。

そのほかにも諸々オプションを指定できます。 Run Command の場合と異なり、 CloudWatch Logs への出力には対応していません。 [ 関連付けの作成 ] を押下します。

今回はスケジュールの箇所でチェックを入れなかったため、作成と同時に「関連付け」の適用が実行されました。関連付けはこのような形で過去の実行履歴などが確認できます。

(作成した後に編集を加えてからスクショを撮ったので、バージョンが2に上がっています。関連付けはバージョン管理が可能です。)

基本的には上記の関連付けの画面から履歴を確認するのが便利ですが、 Run Command からも履歴を確認することができます。

ちなみに、今回のケースでは最新の CodeDeploy エージェントが適用されているからか、実行結果には以下が出力されているのみでした。

AWSCodeDeployAgent 1.1.0 is already installed

インスタンスに適用されているエージェントより新しいものが発表された場合、ここで更新が行われるものと思われます。

インスタンス内部からコマンドでエージェントの更新

Systems Manager を使用せず、手動で CodeDeploy エージェントの更新をする操作も試してみました。最新のエージェントがインストールされているためアップデートが行われない結果の例です。

sh-4.2$ sudo /opt/codedeploy-agent/bin/install auto
I, [2020-07-01T10:39:44.908715 #4162]  INFO -- : Starting Ruby version check.
I, [2020-07-01T10:39:44.909047 #4162]  INFO -- : Starting update check.
I, [2020-07-01T10:39:44.909103 #4162]  INFO -- : Attempting to automatically detect supported package manager type for system...
I, [2020-07-01T10:39:44.917885 #4162]  INFO -- : Checking AWS_REGION environment variable for region information...
I, [2020-07-01T10:39:44.917944 #4162]  INFO -- : Checking EC2 metadata service for region information...
I, [2020-07-01T10:39:44.937468 #4162]  INFO -- : Downloading version file from bucket aws-codedeploy-ap-northeast-1 and key latest/LATEST_VERSION...
I, [2020-07-01T10:39:45.002439 #4162]  INFO -- : Running version matches target version, skipping install
I, [2020-07-01T10:39:45.002567 #4162]  INFO -- : Update check complete.
I, [2020-07-01T10:39:45.002617 #4162]  INFO -- : Stopping updater.
sh-4.2$

終わりに

CodeDeploy エージェントのインストールおよび更新が AWS Systems Manager ディストリビューターに対応したことを確認しました。 Systems Manager と連携可能となったことで、エージェントの管理がより簡単にできるケースが出てくるかと思います。

ディストリビューターの機能を初めて知ったのですが、複数の対象に効率的にパッケージの配布を行う際には便利そうですね。今回は AWS が管理しているパッケージを扱いましたが、カスタマーが作成したパッケージを使用している例は以下をご参照ください。

以上、千葉(幸)がお送りしました。