[アップデート] EC2インスタンスに対しデフォルトでSSMを有効にするDefault Host Management Configurationが追加されました

2023.02.18

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

しばたです。

本日AWSより以下のアナウンスがあり、EC2インスタンスに対しデフォルトでSSMを利用可能にするための権限を設定可能になりました。

すこし注意点のある仕組みなので本記事で解説していきます。

どういうことか?

今回の更新でAWS Systems Manager(以後SSM)に新しいDefault Host Management Configuration (DHMC。日本語だと「デフォルトのホスト管理設定」) という設定が追加されました。

このDHMCはSSMのフリートマネージャーで所定の権限(IAMロール)を指定する形で設定します。
そしてSSM Agentがインスタンスプロファイルの代わりにDHMCに設定されたロールからクレデンシャルを取得しSSMの各種機能を実現する形となります。

従来の挙動と比較すると以下の点が異なります。

  • 従来の挙動
    • SSMを使うEC2インスタンスに所定のインスタンスプロファイルを設定する
    • SSM Agentは上記インスタンスプロファイルの権限で動作しSSMの各種機能を実現する
  • DHMCを有効にした場合の挙動
    • SSMを使うEC2インスタンスにインスタンスプロファイルは必須では無くなった
    • EC2インスタンスにインスタンスプロファイルが設定されている場合、SSM Agentはそのインスタンスプロファイルの権限で動作しSSMの各種機能を実現する (従来通りの挙動)
    • EC2インスタンスにインスタンスプロファイルが設定されていない場合、SSM AgentはDHMCに設定されたロールからクレデンシャルを取得しSSMの各種機能を実現する

名前通りの機能ですがエンジニア的には「インスタンスプロファイルが無い時にフォールバックされるデフォルトロール」と表現した方が分かりやすいかもしれません。

そして権限の取得方法が全く新しい形となるため、

  • SSM AgentはVer.3.2.582.0以上であること
    • 古いSSM AgentはDHMCに対応していない
  • Instance Metadata Service Version 2 (IMDSv2) のみサポート

という前提条件になっています。
IMDSv2に関してはこの機能に関してのみ必須なため、その他の機能においてIMDSv1を使うことは問題ありません。

やってみた

ここからは実際に動作確認を行います。
今回は私の検証用AWSアカウントの東京リージョンで検証しています。

1. 専用ロールの作成

最初にDHMCで設定するためのIAMロールを準備する必要があります。

AWSとしてはこのためにAmazonSSMManagedEC2InstanceDefaultPolicyという新しいマネージドポリシーを用意してくれています。このためまずはこのポリシーの利用を検討し、必要があれば他の権限も与えると良いでしょう。

ちなみに、このマネージドポリシーは従来のAmazonSSMManagedInstanceCoreとおおむね同一ですが、

  • ssm:GetParameter
  • ssm:GetParameters

の2つのアクションが不許可になっていました。
もしEC2インスタンスでSSM Parameter Storeに対する読み込みもしたい場合はAmazonSSMManagedInstanceCoreをベースにすると良いでしょう。

今回は以下のテンプレートからAmazonSSMManagedEC2InstanceDefaultPolicyをアタッチしたSSMManagedEC2InstanceDefaultRoleという名前のIAMロールを作成しておきました。

SSMManagedEC2InstanceDefaultRole.yaml

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  RoleName:
    Description: "Input SSM service role name."
    Type: String
    Default: "SSMManagedEC2InstanceDefaultRole"
Resources:
  # IAM Role
  SSMDefaultRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName:
        Fn::Sub: "${RoleName}"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "ssm.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AmazonSSMManagedEC2InstanceDefaultPolicy"

注意点 : 信頼するエンティティはSSM

このロールはEC2インスタンスではなくSSMのサービスに設定するものです。
このため信頼するエンティティはEC2(ec2.amazonaws.com)ではなくSSM(ssm.amazonaws.com)ですのでご注意ください。

加えてインスタンスプロファイルも不要です。IAMロールだけ準備してください。

2. DHMC設定変更

DHMCの設定はSSMフリートマネージャーから行います。

フリートマネージャーのマネージドノード一覧の右上にある「アカウント管理」から「デフォルトのホスト管理設定の構成」を選択します。

DHMC設定画面に遷移しますので、画面下部にある「デフォルトのホスト管理設定を有効にする」を有効にします。

するとIAMロールの設定欄が表示されますので、前項で作成したロール(今回の場合はSSMManagedEC2InstanceDefaultRole)を指定し「設定」ボタンをクリックして確定させます。

これでDHMCの有効化は完了です。
AWSのドキュメントによるとDHMCを有効にしてから実際に利用可能になるまでに30分程度かかるそうです。

ちなみにCLIから設定状況を確認する場合はこんな感じでaws ssm get-service-settingコマンドを使います。

# AWS CLI on PowerShellの場合
$region = "ap-northeast-1"
$account_id = aws sts get-caller-identity --query 'Account' --output text
aws ssm get-service-setting --setting-id "arn:aws:ssm:${region}:${account_id}:servicesetting/ssm/managed-instance/default-ec2-instance-management-role"

# デフォルトリージョン指定がされている場合は以下でも可能
aws ssm get-service-setting --setting-id "/ssm/managed-instance/default-ec2-instance-management-role"

実行例)

# "Status": "Customized" になっていれば有効
PS C:\> aws ssm get-service-setting --setting-id "/ssm/managed-instance/default-ec2-instance-management-role"
{
    "ServiceSetting": {
        "SettingId": "/ssm/managed-instance/default-ec2-instance-management-role",
        "SettingValue": "SSMManagedEC2InstanceDefaultRole",
        "LastModifiedDate": "2023-02-18T12:51:53.807000+09:00",
        "LastModifiedUser": "arn:aws:sts::xxxxxxxxxxxx:assumed-role/xxxxxxxxxxxxxx/xxxxxxxxxxxxxx",
        "ARN": "arn:aws:ssm:ap-northeast-1:xxxxxxxxxxxx:servicesetting/ssm/managed-instance/default-ec2-instance-management-role",
        "Status": "Customized"
    }
}

3. EC2の作成

DHMCが有効になった後はEC2を用意して実際にSSM Session Managerで接続してみます。

今回は本日時点で最新のAmazon Linux 2 AMI (ami-0ffac3e16de16665e :amzn2-ami-kernel-5.10-hvm-2.0.20230207.0-x86_64-gp2)を使っています。
ただ、このAMIだとSSM AgentのバージョンがVer.3.2.582.0より古いため、今回はユーザーデータで最新バージョンにしてやります。(この作業はいずれ不要になります)

マネジメントコンソールから新規にEC2を作成します。

VPC設定などは環境に応じて適当に行ってください。
インスタンスプロファイルはあえて未設定にします。

インスタンスメタデータの設定は明示的にV1とV2を使う様にしてます。

前述の通りSSM Agentを最新バージョンにするユーザーデータを仕込んでおきます。

ユーザーデータ

#!/bin/bash

# Install RPM package (一応IMDSv2を使う様にしている)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
REGION_NAME=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')
sudo yum install -y https://s3.${REGION_NAME}.amazonaws.com/amazon-ssm-${REGION_NAME}/latest/linux_amd64/amazon-ssm-agent.rpm

# Restart SSM agent
sudo systemctl restart amazon-ssm-agent

これでEC2インスタンスを作成し作成完了まで待ちます。
IAMロール(インスタンスプロファイル)が未設定のままなのが確認できますね。

DHMCが有効な場合この状態でもフリートマネージャーからマネージドノードとして認識されます。

マネージドノードとして認識されているのでSSM Session Managerで接続することができます。

いい感じですね。

注意点1 : マネージドノードとして認識されない場合

DHMCを有効にしてもマネージドノードとして認識されない場合は以下の点を調査すると良いでしょう。

  • SSM Agentのバージョンが古い
  • DHMCに設定したIAMロールの記述に誤りがある

注意点2 : 現状DHMCに対応してるのはSSMだけ

DHMCではインスタンスプロファイルではなくSSMのサービスに設定されたロールから直接クレデンシャルを取得しています。
現状SSM Agentのみこの仕組みに対応しており、たとえばAWS CLIでこのロールを使うことはできません。

(AWS CLIはDHMCに対応してないのでaws sts get-caller-identityを実行しても情報を取れない)

SSM以外でIAMロールを使う場合は従来通りインスタンスプロファイルの設定を行う必要があります。

注意点3 : EC2インスタンスにSSMに対する権限が無いインスタンスプロファイルを指定した場合

EC2インスタンスにSSMに対する権限が全くないインスタンスプロファイルをアタッチした場合にどの様な挙動になるか確認したところ、以下の様なログを出力し「インスタンスプロファイル自体は有効なもののSSMに対してはDHMCから取得したクレデンシャルを使う」という挙動になりました。
SSMを利用する分には便利ですが、SSMとそれ以外で利用するクレデンシャルが異なるのを意識する必要がありますのでご注意ください。

/var/log/amazon/ssm/amazon-ssm-agent.log (抜粋)

# インスタンスプロファイルの利用に失敗し、DHMCのクレデンシャル(Systems Manager role credentials)を使用している
2023-02-18 08:23:50 WARN EC2RoleProvider Failed to connect to Systems Manager with instance profile role credentials. Err: retrieved credentials failed to report to ssm. RequestId: 4037c2ff-cb45-43d0-94de-cb893f22d25f Error: AccessDeniedException: User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/ecsInstanceRole/i-02cdaa8efcfaa15c1 is not authorized to perform: ssm:UpdateInstanceInformation on resource: arn:aws:ec2:ap-northeast-1:xxxxxxxxxxxx:instance/i-02cdaa8efcfaa15c1 because no identity-based policy allows the ssm:UpdateInstanceInformation action
        status code: 400, request id: 4037c2ff-cb45-43d0-94de-cb893f22d25f
2023-02-18 08:23:50 INFO EC2RoleProvider Successfully connected with Systems Manager role credentials

ちなみにSSMに対する権限があるインスタンスプロファイルを設定した場合は以下の様なログを出力し従来通りの挙動をします。

/var/log/amazon/ssm/amazon-ssm-agent.log (抜粋)

# 従来どおりインスタンスプロファイルのクレデンシャル(instance profile role credentials)を使用
2023-02-18 08:30:25 INFO EC2RoleProvider Successfully connected with instance profile role credentials

最後に

以上となります。

インスタンスプロファイルの存在を意識せずにSSMを使えるのは多くの場合で便利になると思います。
本日時点ではまだSSM Agentのバージョンを新しくする必要はありますが、AMIに同梱されるバージョンも随時更新されますのでそう遠くないうちに「何も考えることなくSSMが有効になっている」状態を実現できることでしょう。