はじめに
AWS Systems Manager
のユーザーガイドを眺めていたところ、「Amazon S3からのスクリプトの実行」という内容が目に留まったので実際にやってみました。
AWS Systems Managerとは
SSM Agent
と呼ばれるエージェントソフトがインストールされているノードに対して、パッケージ・パッチの適用管理を行ったり、対象ノードにリモートログインしたり、今回のように対象ノードに対してスクリプトを実行したりするサービスです。
別々のサービスに分けてもいいんじゃないかと思われるほどSystems Manager
は様々な機能を提供しているサービスですが、特にリモートログイン機能は、セキュリティグループでSSH
を許可しなくてもアクセスでき、Systems Manager
側で操作ログや権限制御を行うことができることから踏み台サーバの代わりとしても使えるようなサービスになります。
実行構成
実際に試してみたところ、AWS Systems Manager
のRunCommand
機能でS3
に格納したスクリプトを実行する場合の構成としては以下のようになるようです。
やっていることはEC2インスタンスからスクリプトを実行していることと変わりませんが、実行操作をSystems Manager
が行うことで、Systems Manager
に実行履歴や実行結果が残るため、 作業ログの取り忘れなどは防止できるかなと思います。
また、Systems Manager
を介することで、他のAWSサービスと連携させやすくなるので、例えば定期実行処理のエラー通知などもやりやすくなります。
構成の制約事項
AWS Systems Manager
から、実行対象のEC2インスタンスが管理できていないと実行できないので、AWS Systems Manager
サービスと連携できるようにする必要があります。
具体的には対象のEC2インスタンスからAWS Systems Manager
に連携する際に、通常インターネットゲートウェイ、またはNATゲートウェイを経由した通信となるため、インターネットゲートウェイ、NATゲートウェイどちらにも繋がっていない場合、実行できません。
どうしてもどちらのゲートウェイも使用できないといった場合は、AWS PrivateLink
を利用すればインターネットアクセス無しでアクセスすることが可能です。
事前作業
実際にAWS Systems Manager
からスクリプトを実行するために必要となる事前作業は以下となります。
- 対象のEC2インスタンスに
SSM Agent
をインストールする。(必要であれば) - S3バケットに実行するスクリプトを格納する。
- S3&Systems Managerアクセス用ロールを作成する。
- 対象のEC2インスタンスにS3&Systems Managerアクセス用ロールをアタッチする。
SSM Agentインストール
対象のEC2インスタンスが古い場合や、オンプレミスのサーバに対してコマンド実行を行いたいといった場合にはSSM Agent
を別途インストールする必要があります。
最近のマシンイメージ(AMI
)を使用したEC2インスタンスであれば、デフォルトで導入済みとなるため、特に何もしなくても問題ありません。
インストールされているか不明な場合は以下のコマンドで確認できるので、入っていなければインストールしておきましょう。
sudo systemctl status amazon-ssm-agent
S3バケットへのスクリプト格納
Systems Manager
のRunCommand
機能で実行するスクリプトをS3バケットに格納しておきます。
今回はtest.sh
という以下のようなスクリプトを格納しました。
#!/bin/bash
echo "Hello World"
uname -n
pwd
S3&Systems Managerアクセス用ロールの作成
対象のEC2インスタンスにはSystems Manager
へのアクセスと、スクリプトが格納されているS3バケットへのアクセスを許可する必要があるので、以下のポリシーをアタッチしたIAMロールを作成しておく必要があります。
今回は以下のIAMポリシーをアタッチした「RunComanndTestRole」という名前のロールを作成するようにします。
アタッチポリシー | 説明 |
---|---|
AmazonSSMManagedInstanceCore | Systems Managerとの通信用 |
AmazonS3ReadOnlyAccess | S3に格納されているスクリプトダウンロード用 |
IAMロールの作成
IAMダッシュボードから「ロールを作成」でロールを作成します。
今回はEC2インスタンスに適用するロールを作成するため、以下のようにして次へ進みます。
検索ウィンドウ等で上で紹介した2つのポリシーを探しだし、チェックを行ったら次へ進みます。
適当なロール名(今回はRunComanndTestRole)を入力し、画面下部の「ロールを作成」からロールを作成します。
対象のEC2インスタンスにS3&Systems Managerアクセス用ロールをアタッチ
EC2ダッシュボードから対象のEC2インスタンスに先程作成したIAMロールを対象のEC2インスタンスに適用します。
尚、EC2インスタンスの作成と同時にIAMロールをアタッチした場合はすぐにSystems Manager
の画面にマネージドノードとして登録されますが、あとからIAMロールをアタッチした場合はEC2インスタンス自体を再起動するか、サービスを再起動してSystems Manager
への通信を行わせてあげる必要があるようなので、今回はEC2インスタンスにログインしてサービス再起動を行います。
sudo systemctl restart amazon-ssm-agent
Systems Manager
で管理されているかは、Systems Manager
→フリートマネージャーから確認でき、対象のノードが存在して実行中、オンラインと表示されていれば、Systems Manager
で管理されていることになります。
Amazon S3からのスクリプトの実行
いよいよSystems Manager
のRun Command
機能でコマンドを実行してみます。
Systems Manager
→Run Command
より「Run command」を選択。
実行可能なコマンドドキュメントが色々と表示されますが、検索ボックス等を使ってAWS-RunRemoteScriptを見つけ出します。
「コマンドのパラメータ」を以下のように設定。
「Source Info」の「path」と「S3URL」はダブルクォーテーションで閉じる必要があるので、忘れずにくくります。
「ターゲット」で、スクリプトを実行したいインスタンスを選択します。
インスタンスタグやリソースグループから対象を選択したり、複数選択したりすることもできるので、対象が多い場合は他のターゲット項目を活用してチェックします。
全て設定したら画面下部の実行ボタンで実行します。
尚、出力オプションに以下のようなコマンド出力結果をS3バケットへ書き込みする設定もありますが、有効にする場合は先程作成したIAMロールにS3への書き込み権限を付与させる必要があるので、S3にも残しておきたい場合はIAMロールを修正しておきます。
結果の確認
実行に成功すると、以下のようにコマンド実行結果が表示されます。
結果をコピーしたりダウンロードすることもできるので、取っておく必要がある場合は選択します。
Run Commandからのスクリプト実行について
前述している通り、S3に格納したスクリプトは対象のEC2インスタンスで実行することになります。
動作的にはSystems Manager
からEC2インスタンスにログインして、EC2インスタンス自身がS3バケットにあるスクリプトを所定のディレクトリにダウンロードして実行するといった流れになります。
実行時に使用したスクリプトは上記pwd
の結果からも分かる通り、「/var/lib/amazon/ssm/[インスタンスID]/document/orchestration/[UUID]/download
」配下に格納されており、特に削除するようなことは行わないため、EC2インスタンス上にそのまま残ります。
Systems Manager
のRun Command
機能で実行完了後もEC2インスタンス上に残り続けることをリスクと考えるのであれば、意図的に削除するような処理を導入したほうが良いかと思います。
※上記については気になったので別途記事を書きたいと思います。
2022年9月3日追記
書きました!
おわりに
EC2インスタンスに対してコマンド実行するような方法は沢山ありますが、IAMロールを追加するくらいで手軽に実行できるため、簡単な運用見直しを提案したりする場合に使えるかもと思いました。