こんにちは。よっしーです(^^)
今日は、Terraformで構築したEC2環境にセッションマネージャで接続した方法についてご紹介します。
前提
この記事は下記の記事をベースにしています。
背景
AWSのEC2環境にセッションマネージャを利用する理由は、セキュリティと運用の向上にあります。一方、SSH接続も一定の利用場面はありますが、セッションマネージャには優れた利点があるため、場合によってはSSH接続よりも適している場合があります。
セッションマネージャを利用する理由:
- セキュリティの向上:SSH接続には、EC2インスタンスに直接アクセスする必要があります。一方、セッションマネージャはAWS Systems Managerの一部であり、HTTPS経由で暗号化されたセッションを提供します。このため、SSH接続よりもセキュリティが強化され、セッションへの不正アクセスや攻撃を減らすことができます。
- IAMロールによるアクセス制御:セッションマネージャを利用する場合、IAMロールを使用してEC2インスタンスへのアクセスを制御することができます。これにより、必要な権限を持つユーザーのみがインスタンスにアクセスできるようになります。
- インスタンスへの直接アクセス不要:SSH接続では、インスタンスへの直接アクセスが必要となりますが、セッションマネージャを利用する場合、インスタンスへの直接アクセスが不要です。これにより、セキュリティ上のリスクを軽減しつつ、運用の効率が向上します。
- ターミナルの操作を簡素化:セッションマネージャは、ターミナルエミュレータを提供し、コマンドライン操作を容易にします。SSH接続よりも使いやすく、直感的に操作できるため、管理作業の効率が向上します。
SSH接続でも依然として利用価値がある場面がありますが、特にセキュリティや運用効率を重視する場合には、セッションマネージャを活用することが推奨されます。ただし、利用にあたってはIAMロールの適切な設定や適用範囲などに注意して設定することが重要です。
修正内容
下記のファイルを更新、もしくは、作成します。下記の各セクションに各ファイルの修正内容を記載しています。
new file: ssm.tf
modified: ec2.tf
modified: output.tf
ssm.tf
下記の内容で新規作成します。
# AmazonSSMManagedInstanceCore policyを付加したロールを作成
resource "aws_iam_role" "learn-aws-ec2-ssm-role" {
name = var.tag_name
assume_role_policy = data.aws_iam_policy_document.learn-aws-ec2-assume-role.json
}
data "aws_iam_policy_document" "learn-aws-ec2-assume-role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
data "aws_iam_policy" "learn-aws-ec2-policy_ssm_managed_instance_core" {
arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_iam_role_policy_attachment" "learn-aws-ec2-ssm_managed_instance_core" {
role = aws_iam_role.learn-aws-ec2-ssm-role.name
policy_arn = data.aws_iam_policy.learn-aws-ec2-policy_ssm_managed_instance_core.arn
}
# インスタンスプロファイルを作成
resource "aws_iam_instance_profile" "learn-aws-ec2-profile" {
name = var.tag_name
role = aws_iam_role.learn-aws-ec2-ssm-role.name
}
ec2.tf
18行目に追記します。
resource "aws_instance" "learn_ec2_instance" {
ami = data.aws_ssm_parameter.learn_ec2_ami.value
instance_type = "t2.micro"
availability_zone = var.az_a
vpc_security_group_ids = [aws_security_group.learn_ec2_sg.id]
subnet_id = aws_subnet.learn_ec2_public_subnet_1a.id
associate_public_ip_address = "true"
key_name = var.key_name
user_data = file("./userdata.sh")
+ iam_instance_profile = aws_iam_instance_profile.learn-aws-ec2-profile.name
tags = {
Name = "${var.tag_name}"
}
}
output.tf
7行目に追記します。
+# 作成したEC2のインスタンスIDを出力
+output "ec2_instance_id" {
+ value = aws_instance.learn_ec2_instance.*.id
+}
環境構築
下記のコマンドを実行します。
terraform fmt
terraform validate
terraform apply
下記の結果が出力されていれば成功です。
Apply complete! Resources: 18 added, 0 changed, 0 destroyed.
Outputs:
secretsmanager_secret = "xxx"
secretsmanager_secret_version = "xxx"
ec2_global_ips = [
"xxx",
]
ec2_instance_id = [
"xxx",
]
EC2への接続
AWSマネジメントコンソールでの接続
AWS マネジメントコンソールにサインインして、EC2サービスを開きます。
「インスタンス(実行中)」をクリックします。
接続したいインスタンスを選択し、「接続」をクリックします。
「セッションマネージャー」タブをクリックし、「接続」ボタンをクリックします。
下記のような画面になれば、接続成功です。
AWS CLI での接続
Session Manager プラグインのインストール
AWS CLIで接続するには、Session Manager プラグインが必要なため、Session Manager プラグインをインストールします。
自分の環境では、M1 Mac を利用しているため、下記の手順でインストールしました。
# バンドルされたインストーラをダウンロードします。
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac_arm64/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
# パッケージを解凍します。
unzip sessionmanager-bundle.zip
# インストールコマンドを実行します。
sudo python3 sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
# 動作検証
session-manager-plugin
下記の結果になっていれば、Session Manager プラグインのインストールが成功しています。
% session-manager-plugin
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
詳しくは、公式サイトを御覧ください。
AWS CLI で接続
xxx は、terraform apply で出力された、ec2_instance_id に読み替えてください。
# xxx を ec2_instance_id に置き換えて実行
aws ssm --profile terraform start-session --target xxx
下記のような出力になれば成功です。
% aws ssm --profile terraform start-session --target xxx
Starting session with SessionId: yyy
sh-4.2$
解説
ssm.tf
このTerraformコードは、AWS Identity and Access Management (IAM) リソースを使用して、EC2インスタンスにSystems Manager (SSM) を使用するためのIAMロールとインスタンスプロファイルを作成するものです。以下は、各リソースの解説です:
aws_iam_role
リソース: このリソースは、AmazonSSMManagedInstanceCore
ポリシーを付加したIAMロールを作成します。IAMロールは、AWSリソースへのアクセス権を持つエンティティを定義します。ここでは、変数var.tag_name
に指定された名前のロールが作成されます。data "aws_iam_policy_document"
データソース: このデータソースは、IAMロールにアタッチするポリシーの条件を定義します。sts:AssumeRole
アクションをEC2サービスに対して許可することにより、EC2インスタンスがIAMロールをアサインできるようになります。data "aws_iam_policy"
データソース: このデータソースは、既存のIAMポリシーであるAmazonSSMManagedInstanceCore
ポリシーのARNを取得します。このポリシーは、SSMエージェントを実行するためにEC2インスタンスが必要とするポリシーです。このARNは、後でIAMロールにアタッチされます。aws_iam_role_policy_attachment
リソース: このリソースは、先ほど作成したIAMロールにポリシーをアタッチします。具体的には、AmazonSSMManagedInstanceCore
ポリシーをaws_iam_role.learn-aws-ec2-ssm-role
のIAMロールにアタッチします。aws_iam_instance_profile
リソース: このリソースは、インスタンスプロファイルを作成します。インスタンスプロファイルは、EC2インスタンスに関連付けられたIAMロールを指定するための仕組みです。ここでは、var.tag_name
に指定された名前のインスタンスプロファイルが作成され、先ほど作成したIAMロールが関連付けられます。
このコードの目的は、EC2インスタンスにSSMを有効化するために必要なIAMロールとインスタンスプロファイルを作成することです。SSMを有効にすることで、インスタンスのリモート管理や自動化などが可能になります。
ec2.tf
iam_instance_profile
: EC2インスタンスに関連付けるIAMインスタンスプロファイルの名前を指定します。先前に作成した aws_iam_instance_profile.learn-aws-ec2-profile
の名前が指定されています。
output.tf
このTerraformコードの最後に記載された output
ブロックは、作成したEC2インスタンスのIDをTerraform実行後に出力するためのものです。以下は、output
ブロックの解説です:
output
: Terraformのoutput
ブロックは、Terraformがリソースを作成または更新した後に、特定の値を出力するために使用されます。"ec2_instance_id"
: この行は、出力値の名前を指定しています。ここでは、作成したEC2インスタンスのIDを示すために、ec2_instance_id
という名前が使われています。この名前は、Terraform実行後に出力値を参照する際に使用されます。value
: この行は、出力する値を定義しています。aws_instance.learn_ec2_instance.*.id
は、Terraformのaws_instance
リソースで作成したEC2インスタンスのIDを取得するための指定方法です。aws_instance.learn_ec2_instance.*.id
は、リソースのアトリビュートid
の値を取得します。aws_instance.learn_ec2_instance.*
は、すべてのEC2インスタンスに対して適用されることを意味します。
このように output
ブロックを使用することで、Terraform実行後に作成されたEC2インスタンスのIDを確認することができます。Terraform実行後、この値はコンソールに表示されるほか、Terraformの出力結果としても表示されます。
トラブルシューティング
aws ssm –profile terraform start-session –target xxx
AWS CLIでEC2環境に接続しようとしたときに、下記のように出力がない問題がありました。
% aws ssm --profile terraform start-session --target xxx
# 上記のコマンドだけで、Starting session with SessionId: yyy 以降の表示がされない
AWSマネジメントコンソールでの接続はできていたので、AWS CLIコマンドの問題かと思いいろいろと調べていたところ、下記が原因でした。
session-manager-plugin に 実行権限が付与されていなかった。
-rw-r--r-- 1 root wheel 10460866 Mar 16 04:51 /usr/local/sessionmanagerplugin/bin/session-manager-plugin
なので、下記のコマンドで実行権限を付与しました。
sudo chmod +x /usr/local/sessionmanagerplugin/bin/session-manager-plugin
その後、再度、接続を試みると成功しました。
おわりに
今日は、Terraformで構築したEC2環境にセッションマネージャで接続した方法についてご紹介しました。
本記事でご紹介したソースは、下記のリポジトリにあります。
何か質問や相談があれば、遠慮なくコメントしてください。また、エンジニア案件についても、いつでも相談にのっていますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント