【AWS】起動中の全てのEC2に一括でスクリプトを実行する

9 min読了の目安(約8900字TECH技術記事

はじめに

ウェブアプリケーションを作成する際はウェブ3層構造で構築することが多いと思います。

Web3層アプリケーションとは、Webシステムの構成要素をプレゼンテーション層、アプリケーション層、データ層の3層に分割し、独立したモジュールとして設計するアプリケーションである。
引用:http://ossforum.jp/en/node/813

ウェブサーバ、アプリケーションサーバ、データベースサーバと3つのサーバに各機能を分けることで、2層構造と比べてスケールやメンテナンスがしやすくなります。

ウェブ3層構造なので、本番環境だけでもサーバは3つ存在します。(稀にウェブサーバとアプリケーションサーバが同居している環境もありますが、今回は3つのサーバに分かれていることを想定します)
更に、本番環境とは別に開発環境が存在する場合はサーバ台数は6台になります。
これに加えてバッチサーバ等が存在する場合はさらにサーバの台数が増えていきます。

こういった場合に、今話題のsudoの脆弱性(CVE-2021-3156)の調査のために、各サーバのsudoのバージョンやOSの種類やバージョンを確認したい場合に、サーバ1つずつSSHしてコマンドを叩くのはとても面倒な作業です。

この記事では、上記のような各サーバにSSHすることなく、特定のスクリプトを起動中の全てのインスタンスで実行可能な AWS Systems Manager について紹介します。

AWS Systems Manager とは

AWS Systems Manager は、AWS でインフラストラクチャを表示および制御するために使用できる AWS のサービスです。Systems Manager コンソールを使用すると、複数の AWS のサービスのオペレーションデータを表示して、AWS リソース間でオペレーションタスクを自動化することができます。
引用:https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/what-is-systems-manager.html

Systems Managerを使うと、パッチの適用や特定のスクリプトの一括実行など、運用に役立つ様々なことが行えます。

今回は、Systems Managerの機能の1つである、スクリプトの実行を用いて、起動中のEC2インスタンスのOSの種類とバージョン(おまけにsudoのバージョン)を表示するスクリプトを実行してみたいと思います。

Systems Managerの各種機能は公式ページをご覧ください。

EC2用IAMロールの作成

Systems ManagerからEC2にアクセスできるようにするため、EC2にアタッチするIAMロールを作成します。

AWSマネージメントコンソールからIAMと検索し、IAMをクリック。

左側メニューからロールをクリック。

ロールの作成をクリック。

AWSサービスEC2を選択し、次のステップ:アクセス権限をクリック。

以下ロールにチェックを入れて次のステップ:タグをクリック。

  • AmazonEC2RoleforSSM(必須)
    • Systems Manager からEC2にアクセスするため
  • CloudWatchAgentServerPolicy(任意)
    • Systems Managerの実行結果をCloudWatchに出力する場合に必要

キーにName、値に分かりやすい名前を入力(今回はec2-ssm-roleと入力)し、次のステップ:確認をクリック。

ロール名(今回はssm-test-role)を入力してロールの作成をクリック。

EC2インスタンスの作成

既に何かしらのEC2インスタンスを作成されている方は、こちらをスキップして次のドキュメント作成に進んでください。
また、既存のEC2インスタンスを利用する際はEC2ロールにAmazonEC2RoleforSSMを割り当ててください。

AWSマネージメントコンソールからec2と検索し、EC2をクリック。

左側メニューからインスタンスをクリック。

Amazon Linux2 インスタンスを作成

今回はOSの種類とバージョンを確認するデモのため、異なるOSのインスタンスを立てていきます。
まずは、Amazon Linux2 のインスタンスを作成します。

インスタンスを起動をクリック。

Amazon Linux 2 AMI (HVM), SSD Volume Type を選択。

インスタンスタイプはt2.microを選択して次のステップ:インスタンスの詳細設定をクリック。

無料利用枠が終了している方はt3.microを選択した方が若干料金が安くなります。
詳しくはAWS公式の料金表をご覧ください。

サブネットをap-northeast-1a、IAMロールを先ほど作成したロール(今回はssm-test-role)にし、その他項目はデフォルトの状態で次のステップ:ストレージの追加をクリック。

ストレージの追加はデフォルトの状態で次のステップ:タグの追加をクリック。

左下のタグを追加をクリックし、キーをName、値を分かりやすい名前にして次のステップ:セキュリティグループの設定をクリック。
(今回はSSM-test AmazonLinux2と入力しています)

EC2のアクセス制御を定義するセキュリティグループを作成します。
新しいセキュリティグループを作成するを選択し、セキュリティグループ名にssm-testと入力し、説明にssm test security groupと入力。
今回作成するインスタンスは一般公開しないため、SSHのソースをマイIPにし、ルールの追加からHTTPを選択して、同じくソースをマイIPに変更し、確認と作成をクリック。

作成したインスタンスをブラウザで表示しない場合はHTTPの追加は不要です。

設定内容を確認して起動をクリック。

新しいキーペアの作成を選択し、キーペア名にssm-test-keypairと入力。(キーペア名は分かりやすい名前を入力してください)
キーペアのダウンロードをクリックし、キーペアをDLした後にインスタンスの作成をクリックします。

右下のインスタンスを表示をクリックして、作成したインスタンスが立ち上がっていることを確認。

Ubuntu Server インスタンスを作成

続いて2台目のインスタンスを作成します。
EC2→インスタンス→インスタンスを起動をクリック。

Systems Managerを用いてOSの種類とバージョンを表示するため、Amazon Linux 2 とは異なるOSを選択します。(Amazon Linux 2 でも問題ありません)

今回はUbuntu Server 20.04 LTS (HVM), SSD Volume Type - ami-0f2dd5fc989207c82 (64 ビット x86) / ami-0d1f7bec0e294ef80 (64 ビット Arm)を選択します。
Linuxサーバであればお好きなものを選んで構いません。

インスタンスをt2.microにし、次のステップ:インスタンスの詳細の設定をクリック。

サブネットをap-northeast-1c、IAMロールを先ほど作成したロール(今回はssm-test-role)にして次のステップ:ストレージの追加をクリック。

デフォルトの状態で次のステップ:タグの追加をクリック。

左下のタグを追加をクリックし、キーをName、値を分かりやすい名前にして次のステップ:セキュリティグループの設定をクリック。
(今回はSSM-test Ubuntuと入力しています)

既存のセキュリティグループを選択するをクリックし、先ほど作成したセキュリティグループを選択し、確認と作成をクリック。

選択項目を確認して起動をクリック。

既存のキーペアの選択を選択し、キーペアを先ほど作成したキーペアにし、チェックを入れてインスタンスの作成をクリック。

ドキュメント作成

それではSystems Managerに各EC2インスタンスで実行するスクリプトを登録します。
AWSマネージメントコンソールからSystemsと検索し、Systems Managerをクリック。

サイドメニューにある共有リソースからドキュメントをクリック。

コマンドまたはセッションを作成するをクリック。

以下を参考に各種情報を選択。

項目名
名前 わかりやすい名前
ターゲットタイプ - オプション /AWS::EC2::Instance
ドキュメントタイプ - オプション コマンドドキュメント
コンテンツ YAML(ここはお好みで)

登録するスクリプトは以下の通りです。
mainStepsactionはデフォルトでrunPowerShellScriptになっているため、runShellScriptに変更します。

---
schemaVersion: "2.2"
description: "show OS type and version and sudo version"
mainSteps:
- action: "aws:runShellScript"
  name: "show OS type and version and sudo version"
  inputs:
    runCommand:
    - "grep -H '' /etc/*version ; grep -H '' /etc/*release"
    - "sudo -V"


登録したスクリプトを実行

ドキュメントを作成したら、自己所有をクリックし、作成したドキュメントをクリック。

右上のコマンドを実行するをクリック。

この時点で、作成したEC2インスタンスのステータスチェックが合格している必要があります。

コマンドドキュメントに先ほど作成されたドキュメントが選択されていることを確認。

ターゲットのインスタンスを手動で選択するを選択肢、表示されているインスタンスにチェックを入れる。

出力オプションを任意で選択し、実行をクリック。
今回はチェックをしていませんが、チェックする場合はそれぞれの権限が必要です。また、2500 文字までのログはSystems Managerの実行結果で表示されます。

実行が完了したら各インスタンスIDをそれぞれ別タブで開きます。
(実行完了ステータスに自動で切り替わらないので、更新ボタンをクリックしてステータスを確認しましょう)

各ページでステップ1:出力をクリックしてログを展開すると、無事に結果が表示されていることが確認できます。

以上がSystems Managerを使ってスクリプトを一括実行するやり方でした。
サーバにSSHしないでコマンドを叩けるため、踏み台サーバをいくつか経由しているサーバに対しての操作等にも利用できると思います。

Systems Manager の注意事項

Systems Managerでは、コマンド実行時はrootユーザーという特徴があります。
su ec2-user のようにユーザーを切り替えることはでいませんのでご注意ください。

参考