kakakakakku blog

Weekly Tech Blog: Keep on Learning!

任意のパラメータを格納できる EC2 Systems Manager「パラメータストア」を試したら便利だった

re:Invent 2016 で発表されたけど,オンプレ関連だと勝手に思い込んでいて,今まで試していなかった Amazon EC2 Systems Manager の中に「パラメータストア」というサービスがあり,試してみたらこれが非常に便利だった.簡単に言うと,任意のパラメータをパラメータストアに格納することができて,アプリケーションと環境変数を完全に切り離すことができてしまうというもの.The Twelve-Factor App を実現できるぞ!

パラメータストアとは?

  • 任意のパラメータをパラメータストアに格納することができる
  • データタイプは3種類ある
    • String
    • String List
    • Secure String (パラメータを KMS で暗号化して格納する)
  • ._ を使うと,パラメータをグルーピングできる
  • IAM Role でアクセスできるパラメータグループを制御できる

docs.aws.amazon.com

パラメータストアに格納してみた

サンプルとして,4個のパラメータをパラメータストアに格納してみた.なお,キーと値は同じにした.

  • パラメータグループとして prdstg を用意した
  • KMS の挙動を確認するため StringSecure String を用意した

f:id:kakku22:20170610180222p:plain

パラメータストアからパラメータを取得する

aws ssm get-parameters コマンドを使うと,簡単にパラメータを取得することができる.

$ aws ssm get-parameters --name 'stg.user_id'
{
    "InvalidParameters": [],
    "Parameters": [
        {
            "Type": "String",
            "Name": "stg.user_id",
            "Value": "stg.user_id"
        }
    ]
}

Secure String の場合は,デフォルトだと KMS で暗号化された値が返ってくる(今回は例として xxxxx とした).

$ aws ssm get-parameters --name 'stg.user_pass'
{
    "InvalidParameters": [],
    "Parameters": [
        {
            "Type": "SecureString",
            "Name": "stg.user_pass",
            "Value": "xxxxx"
        }
    ]
}

よって,Secure String の場合は --with-decryption オプションを付ける必要がある.ちなみに --with-decryption オプションは Secure String 以外の場合は無視されるため,String のときにも付けておけば,コマンドが統一できて良さそう.

$ aws ssm get-parameters --name 'stg.user_pass' --with-decryption
{
    "InvalidParameters": [],
    "Parameters": [
        {
            "Type": "SecureString",
            "Name": "stg.user_pass",
            "Value": "stg.user_pass"
        }
    ]
}

ちなみに aws ssm get-parameters コマンドの詳細は以下にまとまっている.

パラメータストアから取得した値を環境変数に設定する

こんな感じでスクリプトを用意すれば,簡単に The Twelve-Factor App を実現できる.便利!

$ USER_ID=$(aws ssm get-parameters --name 'stg.user_id' | jq -r '.Parameters[].Value')
$ echo ${USER_ID}
stg.user_id

$ USER_PASS=$(aws ssm get-parameters --name 'stg.user_pass' --with-decryption | jq -r '.Parameters[].Value')
$ echo ${USER_PASS}
stg.user_pass

IAM Role でアクセスできるパラメータグループを制御する

まず prd.* にアクセスできる IAM ポリシーと stg.* にアクセスできる IAM ポリシーを用意して,IAM ロールに紐付けた.

  • policy-ssm-prd
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:Describe*",
                "ssm:Get*",
                "ssm:List*"
            ],
            "Resource": [
                "arn:aws:ssm:ap-northeast-1:111111111111:parameter/prd.*"
            ]
        }
    ]
}
  • policy-ssm-stg
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:Describe*",
                "ssm:Get*",
                "ssm:List*"
            ],
            "Resource": [
                "arn:aws:ssm:ap-northeast-1:111111111111:parameter/stg.*"
            ]
        }
    ]
}

次に IAM ロールをアタッチしたインスタンスを起動して動作確認をした.以下の例は stg からパラメータストアにアクセスした状態で,prd.* グループのパラメータにはアクセスできなかった.このように設定することで,別環境の設定が誤って取得されるリスクが無くなる.

$ aws ssm get-parameters --name 'stg.user_id'
{
    "InvalidParameters": [],
    "Parameters": [
        {
            "Type": "String",
            "Name": "stg.user_id",
            "Value": "stg.user_id"
        }
    ]
}
$ aws ssm get-parameters --name 'prd.user_id'

An error occurred (AccessDeniedException) when calling the GetParameters operation: User: arn:aws:sts::111111111111:assumed-role/ec2-ssm-stg/i-22222222222222222 is not authorized to perform: ssm:GetParameters on resource: arn:aws:ssm:ap-northeast-1:111111111111:parameter/prd.user_id

簡単に図にすると,このようになる.

f:id:kakku22:20170610180308j:plain

re:Invent 2016 動画

パラメータストア以外にもいろいろ機能があるので,試してみないと!

www.youtube.com

env-injector

パラメータストアから環境変数に自動的に設定をしてくれる env-injector というツールを先輩の id:okzk が実装していた.これは便利!

$ ENV_INJECTOR_PREFIX=prd env-injector printenv | egrep 'user_id|user_pass'
user_id=prd.user_id
user_pass=prd.user_pass

$ ENV_INJECTOR_PREFIX=stg env-injector printenv | egrep 'user_id|user_pass'
user_id=stg.user_id
user_pass=stg.user_pass

env-injector の詳細は以下の記事を参照で!

okzk.hatenablog.com

まとめ

  • Amazon EC2 Systems Manager の中にはたくさんのサービスがあった
  • 「パラメータストア」は非常に便利でパラメータの格納を AWS に任せられる
  • IAM Role でアクセスできるパラメータグループを制御することもできる
  • クレデンシャル / データベース接続情報などの一般的なユースケース以外にも「パラメータストア」を活用できるアイデアがたくさんありそう