別の AWS アカウントの EC2 インスタンスにセッションマネージャーでつなぎたい！


こんにちは。
この記事は、[株式会社日立システムズ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/hisys) の25日目の記事です。

今回は、普段利用している AWS アカウントのマネージメントコンソールから、別の AWS アカウントで稼働している Amazon Elastic Compute Cloud(Amazon EC2) インスタンスに対してセッションマネージャーで接続したい！といった場合の試行方法についてお伝えします。

構成図のイメージは以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/1e36b71c-b824-5a35-a1e9-93ebb3d1ba62.png)


# 概要
AWS Systems Manager ユーザーガイドの **[ハイブリッド環境で AWS Systems Manager を設定する](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-managedinstances.html)** の記載から、別の AWS アカウントの Amazon EC2 インスタンスにセッションマネージャーで接続するために、最低限何をしたらよいかをまとめました。

※実際の運用に導入する際には、必要な権限などを割り当ててください。

## この記事での前提
上図でいうところの接続**先** AWS アカウントのマネージメントコンソールなどから、セッションマネージャーで接続**先**の Amazon EC2 インスタンスに対してアクセスできる状態にある。

## ながれ

1. 接続**元**の AWS アカウント: マネージメントコンソールから AWS Systems Manager のコンソールを開き、ハイブリッドアクティベーションの画面でアクティベーションを作成する
2. 接続**先**の Amazon EC2 インスタンス：アクティベーション操作を実施する
3. 接続**元**の AWS アカウント: マネージメントコンソールから AWS Systems Manager のコンソールを開き、セッションマネージャーの画面から接続**先**の Amazon EC2 インスタンスに接続する


# 実際にやってみる
## アクティベーションの作成
**※接続元 AWS アカウントでの作業です※**

接続**元**の AWS アカウントで AWS Systems Manager のコンソールを開き、ハイブリッドアクティベーションの画面を表示します。
そして、「アクティベーションの作成」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/23cdbe92-3975-cd33-b4be-b56ebda6bfd5.png)

画面が切り替わり、以下が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/2f2c107b-2078-5ef2-ca5b-a8dcc4c4e364.png)

試すだけなら、特に設定することなくデフォルトのままで「アクティベーションの作成」ボタンを押下します。

画面が切り替わり、以下が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/2bd98777-64dc-f9f2-789e-e01d65de6053.png)

この Activation Code と Activation ID を使って、接続**先** インスタンスの設定を変更するのでテキストエディタにコピペしておきます。

## アクティベーション操作
**※接続先 AWS アカウントでの作業です※**
接続**先** Amazon EC2 インスタンスに接続**先** AWS アカウントから接続します。

以下のコマンドを実行します。
このコマンドを実行することで、接続**元** AWS アカウントでのアクティベーション情報が登録されます。

```sh
ActivationCode=<アクティベーションを作成した際に表示された Activation Code の値>
ActivationID=<アクティベーションを作成した際に表示された Activation ID の値>
Region=ap-northeast-1

echo "yes" | sudo amazon-ssm-agent -register -code "${ActivationCode}" -id "${ActivationID}" -region "${Region}" && sudo systemctl restart amazon-ssm-agent
```

実行すると以下のような出力がされます。
一部エラーが出ていますが、表示されたファイルがその時点で存在しないというものであり、問題ありません。

Successfully とともに、```mi-``` からはじまる instance-id が表示されれば、アクティベーション成功です。

```sh
Error occurred fetching the seelog config file path:  open /etc/amazon/ssm/seelog.xml: no such file or directory
Initializing new seelog logger
New Seelog Logger Creation Complete
YYYY-MM-DD hh:mm:ss INFO Successfully registered the instance with AWS SSM using Managed instance-id: mi-*****************

```

## 接続
**※接続元 AWS アカウントでの作業です※**

接続**元**の AWS アカウントで AWS Systems Manager のコンソールを開き、セッションマネージャーの画面を表示します。

そして、「セッションの開始」ボタンを押下します。
※場合によってはランディングページが表示される可能性がありますが、「セッションの開始」のようなボタンをクリックすれば進めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/4023bb30-d957-403b-5d11-238e66caf7b1.png)

画面が切り替わり、以下が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/3a91f9d8-fa78-3381-5114-75d4bc286270.png)

接続**先** の Amazon EC2 インスタンスでアクティベーション操作をした際に表示された ```mi-``` からはじまる ```instance-id``` の値の行にある、ラジオボタンを選択し、「セッションを開始する」ボタンをクリックします。

すると、アドバンスドインスタンスの有効化のダイアログが表示されます。
これは、ハイブリッドアクティベーションで登録したインスタンスに対してセッションマネージャーで接続する際に必要な設定のため、未設定の場合に表示されます。
アドバンスドインスタンスを有効化すると、費用が1台当たり 0.00695 USD/時間 かかりますので、ご注意ください。
※10台管理していたら、1か月(約720時間)で約50ドルかかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/3aa13e8f-a4cf-85b5-c53e-b55dc48468af.png)

有効化しないと接続できないので、チェックボックスにチェックを入れて、「設定の変更」ボタンをクリックします。

そして、改めて、「セッションを開始する」ボタンをクリックすると、別の AWS アカウントのAmazon EC2 インスタンス に接続できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/09f03f92-dfd9-9f6b-deab-8bbb75c4456a.png)

以下のコマンドを実行すると、[インスタンスメタデータ](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html)の値を取得できます。
インスタンスメタデータは、 Amazon EC2 インスタンス自体のインスタンス ID や IP アドレス、MAC アドレスなどを確認することができます。

```sh
curl http://169.254.169.254/2021-07-15/meta-data/instance-id
i-*****************
```

## あとかたづけ
試行が終わったら、後片付けを行います。


### AWS Systems Manager エージェントの初期化
**※接続先 Amazon EC2 インスタンス上での作業です※**
以下のコマンドを実行することで、アクティベートした情報が初期化され、接続**先** AWS アカウントでの管理に戻ります。

```sh
sudo amazon-ssm-agent -register -clear
```

### 接続先 Amazon EC2 インスタンスの登録解除
**※接続元 AWS アカウント上での作業です※**
接続**元** AWS アカウントに登録されている、接続**先**の Amazon EC2 インスタンスの登録を解除します。
AWS Systems Manager のコンソールにアクセスし、フリートマネージャーの画面を表示します。

そして、 ```mi-``` から始まる ID をもつインスタンスを選択し、Node actions から、Deregister this managed node をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/44ca3f7d-200d-00a3-519d-46aa6cc2159f.png)

以下のような「このマネージドインスタンスの登録を解除する」という表示がなされるので、インスタンスIDの値を改めて確認し、問題がなければ、「登録解除」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/c01c38b6-e0f0-d3eb-f832-9bf7e6ac77d5.png)

画面が切り替わり、以下のような状態になれば、登録が解除されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/566c34a2-54bc-5321-3aae-10ced4c5dee8.png)
※すぐに消えない場合がありますので、再読み込みアイコン(ぐるぐるアイコン)を何度かクリックしてください。

### アドバンスドインスタンスの設定解除
**※接続元 AWS アカウント上での作業です※**
接続**先** Amazon EC2 インスタンスの登録解除の操作から引き続き実施します。

AWS Systems Manager のコンソールのフリートマネージャーの画面上部にある、「設定」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/b23af3cd-f1ce-4698-c324-773a11b00dee.png)

インスタンス枠のエリアにある「アカウント設定の変更」ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/397af46f-2921-4525-99eb-7ef4e69e1580.png)

高度な層(アドバンスドインスタンスのことだと推察)から標準層(スタンダードインスタンスのことと推察)への変更を確認が表示されるので、チェックボックスにチェックを入れて、「設定の変更」ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/9175820c-e18b-e5f2-799d-d1b51992baa2.png)

すると画面が切り替わります。
30分程度で、以下のような「高度なインスタンス」の表示が消えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548623/47929ed0-e7e7-65ff-8cc0-2831c46afe68.png)

# まとめ
どうしても、自分が管理する AWS アカウント(この記事でいう接続**元**アカウント)のマネージメントコンソールから、別のアカウントにある Amazon EC2 インスタンスに対してセッションマネージャーで接続するにはどうしたらよいか？への解答になるのかなと思います。

# おまけ
ただ、費用がかかってしまうので、別アカウントとはいえ Amazon EC2 インスタンスに対してなのであれば、若干もったいない気もします。

そこで、AWS CLI で実行すれば、以下の方法も使えます。

* 接続**先** AWS アカウントで IAM ユーザーを払い出してもらい、そのユーザーに セッションマネージャーを利用する最小限の権限を当ててもらう。そのユーザーのアクセスキーとシークレットアクセスキーで ```ssm start-session``` を実行する
* 接続**先** AWS アカウントで IAM ロールを払い出してもらう。ロールは、セッションマネージャーを利用する最小限の権限を付与してもらう。そのロールへクロスアカウントアクセスをして、取得できたトークンを使って ```ssm start-session``` を実行する

※どちらの方法でも、マネージメントコンソールで実行可能です。あくまでも、接続**先** AWS アカウントのマネージメントコンソールへのログイン不可であることを前提条件としています。

## AWS CLI でスイッチロールして、セッションマネージャーで接続する
### 前提
* 接続**先** AWS アカウントに IAM ロールを作成してもらう。
 * 必要最低限のポリシー付与してもらう。
 * 信頼関係のプリンシパルに接続**元** AWS アカウントを指定してもらう。<br>もしく、接続**元** AWS アカウントの IAM ユーザーを指定してもらう。

### 設定
```.aws/config``` ファイルに以下を追記、設定をすることで、簡単にクロスアカウントアクセスが行えます。
実行環境ごとに微妙に設定が異なるので、ご確認ください。

#### 接続元の AWS アカウント上の IAM ユーザーのアクセスキーを利用している場合
```sh:.aws/config
[profile <任意の文字列>]
source_profile=default
role_arn=arn:aws:iam::<接続先AWSアカウントID>:role/<IAMロール名>
```

#### 接続元の AWS アカウント上の Amazon EC2(IAM ロール(インスタンスプロファイル)でSTSの権限付与済み)の場合
```sh:.aws/config
[profile <任意の文字列>]
credential_source=Ec2InstanceMetadata
role_arn=arn:aws:iam::<接続先AWSアカウントID>:role/<IAMロール名>
```


#### 接続元の AWS アカウントの AWS CloudShell の場合

```sh:.aws/config
[profile <任意の文字列>]
credential_source=EcsContainer
role_arn=arn:aws:iam::<接続先AWSアカウントID>:role/<IAMロール名>
```

### 実行
```aws ssm start-seession``` コマンドを実行することでセッションマネージャーにクロスアカウントアクセスで接続できます。

```sh
aws ssm start-session --target <対象の接続先Amazon EC2のインスタンスID> \
--profile <.aws/config で指定した profile の任意の文字列>


Starting session with SessionId: botocore-session-**********-*****************
sh-4.2$ 
```
　
　
 
　
　
記載されている会社名、製品名、サービス名、ロゴ等は各社の商標または登録商標です。