パラメータストアに複数行の文字列を保存する方法とその適用例 #AWS

AWS Systems Managerのパラメータストアはその名に反し、単純な文字列パラメータだけでなく、複数行にわたる文字列を保存することも可能です。しかも何の工夫も要りません。
2018.04.25
('19/02追記) SecureString を指定した場合の挙動についてフォローアップ記事を書きました。本記事とあわせてこちらもご一読ください。

概要

AWS Systems Manager のパラメータストア、皆さん使ってますか?

世代管理から KMS での暗号化機能も備え、APIキーなどのちょっとした文字列を保存するにはとても手軽で手堅いサービスです。

ただこの「パラメータ」ストアという名前のため、上で例に出した APIキー等のような数十文字程度の文字列、しかも 1行に収まるようなものしか保存できないと誤解しているひとも多そうに思います。

そんなことはありません、実は普通に複数行入力できますし日本語(UTF-8)も問題なしです。タイプは文字列のままで構いません。

試しに multi-line_parameter という名前でパラメータを作成してみたのが下記の画面です。

入力した文字列をマネジメントコンソールであとから確認しようとすると、1行で表示されてしまうのですが、

編集画面に移行したり、AWSCLI などで取得すると、ちゃんと改行コードも保存されているのが分かります。

$ aws ssm get-parameter --name multi-line_parameter
{
    "Parameter": {
        "Name": "multi-line_parameter",
        "Type": "String",
        "Value": "AWS Systems Managerのパラメータストアはその\n名に反し、単純な文字列パラメータだけでなく、\n複数行にわたる文字列を保存することも可能です。\nしかも何の工夫も要りません。",
        "Version": 1
    }
}

ちなみに AWSCLI でパラメータの値だけを取り出したい場合は、--query--outputを指定しましょう。

$ aws ssm get-parameter --name multi-line_parameter --query Parameter.Value --output text
AWS Systems Managerのパラメータストアはその
名に反し、単純な文字列パラメータだけでなく、
複数行にわたる文字列を保存することも可能です。
しかも何の工夫も要りません。

こちらのドキュメント によると最大 4096 文字 まで保存できるそうですから、ちょっとした設定ファイルや SSH 秘密鍵などを持たせるのも可能ですね。

応用

具体的に、どんなときに使えるか考えてみました。

その 1 : SSH秘密鍵を保存する

とある EC2 インスタンスに SSH ログインするための秘密鍵が、下記の名前でパラメータストアに保存されているとします。

  • /ssh/id_rsa/<ホスト名>

するとこんな感じで、パラメータストアから鍵をダウンロード → その鍵を使って SSH ログイン、ということが可能になります。

{
    USER=<ユーザ名>
    HOST=<ホスト名>
    
    # 一時的なキーファイル置き場を作成
    TMPDIR=~/.ssh/tmp/
    mkdir -m 0700 -p ${TMPDIR}

    # テンポラリファイルを作成して鍵をそこに書き込み、SSHコマンドで指定
    KEY=$(mktemp ${TMPDIR}/tmp.XXXXXXXXXX) && \
    chmod 0600 ${KEY} && \
    aws ssm get-parameter --name "/ssh/id_rsa/${HOST}" --query Parameter.Value --output text > ${KEY} && \
    ssh -i ${KEY} ${USER}@${HOST}
    
    # SSHが終了したらキーを削除
    rm -vf ${KEY}
}

KMS と連動させることもできますし、踏み台インスタンスに鍵を置いたりしなくて済むので、管理上楽になるのではないでしょうか。鍵の交換をする場合も 1 箇所ですみます。

またこの方法を応用して、該当ホスト用の ssh_config ファイルもパラメータストアに置いておいても良いかもしれません。

もちろん上記のコマンドを実行するには、パラメータストアにアクセスするための権限が別途必要です。ACCESS_KEY 等のクレデンシャル情報を設定しても良いし、アクセス元も EC2 インスタンスなら IAM ロールでも良いでしょう。そこはよしなに設計して下さい。

ちなみに BASH のプロセス置換(<( コマンド ))が使えるともっとシンプルになって良かったんですが、sshコマンドは鍵ファイルを何度も open するみたいで上手くいきませんでした。ちょっと残念です。

その 2 : YAMLで記述した設定ファイルを保存する

何かしらの設定ファイルをパラメータストアに置いておいて、EC2 や Lambda から参照するという使い方をする場合だと、例えば Python なら下記のようにして設定を辞書変数に読み込むことができます。

import boto3
import yaml

ssm = boto3.client('ssm')
ssm_parameter_name = 'nanika_configuration.yml'

config = yaml.load(
    ssm.get_parameter(
        Name=ssm_parameter_name
    )['Parameter']['Value']
)

Lambda から実行する場合は下記のようになりますね。YAMLモジュールは標準では持っていないので、lambda_function.py と共に PyYAML 等を Zip で固めてアップロードしてください。

import boto3
import yaml

def lambda_handler(event, context):
    ssm = boto3.client('ssm')
    ssm_parameter_name = 'nanika_configuration.yml'

    config = yaml.load(
        ssm.get_parameter(
            Name=ssm_parameter_name
        )['Parameter']['Value']
    )

パラメータストアに格納する情報を YAML にすることで、複数のパラメータをひとつにまとめたり、コメントをつけたりすることが可能になります。一方でマネジメントコンソール上でも編集できるので、使いどころによっては便利に使えるのではないでしょうか。

なお、Lambda からパラメータストアを使う場合には下記の記事が参考になります。合わせてご参照下さい。

パラメータストアを使って安全なLambda関数を作成する

まとめ

AWS Systems Manager のパラメータストアには、改行を含む複数行の文字列を保管可能です。

IAM によってアクセスをコントロール可能な情報倉庫として使うことができるので、もしそのような要件があった場合には、選択肢の一つとして是非検討してみて下さい。