はじめに
RHEL10のEC2を使って○○を検証してほしいと言われたので、いつものようにインスタンスを起動してSession Managerで接続しようとしました。ところが、接続できません。
調べてみると、今回使ったAMIにはSSM Agentが入っていませんでした。それならSSHで接続してインストールすればいいかと思ったのですが、社内プロキシなどの関係でSSH接続もうまくいかず。
あれ、これできなくね?
そこで調べて見つけたのが、EC2のユーザデータでした。今回は、ユーザデータの基本と使いどころから、SSM Agentをインストールして接続できるようになるまでを紹介します。
Session Managerで接続できなかった理由
SSM AgentはEC2上で動作し、AWS Systems Managerとの通信を行うソフトウェアです。Session Managerで接続するには、このエージェントが必要です。普段使っていたAmazon LinuxのAMIには入っていたので、インストールを意識していませんでした。
Amazon Linux 2やAmazon Linux 2023にはSSM AgentがプリインストールされているAMIがあります。一方、AWS提供のRHELのAMIにはデフォルトで入っておらず、今回使ったRHEL10のAMIでも未導入でした。RHEL10自体はSystems Managerのサポート対象なので、必要な設定を済ませればSession Managerを利用できます。
カスタムAMIなどではインストール状況が異なります。OS名だけで判断せず、使うAMIの状態を確認してください。Amazon Linuxでも、エージェントが入っているだけで必ず接続できるわけではありません。
ユーザデータとは
ユーザデータは、EC2の起動時にスクリプトや設定を渡すためのデータです。ソフトウェアのインストールや設定ファイルの配置など、起動後に行いたい処理を指定できます。
Linuxではシェルスクリプトやcloud-initの設定を渡せます。cloud-initは、インスタンスの初期設定を行うソフトウェアです。今回のようにcloud-initが動作するAMIでは、渡したスクリプトをインスタンス内で実行します。ユーザデータを入力するだけでは実行されないため、AMI側にこうした仕組みが必要です。
Linuxでシェルスクリプトを実行する場合の主な特徴は次のとおりです。
| 項目 | 内容 |
|---|---|
| 実行タイミング | デフォルトでは初回起動時 |
| 実行ユーザー | root |
| 渡せる形式 | シェルスクリプト、cloud-init設定など |
| サイズ上限 | Base64エンコード前で16KB |
| コンソールからの設定 | 入力欄にスクリプトを貼り付ける |
SSHで接続してからコマンドを実行する必要がないので、ログインする前の準備にも使えます。今回はここに助けられました。
どんなときに使うのか
例えば、次のような初期設定に使えます。
| 用途 | 処理の例 |
|---|---|
| 管理や監視の準備 | SSM AgentやCloudWatch Agentをインストールする |
| ミドルウェアの準備 | Webサーバーをインストールして起動する |
| 設定ファイルの配置 | 環境に応じた設定を書き込む |
| アプリケーションの配置 | 必要なファイルを取得して配置する |
| EC2を追加するときの設定 | 起動テンプレートに組み込み、追加するEC2にも同じ初期設定を行う |
ユーザデータでSSM Agentをインストールする
検証環境と前提
検証に使ったOSはRHEL10です。以下の手順は、新しいEC2の起動時にユーザデータを設定する場合の例として記載しています。
Session Managerを利用するには、EC2側と接続する利用者側の両方に必要な権限があることを確認します。EC2側では、例えばAmazonSSMManagedInstanceCoreポリシーを付けたIAMロールをインスタンスプロファイルとして関連付けます。利用者側にも、対象のインスタンスなどに対するssm:StartSessionなどの権限が必要です。
今回の検証では、EC2からインターネットゲートウェイ(IGW)を経由して、SSM Agentのインストール用ファイルを取得しました。
インストール用スクリプト
パッケージ名でのインストールに、自動起動の設定とサービスの起動を加えた例です。利用するリポジトリからamazon-ssm-agentを取得できる環境を前提としています。
#!/bin/bash
dnf install -y amazon-ssm-agent
systemctl enable amazon-ssm-agent
systemctl start amazon-ssm-agent
| コマンド | 処理 |
|---|---|
dnf install -y amazon-ssm-agent |
確認の入力を挟まずにSSM Agentをインストールする |
systemctl enable amazon-ssm-agent |
OS起動時にSSM Agentを自動起動するよう設定する |
systemctl start amazon-ssm-agent |
SSM Agentをその場で起動する |
インストール時にエージェントが起動する場合もありますが、この例では起動まで明示しています。ユーザデータのシェルスクリプトはrootで実行されるので、sudoは付けていません。
※このスクリプトは記載案です。検証時に使用した全行との一致は確認中です。
EC2の起動画面に設定する
- EC2の起動画面でRHEL10のAMIを選びます。
- ネットワークやIAMインスタンスプロファイルを設定します。
- 「高度な詳細」の「ユーザーデータ」にスクリプトを貼り付けます。
- 平文で貼り付ける場合は「ユーザーデータは既にBase64でエンコードされています」を選択せずに起動します。
起動後、インストールとSystems Managerへの登録が終わるまで少し待ちます。
Session Managerで接続を確認する
EC2コンソールで対象のインスタンスを選び、「接続」から「セッションマネージャー」を開きます。
今回の検証では、ユーザデータでSSM Agentをインストールした後、Session Managerで接続できました。SSHで入れずに困っていたのですが、中に入って実行しようとしていた処理をユーザデータに任せられました。
Session Managerの通常のシェル接続では、SSH用のインバウンドポートを開ける必要はありません。SSM AgentがEC2側からAWSに接続します。
使うときの注意点
デフォルトでは初回起動時だけ実行される
Linuxのユーザデータは、通常は初回起動時に実行されます。デフォルト設定のまま既存のEC2を停止してユーザデータを変更しても、次の起動時にスクリプトが再実行されるわけではありません。再実行する場合はcloud-initの実行設定などを確認する必要があります。
パスワードやアクセスキーを直接書かない
ユーザデータにパスワードやアクセスキーを直接書かないようにします。Base64でエンコードしても暗号化にはなりません。
AWSへのアクセスにはIAMロールを使い、秘密情報が必要な場合はSecrets ManagerやParameter Storeなどから取得する方法を検討します。取得した値をログに出さないことも必要です。
初期設定が増えたら処理を見直す
ユーザデータが長くなると、失敗した箇所を追うのも大変になります。設定する処理が増えてきたら、AMIにあらかじめ含めるものと起動時に実行するものを整理すると管理しやすくなります。
おわりに
今回は、RHEL10のEC2にSession Managerで接続するためにユーザデータを使いました。「中に入れないから設定できない」と思っていたところを、起動時にコマンドを実行することで解決できました。
EC2への接続だけで行き詰まっていましたが、ユーザデータでSSM Agentをインストールできたおかげで、検証を進められる状態になりました。
最後までお読みいただき、ありがとうございました!