AWSパラメータストアでSSH鍵管理

# はじめに
EC2インスタンス上でgithubなどのリポジトリのSSH秘密鍵を管理する際に、パラメータストアを用いて管理する方法についてまとめた内容になります。

# AWS parameter store
パラメータストア(正式にはAWS Systems Manager パラメータストア)とはAWSのサービスで、設定データや機密情報を管理できるサービスです。
パラメータストアに保存したデータはAWS CLIなどから値を参照することができます。
またAWS Key Management Service (AWS KMS)を利用してパラメータを暗号・復号化することができます。

# SSH鍵の管理
EC2インスタンス上でリポジトリのSSH秘密鍵を利用するという状況を想定します。鍵をパラメータストアに保存し利用するためにやらないといけないことは以下です。

1. SSH秘密鍵をパラメータストアに登録
1. パラメータへのアクセスを許可するIAMロールの作成(EC2へアタッチ)
1. AWS CLIによるパラメータの呼び出し・利用

以下、説明します。

### SSH秘密鍵をパラメータストアに登録
SSH鍵を作成し、秘密鍵をパラメータストアに登録します。
AWSマネジメントコンソールからSystems Managerのページに移動します。
ページ左側のウィンドウペインから`パラメータストア`(下の方)を選択し、パラメータストアのページに移動します。
ページ内の`パラメータの作成`をクリックするとパラメータ設定画面(下図)に移ります。

![スクリーンショット 2019-07-20 22.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/380830/514094a6-df6e-15cc-cbd1-d798feccbfdf.png)

画面項目内の必要項目を入力しパラメータの設定を行います。
今回は以下のように設定しました。

- 名前: ssh-key
- 利用枠: 標準
- タイプ: 安全な文字列
- KMSの主要なソース: 現在のアカウント
- 値: (SSH秘密鍵)

パラメータを暗号化する設定を行っています。
利用枠が詳細の場合はアドバンストパラメータを利用することになります。
アドバンストパラメータでは利用料金が発生しますが、パラメータのサイズや数の上限が大きく、有効期限など詳細な設定が可能です。
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/parameter-store-advanced-parameters.html


### パラメータへのアクセスを許可するIAMロールの作成
EC2インスタンスにパラメータへのアクセスを許可するためにIAMロールを作成する必要があります。
IAMロール作成テンプレートは以下です。

```yaml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  ParameterName:
    Type: String
    Description: ssm parameter name

Resources:

  # SSMパラメータにアクセス許可するIAMロール
  GetParameterRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "get-parameter-role"
      Path: "/"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement: 
        - Effect: "Allow"
          Principal: 
            Service: 
            - "ec2.amazonaws.com"
          Action: 
            - "sts:AssumeRole"

  # SSMパラメータにアクセスするポリシー
  GetParameterPolicy:
    Type: "AWS::IAM::Policy"
    Properties:
      PolicyName: "get-parameter-policy"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - 
            Effect: "Allow"
            Action: "ssm:GetParameter"
            Resource: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${ParameterName}"

      Roles:
        - !Ref GetParameterRole
  
  # インスタンスプロファイル
  GetParameterProfile:
    Type: "AWS::IAM::InstanceProfile"
    Properties:
      Path: "/"
      Roles:
        - !Ref GetParameterRole
      InstanceProfileName: get-parameter-profile
```

上記テンプレートでは指定した名前(テンプレート内のParameterName)のパラメータ情報の取得を許可するロールを作成しています。
ロール作成後、インスタンスプロファイルをEC2インスタンスにアタッチします。

### AWS CLIによるパラメータの呼び出し・利用
EC2インスタンスからAWS CLIを利用して、以下のコマンドでパラメータの情報を取得できます。

```
aws ssm get-parameter --name (parameter-name) --with-decryption --output text
```

コマンドのオプションの説明は以下です。

- name: パラメータ名を指定
- with-decrypton: パラメータの復号を行う
- output: 出力形式

また `--query Parameter.Value`を加えることで、パラメータ値のみ取得することができます。


### gitコマンド実行
取得した鍵はssh-agentに鍵登録を行うことで、ファイルとして管理することなく利用できます。
以下、取得したパラメータを用いてgitコマンドを実行するシェルスクリプトの例です。

```shell
#!/bin/bash

key_name=ssh-key

git_with_ssm_key() {

  ssm_key=$1; shift

  # 鍵の取得
  key_param=$(aws ssm get-parameter \
              --with-decryption \
              --name $ssm_key \
              --output text \
              --query Parameter.Value)
  
  if [ $? -eq 0 ]; then
    
    # 鍵の登録
    ssh-add - <<< "${key_param}"

　　 # gitコマンド実行
    git "$@"
  else
    echo >&2 "ERROR: Failed to get ssm parameter : $ssm_key"
    exit 1
  fi
}

git_with_ssm_key $key_name clone git@github.com:your_account/repo_name
```

上のスクリプトではパラメータストアから取得した鍵をssh-agentに登録し、git cloneコマンドを実行しています。


# 注意点など
今回説明した方法だとパラメータストアへパラメータを設定するところとEC2インスタンス上でパラメータを取得するところでは通信がインターネットを経由します。よりセキュリティに配慮する場合、上記の手順を以下のように変更することで、インターネットを経由せずにパラメータの設定・利用を行うことができます。

1. Systems Manager 用 VPC エンドポイントを作成する。
2. EC2インスタンス上でキーペアを作成する。
3. EC2インスタンス上から`aws ssm put-parameter`コマンドでパラメータストアに秘密鍵を登録する(ロールの作成も必要)。

1によりVPC内のEC2インスタンスとSystems Managerの通信がAWSネットワーク内に限定されるので、以降の3およびパラメータ取得はインターネットを経由せずに実行することができます。

# 参考
- VPCエンドポイントの設定
　https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-create-vpc.html

- アドバンストパラメータ
 https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/parameter-store-advanced-parameters.html

- シェルスクリプトの作成においては以下のサイトを参考にしました。
  https://alestic.com/2018/12/aws-ssm-parameter-store-git-key/