env-injector作るときに考えてたこと

medium.com

env-injectorが「問題がある」って言われてもうた。ツライ……

というわけで言い訳エントリです。見苦しいですね。


env-injectorの作成時、空の環境変数を作らずに「DescribeParameterでパラメータ一覧ぶっこ抜いてprefixにマッチするものをinjectする」っていうのも考えたんですけど、以下のような理由からやめました。

1. DescribeParameterはIAMのポリシーで必要となる一部のパラメータだけに制限することができない。

開発環境から本番環境のパラメータ一覧が見えたり、別アプリケーションのパラメータ一覧が見えたからって「だから何?」ってハナシもありますが、 なんとなく嬉しくないかなぁ……と。

2. 意図しない環境変数をinjectしないか?

ssm側のパラメータ一覧を全部読み込むことになるので、ちょっとした確認での実行時に意図しない環境変数まで読み込んでしまうコトを懸念しました。

自分で空の環境変数用意するんなら、必要なものだけinjectするだろうし、意図せずinjectするコトはないだろうと思ってみたり。

3. dockerのentrypoint用を最初から想定

パラメータの一覧の「正」とするモノはアプリケーション側にあった方がいい(パラメータストアを見ないと一覧がワカラナイとかツライ)し、 空の環境変数用意するのは、DockerfileのENVで指定すればそんなに手間じゃない、と考えました。

また環境変数のキーが隠蔽できない件も、DockerfileのENVで記述するような時点で隠蔽するものではないだろうと。


最終的には「id:kakku22兄さんからの宿題で、数ヶ月放置したあげくの回答用のPoCだから何でもいっか」っていう雑な決断ですけどね。。。

ざっくり見たカンジ、スクリプトに組み込むんならexecするenv-injectorより、ssm2envの方が便利だと思います。

そんなこんなでパラメータストア周りのツールでイロイロ選択肢が増えればいいんじゃないかなぁ、と個人的には思います。


(追記: 2017-08-04)

なんか元記事の中の方に気を使わせてしまったみたいでスミマセン。

もともとがやっつけで作ったもなので対応できないユースケースがあるのは当然なので、「イケてない」と思われても仕方ないんですけどね。(;・∀・)

んで、実はこっそりDescribeParametersでパラメータぶっこ抜いて環境変数を設定するモードも用意してみました。

# 以下の値がパラメータストアに保存されてるという前提で
#   - prod.wap.DB_USER=admin
#   - prod.wap.DB_PASSWORD=password
#   - prod.wap.DB_PARAM=param
# こんな環境変数を設定しておく
$ export ENV_INJECTOR_PREFIX=prod.wap
$ export DB_USER=user
$ export DB_PASSWORD=

# mode=empty_only: 空の環境変数(DB_PASSWORD)だけ上書き。デフォルト
$ ENV_INJECTOR_MODE=empty_only env-injector printenv | grep DB_
DB_USER=user
DB_PASSWORD=password

# 当然無指定でも同じ挙動
$ env-injector printenv | grep DB_
DB_USER=user
DB_PASSWORD=password

# mode=aggressive: パラメータストアの変数を全部設定するけど、もともと設定されている環境変数(DB_USER)はそのまま
$ ENV_INJECTOR_MODE=aggressive env-injector printenv | grep DB_
DB_USER=user
DB_PASSWORD=password
DB_PARAM=param

# mode=all: パラメータストアの変数を全部設定する。もともと設定されている環境変数があっても上書き
$ ENV_INJECTOR_MODE=all env-injector printenv | grep DB_
DB_USER=admin
DB_PASSWORD=password
DB_PARAM=param

aggressiveallはGetParametersに加えてDescribeParametersのパーミッションも必要になります。
逆にデフォルトのままだと特に追加のパーミッションもいらない、ということで。

……こ、これで、どや?