AWS Systems ManagerのSession ManagerでSSHなしにEC2を管理する方法|Run Command・Parameter Storeの実践設計

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)AWS(Amazon Linux) > AWS Systems ManagerのSession ManagerでSSHなしにEC2を管理する方法|Run Command・Parameter Storeの実践設計
「プライベートサブネットのEC2に入るたびに踏み台サーバーにSSHして、そこから内部EC2に再度SSH……という二段階接続が手間すぎる」
「SSH鍵を複数人で共有している。誰がいつ何のために接続したか分からなくて怖い」

こういった声は、AWSでインフラを運用しはじめたLinuxエンジニアからよく聞きます。踏み台サーバー(Bastion Host)方式は「公開鍵認証+ポート22開放」が必須のため、鍵の紛失・共有・ローテーションが運用負荷になりがちです。

この記事では、AWS Systems Manager(SSM)のSession Managerを使って踏み台サーバーなしでEC2に接続する方法を解説します。IAMロールによるアクセス制御、Run Commandを使った一括コマンド実行、Parameter StoreによるDBパスワードなどの秘密情報管理まで、実務で使えるSSMの設計パターンをひとまとめに解説します。

動作確認環境: Amazon Linux 2023 / AWS CLI 2.17.x / AWS Systems Manager Agent 3.3.x

この記事のポイント

・aws ssm start-session でSSHなし・鍵なしでEC2に接続できる
・IAMロール(AmazonSSMManagedInstanceCore)のアタッチが唯一の前提条件
・Run Commandでタグ指定した複数EC2へ同時コマンドを実行できる
・Parameter StoreでDBパスワードをKMS暗号化して安全に管理できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

なぜ踏み台サーバーを廃止してSSMに移行すべきか

従来の踏み台サーバー方式では次のような問題が生じます。

ポート22の開放が必要: 踏み台EC2のセキュリティグループでポート22を外部に開放しなければなりません。ポート22は攻撃者が最初に狙うポートのひとつです
SSH鍵の管理コスト: 開発者ごとに鍵を発行・失効する管理が必要です。誰かが退職した際のローテーションを忘れると、不正アクセスのリスクが残ります
踏み台EC2自体の管理: 「管理するためのサーバー」を別途メンテナンスしなければならず、OS更新や設定変更が本来業務の足を引っ張ります
接続ログの取得が煩雑: bashの履歴だけでは「誰がいつ何を実行したか」の監査証跡が不完全です

AWS Systems ManagerのSession Managerに移行すると、次のような設計が実現できます。

ポート22を完全に閉じられる: セキュリティグループのインバウンドルールにSSHポートが不要になります。攻撃対象を大幅に削減できます
IAMによる認証: SSH鍵の代わりにAWS IAMポリシーでアクセス制御します。IAMロールの無効化で即時に接続を遮断できます
全セッションがCloudWatch Logsに記録: 誰がいつどのEC2に接続し何を実行したか、コマンドの出力まで含めた監査ログが自動で残ります
踏み台サーバーが不要: プライベートサブネットのEC2へも直接接続できます(VPCエンドポイント設定時)

Session Managerの設定手順

1. EC2にIAMロールをアタッチする

Session Managerを使うにはEC2にSSMへのアクセス権限を持つIAMロールをアタッチする必要があります。

# Step 1: IAMロールを作成(EC2がSSMを呼び出せる信頼ポリシー) aws iam create-role --role-name EC2-SSMRole --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" }] }' # Step 2: AWS管理ポリシー「AmazonSSMManagedInstanceCore」をアタッチ aws iam attach-role-policy --role-name EC2-SSMRole --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore # Step 3: EC2インスタンスプロファイルを作成してロールを紐づける aws iam create-instance-profile --instance-profile-name EC2-SSMProfile aws iam add-role-to-instance-profile --instance-profile-name EC2-SSMProfile --role-name EC2-SSMRole # Step 4: 既存EC2にインスタンスプロファイルをアタッチ aws ec2 associate-iam-instance-profile --instance-id i-0a1b2c3d4e5f67890 --iam-instance-profile Name=EC2-SSMProfile

新しくEC2を起動する場合は起動時に「IAMインスタンスプロファイル」を指定するだけです(マネジメントコンソールでは「インスタンスの詳細設定」の「IAMロール」欄で設定できます)。

2. SSM Agentのインストール確認

Session ManagerはEC2上で動作するSSM Agentを通じてコマンドを送信します。Amazon Linux 2023・Amazon Linux 2・Ubuntu Server 18.04以降はAmazon提供のAMIにSSM Agentがプリインストールされています。

# SSM Agentの起動状態を確認 sudo systemctl status amazon-ssm-agent # 出力例(正常動作時) # amazon-ssm-agent.service - amazon-ssm-agent # Loaded: loaded (/lib/systemd/system/amazon-ssm-agent.service; enabled) # Active: active (running) since Tue 2026-07-07 10:23:15 UTC; 2h 14min ago # Main PID: 1247 (amazon-ssm-agen) # インストールされていない場合(Amazon Linux 2023) sudo dnf install -y amazon-ssm-agent sudo systemctl enable amazon-ssm-agent --now

3. VPCエンドポイントの設定(プライベートサブネット使用時)

プライベートサブネットのEC2にインターネットへのアウトバウンドがない場合、VPCエンドポイント(AWS PrivateLink)を使ってSSMとプライベートに通信させます。Session Managerには3つのエンドポイントが必要です。

# SSM用VPCエンドポイントを3つ作成(ap-northeast-1の例) for svc in ssm ssmmessages ec2messages; do aws ec2 create-vpc-endpoint --vpc-id vpc-0abc1234 --service-name com.amazonaws.ap-northeast-1.${svc} --vpc-endpoint-type Interface --subnet-ids subnet-0def5678 subnet-0ghi9012 --security-group-ids sg-0ssm1234 --private-dns-enabled echo "Created: ${svc}" done # 出力例 # Created: ssm # Created: ssmmessages # Created: ec2messages

エンドポイントのセキュリティグループには、EC2のセキュリティグループからHTTPS(443番ポート)のインバウンドを許可するインバウンドルールを追加してください。

Session ManagerでSSHなしでEC2に接続する方法

1. Session Manager用プラグインのインストール(初回のみ)

`aws ssm start-session` コマンドの実行には、作業するPC(自分のPC)へ「Session Managerプラグイン」をインストールする必要があります。

# Linux(Amazon Linux 2023 / RHEL9 / AlmaLinux 9) sudo dnf install -y https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm # macOS(Homebrewを使う場合) brew install --cask session-manager-plugin # インストール確認 session-manager-plugin --version # 1.2.650.0

2. aws ssm start-session でEC2に接続する

インスタンスIDを指定してセッションを開始します。パスワードも鍵ファイルも不要です。

# 接続先のEC2インスタンスIDをタグ名で確認 aws ec2 describe-instances --filters "Name=tag:Name,Values=web-server-prod" --query 'Reservations[*].Instances[*].{ID:InstanceId,State:State.Name}' --output table # 出力例 # ------------------------------------------ # | DescribeInstances | # +---------------------+------------------+ # | ID | State | # +---------------------+------------------+ # | i-0a1b2c3d4e5f67890 | running | # +---------------------+------------------+ # Session Managerで接続(SSH不要・鍵不要) aws ssm start-session --target i-0a1b2c3d4e5f67890 # 接続後のプロンプト(シェルが起動する) # Starting session with SessionId: tomohiro.miyazaki-0a1b2c3d4e5f67890 # sh-5.2$ whoami # ssm-user # sh-5.2$ sudo su - # [root@ip-10-0-1-42 ~]# hostname # ip-10-0-1-42.ap-northeast-1.compute.internal

接続後は通常のSSHセッションと同じシェル操作が行えます。セキュリティグループへのポート22開放も、SSH鍵の準備も不要です。

3. 接続ログをCloudWatch Logsに保存する設定

Session Managerのセッションログはデフォルトでは保存されません。監査証跡を残すにはSSMのセッション設定(SSM-SessionManagerRunShell)を更新します。

# CloudWatch Logsのロググループを作成 aws logs create-log-group --log-group-name /ssm/session-manager # セッション設定を更新(ログ出力を有効化) aws ssm update-document --name SSM-SessionManagerRunShell --document-version "\$LATEST" --content '{ "schemaVersion": "1.0", "sessionType": "Standard_Stream", "inputs": { "cloudWatchLogGroupName": "/ssm/session-manager", "cloudWatchEncryptionEnabled": false, "idleSessionTimeout": "20" } }' # セッション終了後にログを確認 aws logs get-log-events --log-group-name /ssm/session-manager --log-stream-name i-0a1b2c3d4e5f67890 --query 'events[].message' --output text | head -30

Run CommandでEC2に一括コマンドを実行する方法

Run CommandはSSH接続なしに複数EC2へ同時コマンドを送信できる機能です。パッチ適用やサービス再起動などの定型作業を、踏み台サーバーを経由せずに実行できます。

1. 単一EC2にコマンドを送信する

# AWS-RunShellScriptドキュメントを使って単一EC2でコマンド実行 aws ssm send-command --instance-ids i-0a1b2c3d4e5f67890 --document-name "AWS-RunShellScript" --parameters '{"commands":["df -h","systemctl status nginx | head -10"]}' --comment "ディスク確認とnginxステータス" # 出力例(コマンドIDが返る) # { # "Command": { # "CommandId": "ab12cd34-ef56-7890-gh12-ij3456klmnop", # "DocumentName": "AWS-RunShellScript", # "Status": "Pending" # } # } # 実行結果を取得 aws ssm get-command-invocation --command-id "ab12cd34-ef56-7890-gh12-ij3456klmnop" --instance-id i-0a1b2c3d4e5f67890 --query '{Status:Status,Output:StandardOutputContent}'

2. タグを使って複数EC2に一括実行する

# tag:Environment=production の全EC2にセキュリティアップデートを一括適用 aws ssm send-command --targets 'Key=tag:Environment,Values=production' --document-name "AWS-RunShellScript" --parameters '{"commands":["sudo dnf update -y --security"]}' --comment "セキュリティアップデート一括適用" --timeout-seconds 600 # 全対象インスタンスの実行状況を一覧表示 aws ssm list-command-invocations --command-id "ab12cd34-ef56-7890-gh12-ij3456klmnop" --details --query 'CommandInvocations[*].{ID:InstanceId,Status:Status}' --output table # 出力例(3台のEC2に実行した場合) # ------------------------------------------- # | ListCommandInvocations | # +---------------------+-------------------+ # | ID | Status | # +---------------------+-------------------+ # | i-0a1b2c3d4e5f67890 | Success | # | i-0b2c3d4e5f678901 | Success | # | i-0c3d4e5f6789012 | Success | # +---------------------+-------------------+

Parameter Storeで秘密情報を安全に管理する設計

Parameter Storeを使うとDBパスワードやAPIキーをコードやEC2のファイルに直書きせずに管理できます。KMSによる暗号化(SecureString型)と階層パスによる整理が設計の基本です。

1. パスの命名規則(階層設計)

# 推奨の命名規則(/{環境}/{アプリ名}/{パラメータ名}) /prod/api-server/db-password /prod/api-server/db-endpoint /prod/api-server/stripe-secret-key /staging/api-server/db-password # パスに階層をつけることで、アプリ単位・環境単位でまとめて取得できる

2. SecureStringでKMS暗号化して登録・取得する

# SecureString型でパラメータを登録(KMSで自動暗号化される) aws ssm put-parameter --name "/prod/api-server/db-password" --value "P@ssw0rd!Secure2026" --type SecureString --description "本番DBの接続パスワード" # パスワードを復号して取得(--with-decryptionが必要) aws ssm get-parameter --name "/prod/api-server/db-password" --with-decryption --query 'Parameter.Value' --output text # 出力例 # P@ssw0rd!Secure2026 # 階層パス配下のパラメータを一覧表示 aws ssm get-parameters-by-path --path "/prod/api-server/" --recursive --query 'Parameters[*].{Name:Name,Type:Type}' --output table # 出力例 # ---------------------------------------------------------- # | GetParametersByPath | # +-------------------------------------+-----------------+ # | Name | Type | # +-------------------------------------+-----------------+ # | /prod/api-server/db-endpoint | String | # | /prod/api-server/db-password | SecureString | # | /prod/api-server/stripe-secret-key | SecureString | # +-------------------------------------+-----------------+

3. EC2のスクリプトからParameter Storeを参照する

#!/bin/bash # アプリ起動スクリプト(Parameter Storeから秘密情報を取得する例) DB_PASS=$(aws ssm get-parameter --name "/prod/api-server/db-password" --with-decryption --query 'Parameter.Value' --output text --region ap-northeast-1) DB_HOST=$(aws ssm get-parameter --name "/prod/api-server/db-endpoint" --query 'Parameter.Value' --output text --region ap-northeast-1) # 取得した値を環境変数にセットしてアプリを起動 export DATABASE_PASSWORD="${DB_PASS}" export DATABASE_HOST="${DB_HOST}" ./myapp --config /etc/myapp/config.yaml

EC2のIAMロールに `ssm:GetParameter` の権限があれば、コードやconfigファイルにパスワードを直書きせずに安全に参照できます。

AWSのLinuxサーバー構築と管理を体系的に学びたい方には、AWSでLinuxサーバーを学ぶ実践ロードマップもあわせてご覧ください。

トラブルシュート|Session Manager接続できない時の確認手順

1. IAMロールのアタッチ状況を確認する

接続できない最多原因はIAMロールがアタッチされていないことです。

# EC2に紐付いているIAMロールを確認 aws ec2 describe-instances --instance-ids i-0a1b2c3d4e5f67890 --query 'Reservations[0].Instances[0].IamInstanceProfile.Arn' # 出力例(設定済みの場合) # "arn:aws:iam::123456789012:instance-profile/EC2-SSMProfile" # IAMロールに必要なポリシーが付いているか確認 aws iam list-attached-role-policies --role-name EC2-SSMRole --query 'AttachedPolicies[*].PolicyName' --output text # 出力例(正常) # AmazonSSMManagedInstanceCore

2. SSM Agentの動作確認とマネージドインスタンス登録状態

# EC2にSSH接続できる場合はAgentのログを確認 sudo journalctl -u amazon-ssm-agent -n 30 --no-pager # 典型的なエラーと原因 # "Failed to load instance info from metadata" # → EC2のIAMロールが設定されていない # "No credential providers found" # → IMDSv2のみ有効な環境でIAMロール未設定 # Agentを再起動して状態確認 sudo systemctl restart amazon-ssm-agent sudo systemctl status amazon-ssm-agent # マネジメントコンソール側でのインスタンス登録状態確認 aws ssm describe-instance-information --query 'InstanceInformationList[*].{ID:InstanceId,Status:PingStatus,Agent:AgentVersion}' --output table # 出力例(正常登録済み) # --------------------------------------------------------- # | DescribeInstanceInformation | # +---------------------+---------+---------------------+ # | ID | Agent | Status | # +---------------------+---------+---------------------+ # | i-0a1b2c3d4e5f67890 | 3.3.xxx | Online | # +---------------------+---------+---------------------+ # "Online"でなく一覧に表示されない場合はIAMロールかSSM Agentを確認する

本記事のまとめ

やりたいこと コマンド / 設定
EC2にSession Managerで接続する aws ssm start-session --target i-xxxx
マネージドインスタンスの登録状態を確認する aws ssm describe-instance-information
単一EC2にコマンドを送信する aws ssm send-command --instance-ids i-xxxx --document-name AWS-RunShellScript
タグ指定で複数EC2に一括実行する aws ssm send-command --targets Key=tag:Env,Values=prod ...
コマンドの実行結果を取得する aws ssm get-command-invocation --command-id xxx --instance-id i-xxx
SecureStringでパラメータを登録する aws ssm put-parameter --type SecureString ...
Parameter Storeの値を復号して取得する aws ssm get-parameter --with-decryption ...
VPCエンドポイントを作成する(プライベートサブネット用) aws ec2 create-vpc-endpoint --service-name com.amazonaws.ap-northeast-1.ssm ...
Session Managerを導入すると「ポート22を完全に閉じる」「IAMによるアクセス制御を一元化する」「接続ログを自動記録する」という3つの改善が一度に実現できます。踏み台サーバーの廃止は運用コスト削減とセキュリティ強化の両方につながる設計変更です。

AWSのインフラをSSHなし・IAM管理の「現代的な設計」で構築しませんか?

Session Managerのコマンドは調べれば分かります。でも「IAMポリシーをどう設計するか」「VPCエンドポイントをどう組み合わせるか」を説明できますか?
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。