AWSのSession Managerを使用すると、EC2インスタンスへSSHの鍵をやりとりすることなくAWSのユーザー権限でリモートアクセスできるようになる。

本記事ではTerraformでEC2インスタンスにSession Managerによるアクセスを可能とする場合のポイントを説明する。

Session Managerでアクセス可能なEC2インスタンスの作成

EC2に設定する最低限のセキュリティグループ

Session Managerでアクセスするにはアウトバウンドでポート443が許可されている必要がある。

# セキュリティグループの作成
resource "aws_security_group" "security_group" {
  name        = "example-security-group"
  description = ...
  vpc_id      = ...
}

# アウトバウンドルールで443を許可
resource "aws_security_group_rule" "egress" {
  type              = "egress"
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.security_group.id
}

EC2のインスタンスにはこのセキュリティグループを指定する。

# EC2インスタンスの作成
resource "aws_instance" "example" {
  # ...

  vpc_security_group_ids = [aws_security_group.security_group.id]
}

ssm-agentのインストール

AMIによってはプリインストールされているが、インストールされていない場合はuser_dataで起動時にインストールする。

# EC2インスタンスの作成
resource "aws_instance" "example" {
  # ...

  # CentOS や Rocky Linuxの場合
  user_data = <<-EOF
    sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
    sudo systemctl enable amazon-ssm-agent --now
  EOF
}

IAM ポリシーの設定

EC2インスタンスにインスタンスプロファイルとしてSession Managerによる接続を許可するためのポリシーを与える必要がある。

AWSマネージドポリシーのAmazonSSMManagedInstanceCoreに必要な権限がある。 AmazonSSMManagedInstanceCoreを付加したロールを作成し、インスタンスプロファイルに設定する。

# AmazonSSMManagedInstanceCore policyを付加したロールを作成
resource "aws_iam_role" "example" {
  name               = "example_role"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

data "aws_iam_policy_document" "assume_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

data "aws_iam_policy" "example_policy_ssm_managed_instance_core" {
  arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy_attachment" "ssm_managed_instance_core" {
  role       = aws_iam_role.example_role.name
  policy_arn = data.aws_iam_policy.example_policy_ssm_managed_instance_core.arn
}

# インスタンスプロファイルを作成
resource "aws_iam_instance_profile" "example_profile" {
  name = "example_profile"
  role = aws_iam_role.example_role.name
}

作成したインスタンスプロファイルを上記で作成したaws_instanceリソースに指定する。

resource "aws_instance" "example" {
  # ...

  # インスタンスプロファイルの指定
  iam_instance_profile   = aws_iam_instance_profile.example_profile.name

}

terraform applyコマンドで正常に適用できたら完了。

Session Manager で EC2 インスタンスにアクセスする

ターミナルからSession Managerで接続するにはAWS CLIとSession Managerプラグインをインストールする必要がある。

Macの場合はHomebrewでインストールできる。

$ brew install awscli
$ brew install --cask session-manager-plugin

以下コマンドで接続できる。

$ aws ssm start-session --target <instance-id>