selmertsxの素振り日記

ひたすら日々の素振り内容を書き続けるだけの日記

AWS System Manager Sessions Manager のPort Forwardingを利用して踏み台を経由せずに手元からitamaeを実行する

AWS System Manager Session Managerとか、ちょっと冗談みたいな名前ですよね。 おいおいEKS化とかやってく!!

このドキュメントに書いてあること。

このドキュメントには、AWS System Manager Sessions Manager のPort Forwardingを利用して踏み台を経由せずに手元の端末からitamaeを実行するための設定方法 が記載されています。 具体的には、下記の3点になります。

  • 手元の端末にSession Manager Plugin をインストールする方法
  • インフラを構成するterraformのコードの一部(iamの設定部分)
  • itamaeを実行する手順

AWS System Manager Sessions Manager のPort Forwardingとは

aws.amazon.com

2019年8月28日に、AWS System Manager Sessions Manager の Port Forwarding という機能が発表されました。 これは、プライベートサブネットにデプロイされたEC2インスタンスと自分のPC間に、トンネルを作成してくれる機能です。 この機能を利用すると、踏み台サーバーを経由せずにEC2インスタンスにアクセスすることが可能になります。 今回はこの機能を利用して、踏み台を経由せずに、EC2インスタンスにitamaeを実行していきます。

手元端末に Session Manager Plugin をインストールする

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html#install-plugin-macos

上記のドキュメントにaws cliに Session Manager Pluginをインストールする方法が記載されています。 実際実行するコマンドは下記のようになります。

$ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
$ unzip sessionmanager-bundle.zip
$ sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
$ session-manager-plugin

Terraform設定

EC2 instanceに対してSSM Port Forwardingができるように権限を付与する

AWS SSM Port Forwardingを利用して EC2 instanceにアクセスするためには、 EC2 instanceの IAM Roleに対して、AmazonSSMManagedInstanceCoreのポリシーを付与する必要があります。 僕は下記のTerraformのコードを利用して、ポリシーの付与を行いました。

resource "aws_iam_instance_profile" "default" {
  name = "${var.name}-profile"
  role = "${aws_iam_role.default.name}"
}

resource "aws_iam_role" "default" {
  name               = "${var.name}"
  path               = "/"
  assume_role_policy = file("${path.module}/assume_role_policy.json")
}

// SSMのポリシーを付与する
data "aws_iam_policy" "ssm_core" {
  arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy" "default" {
  name   = "${var.name}-policy"
  role   = "${aws_iam_role.default.id}"
  policy = "${data.aws_iam_policy.ssm_core.policy}"
}
// assume_role_policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}

EC2 instanceにssm agentをインストールする

EC2インスタンスにおいてAWS SSMを利用するには System Manager Agentをインストールして、起動する必要があります。 今回はその設定をEC2インスタンスuser_data にて行うことにしました。 そのterraformの設定が下記のようになります。

resource "aws_instance" "ap-northeast-1a" {
  ami                         = "xxx"
  associate_public_ip_address = true
  availability_zone           = "ap-northeast-1a"
  instance_type               = "t3.medium"
  key_name                    = "xxx"
  monitoring                  = true
  ebs_optimized               = true
  disable_api_termination     = false
  source_dest_check           = true
  subnet_id                          = "$var.subnet_id"
  vpc_security_group_ids      = "${var.security_group_ids}"
  iam_instance_profile        = "${var.instance_profile_name}"

  tags = {
    Env  = "${var.env}"
    Name = "${var.name}"
  }

  user_data = file("${path.module}/install.sh")
}
#! /bin/bash

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
sudo systemctl start amazon-ssm-agent

itamaeの実行

上記でSystem Manager Port Forwardingを実行する環境が整ったので、あとはitamaeを実行するだけです。 itamaeの実行は .ssh/config にちょっとした設定を追加して、aws ssm start-session コマンドを実行すれば、後は itamae コマンドを実行するだけです。 ということで下記の手順で進めていきましょう。

.ssh/configの設定

Host xxx-staging-app-1
  HostName 127.0.0.1
  User ec2-user
  Port 9999

itamaeの実行

aws ssm start-sessionコマンドを実行して、手元の端末とEC2インスタンスの間にトンネルを作成しましょう。

$ aws ssm start-session --target i-xxx \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["22"],"localPortNumber":["9999"]}'

Starting session with SessionId: shuhei.morioka-xxx
Port 9999 opened for sessionId shuhei.morioka-xxx
Connection accepted for session shuhei.morioka-xxx

トンネルの作成が完了したら、あとはいつものようにitamaeのコマンドを実行していきます。

bundle exec itamae ssh -h xxx-staging-app-1 --node-yaml roles/xxx-staging-api/node.yml roles/xxx-staging-api/default.rb
 INFO : Starting Itamae... 
 INFO : Loading node data from /Users/xxx/node.yml...
 INFO : Recipe: /Users/xxx/default.rb
 INFO :   Recipe: /Users/xxx/itamae/cookbooks/git/default.rb
 INFO :     package[git] installed will change from 'false' to 'true'

ということで無事に、踏み台を経由せずに itamaeを実行することができました! 今の時代あんまり需要ないかもですが、この記事が誰かの手助けになるといいっすな。