26
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Terraformで、Systems Manager(Session Manager)でアクセスできるようにしたEC2インスタンスを構築する

Last updated at Posted at 2020-05-10

TL;DR

  • AWS Systems Managerを使って、EC2インスタンスにSSH鍵なしでアクセスできるようにしたい
  • そのための環境を、Terraformで構築する
  • AWS Systems Managerを利用するためには、EC2にAmazonSSMManagedInstanceCoreポリシーを含むIAMインスタンスプロファイルを付与する必要がある

AWS Systems Manager

AWS Systems Managerとは、AWSインフラリソースの運用の役立つサービスです。

AWS Systems Manager

AWS Systems Managerの機能は、こちら。

Systems Manager の機能

また、関連するドキュメントやポリシーなどの名前で「SSM」というのが出てくるのですが、こういう経緯みたいです。

AWS Systems Manager とは何ですか?

AWS Systems Manager (Systems Manager) は、以前は「 Amazon Simple Systems Manager (SSM) 」や「 Amazon EC2 Systems Manager (SSM) 」と呼ばれていました。サービスの元の省略名「 SSM 」は、他のいくつかのサービスコンソールを含むさまざまな AWS リソースにまだ反映されています。

AWS Systems Managerが利用できるOSは、こちら。

サポートされるオペレーティングシステム

あと、利用のための前提条件も読んでおくとよいでしょう。

Systems Manager の前提条件

Session Manager

Session Managerは、AWS Systems Managerの機能のうちのひとつで、AWS CLIを使ってEC2等の仮想マシンを管理することができるツールです。

AWS Systems Manager Session Manager

Session Managerを使うと、SSHキーを管理することなく、EC2インスタンスにアクセスしたり、管理することができます。

今回は、このSession Managerを使える状態にしたEC2インスタンスを、Terraformで作ることを目標にします。EC2インスタンスは、PublicサブネットおよびPrivateサブネットに配置することにします。

OSに関しては、Amazon Linux 2を使用します。

環境

今回の環境は、こちらになります。

$ terraform version
Terraform v0.12.24


$ aws --version
aws-cli/2.0.12 Python/3.7.3 Linux/4.15.0-99-generic botocore/2.0.0dev16


$ session-manager-plugin --version
1.1.61.0

コード

作成したコードは、こちら。

main.tf

terraform {
  required_version = ">=  0.12.24"
}

provider "aws" {
  version = "2.61.0"
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "2.33.0"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-1a"]
  public_subnets  = ["10.0.101.0/24"]
  private_subnets = ["10.0.1.0/24"]

  map_public_ip_on_launch = true

  enable_nat_gateway = true
  single_nat_gateway = true
}

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

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

resource "aws_iam_role" "role" {
  name               = "MyRole"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

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

resource "aws_iam_role_policy_attachment" "default" {
  role       = aws_iam_role.role.name
  policy_arn = data.aws_iam_policy.systems_manager.arn
}

resource "aws_iam_instance_profile" "systems_manager" {
  name = "MyInstanceProfile"
  role = aws_iam_role.role.name
}

resource "aws_instance" "public" {
  ami                  = "ami-0f310fced6141e627"
  instance_type        = "t2.micro"
  iam_instance_profile = aws_iam_instance_profile.systems_manager.name
  subnet_id            = module.vpc.public_subnets[0]
}

resource "aws_instance" "private" {
  ami                  = "ami-0f310fced6141e627"
  instance_type        = "t2.micro"
  iam_instance_profile = aws_iam_instance_profile.systems_manager.name
  subnet_id            = module.vpc.private_subnets[0]
}

クレデンシャルは、環境変数で設定することにします。

$ export AWS_ACCESS_KEY_ID=...
$ export AWS_SECRET_ACCESS_KEY=...
$ export AWS_DEFAULT_REGION=ap-northeast-1

VPC、サブネットを定義する

基礎となるネットワーク部分に関しては、AWS VPC Terraform moduleを使ってまるっと定義しました。

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "2.33.0"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-1a"]
  public_subnets  = ["10.0.101.0/24"]
  private_subnets = ["10.0.1.0/24"]

  map_public_ip_on_launch = true

  enable_nat_gateway = true
  single_nat_gateway = true
}

これで、以下が組み上がります。

  • VPC
  • インターネットゲートウェイ
  • EIP
  • NAT ゲートウェイ
  • ルーティングテーブル
  • Publicサブネット
    • map_public_ip_on_launchtrueにして、Public IPを付与する
  • Privateサブネット

IAMインスタンスプロファイルを定義する

続いて、EC2をAWS Systems Managerで利用できるように、EC2にアタッチするIAMインスタンスプロファイルを作成します。

まずは、IAMロールを定義。

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

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

resource "aws_iam_role" "role" {
  name               = "MyRole"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

IAMロールにアタッチしているのは、EC2がロールを使えるようにするためのポリシーです。

サービス用のロールを作成する (AWS CLI)

定義したIAMロールに、AmazonSSMManagedInstanceCoreポリシーをアタッチします。

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

resource "aws_iam_role_policy_attachment" "default" {
  role       = aws_iam_role.role.name
  policy_arn = data.aws_iam_policy.systems_manager.arn
}

Systems Manager の IAM インスタンスプロファイルを作成する

IAMインスタンスポリシーを定義し、IAMロールを紐付けます。

resource "aws_iam_instance_profile" "systems_manager" {
  name = "MyInstanceProfile"
  role = aws_iam_role.role.name
}

これで、EC2に付与するIAMインスタンスプロファイルが定義できました。

IAMインスタンスプロファイルって、AWSマネジメントコンソールからIAMロールを作った時には、自動で作られるんですね…。

Amazon EC2 の IAM ロール

[IAM role] リストには、IAM ロールの作成時に作成したインスタンスプロファイルの名前が表示されます。コンソールを使用して IAM ロールを作成した場合、インスタンスプロファイルが自動的に作成され、ロールと同じ名前が付けられます。IAM、API、または AWS CLI SDK を使用して AWS を作成した場合、インスタンスプロファイルに異なる名前を付けた可能性があります。

Amazon EC2 インスタンスで実行されるアプリケーションに IAM ロールを使用してアクセス許可を付与する

EC2インスタンスを定義する

あとは、IAMインスタンスプロファイルを紐付けたEC2インスタンスを定義します。

resource "aws_instance" "public" {
  ami                  = "ami-0f310fced6141e627"
  instance_type        = "t2.micro"
  iam_instance_profile = aws_iam_instance_profile.systems_manager.name
  subnet_id            = module.vpc.public_subnets[0]
}

resource "aws_instance" "private" {
  ami                  = "ami-0f310fced6141e627"
  instance_type        = "t2.micro"
  iam_instance_profile = aws_iam_instance_profile.systems_manager.name
  subnet_id            = module.vpc.private_subnets[0]
}

参考

構築

$ terraform init
$ terraform apply

Session Managerでアクセス

以下のコマンドで、EC2にアクセスできます。

$ aws ssm start-session --target [EC2のインスタンスID]

成功すると、こんなメッセージが表示されて

Starting session with SessionId: xxxxx

シェルが使えるようになります。

sh-4.2$

その他

今回、Publicサブネットで起動するEC2にはPublic IPを付与し、PrivateサブネットではNAT ゲートウェイを使える構成にしてますが、これらをやめるとSession Managerで接続できなくなります。

本来は、VPCエンドポイントを作成してアクセスするのが筋なんでしょうね。

Virtual Private Cloud エンドポイントの作成

26
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?