■ はじめに
https://dk521123.hatenablog.com/entry/2020/04/16/113816
で触れた以下の開発フェーズで設定を切り替えることを考えてみた 1)開発環境(dev) 2)検証環境 (stage) 3)本番環境 (prod) 例えば、各フェーズによってS3バケット名を変更したいなどが でてくると思うので、その実装案についてのメモ。
■ 実装案
【案1】すべての値を環境変数でもらう 【案2】設定値を各フェーズに紐づけて命名する 【案3】各設定値が保存されているJSONから取得する 【案4】外部シェルから取得する などなど、、、
【案1】すべての値を環境変数でもらう
CodeBuldには、環境変数があるので、 ごり押しのパワープレー。
【案2】設定値を各フェーズに紐づけて命名する
フェーズが識別できる環境変数(ここでは、環境タイプ:${ENV}とする)をもらい、 設定値(リソース名)は、その環境タイプに紐づけて設計(命名)する (例えば、"s3-buket-prod-001"など)
サンプル
環境変数の環境タイプ ENV(dev/stage/prod)を受け取り、 S3バケット名をそれぞれ「s3-bucket-【環境タイプ】001~3」のように 設計した場合の例を記す。
buildspec.yml
version: 0.2 env: variables: # 本来であれば、外部から取得する ENV: "dev" phases: install: runtime-versions: python: 3.8 commands: pre_build: commands: - export S3_BUCKET_1=”s3-bucket-${ENV}001” - export S3_BUCKET_2=”s3-bucket-${ENV}002” - export S3_BUCKET_3=”s3-bucket-${ENV}003”
【案3】各設定値が保存されているJSONから取得する
設定が保存されているJSONからjqコマンドを使って取得する 以下の関連記事を参照
jq コマンド ~ コマンドで JSON を扱う ~
https://dk521123.hatenablog.com/entry/2020/02/01/000000
サンプル
環境変数の環境タイプ ENV(dev/stage/prod)を受け取り、 S3バケット名は、JSONファイル(s3-setting.json)に格納した場合
buildspec.yml
version: 0.2 env: variables: # 本来であれば、外部から取得する ENV: "dev" phases: install: runtime-versions: python: 3.8 commands: pre_build: commands: - export S3_BUCKET_1=”cat s3-setting.json | jq -r '.${ENV}.s3_bucket1'” - export S3_BUCKET_2=”cat s3-setting.json | jq -r '.${ENV}.s3_bucket2'” - export S3_BUCKET_3=”cat s3-setting.json | jq -r '.${ENV}.s3_bucket3'”
s3-setting.json
{ "prod": { "s3_bucket1":"s3-bucket-pd001", "s3_bucket2":"s3-bucket-pd002", "s3_bucket3":"s3-bucket-pd003" }, "stage": { "s3_bucket1":"s3-bucket-sg001", "s3_bucket2":"s3-bucket-sg002", "s3_bucket3":"s3-bucket-pd003" }, "dev": { "s3_bucket1":"s3-bucket-dv001", "s3_bucket2":"s3-bucket-dv002", "s3_bucket3":"s3-bucket-dv003" } }
【案4】外部シェルから取得する
サンプル(1)外部シェル + caseで取得する
外部シェルとその中でcaseを使って、対応する
条件分岐 ~ if / case ~
https://dk521123.hatenablog.com/entry/2015/05/01/000043
buildspec.yml
version: 0.2 env: variables: # 本来であれば、外部から取得する ENV: "dev" phases: install: runtime-versions: python: 3.8 commands: pre_build: commands: - export S3_BUCKET_1=`get-value-by-env-n-key.sh ${ENV} 's3_bucket1'` - export S3_BUCKET_2=`get-value-by-env-n-key.sh ${ENV} 's3_bucket2'` - export S3_BUCKET_3=`get-value-by-env-n-key.sh ${ENV} 's3_bucket3'`
get-value-by-env-n-key.sh
#!/bin/bash ENV="$1" KEY="$2" case "${ENV}" in prod) case "${KEY}" in s3_bucket1) RETURN_VALUE="s3-buket-pd001" ;; s3_bucket2) RETURN_VALUE="s3-buket-pd002" ;; s3_bucket3) RETURN_VALUE="s3-buket-pd003" ;; esac ;; stage) case "${KEY}" in s3_bucket1) RETURN_VALUE="s3-buket-sg001" ;; s3_bucket2) RETURN_VALUE="s3-buket-sg002" ;; s3_bucket3) RETURN_VALUE="s3-buket-sg003" ;; esac ;; dev | *) case "${KEY}" in s3_bucket1) RETURN_VALUE="s3-buket-${ENV}001" ;; s3_bucket2) RETURN_VALUE="s3-buket-${ENV}002" ;; s3_bucket3) RETURN_VALUE="s3-buket-${ENV}003" ;; esac ;; esac echo "${RETURN_VALUE}"
サンプル(2)外部シェル + 連結配列で取得する
case文をネストする形が可読性を下げるので、 連結配列を使ってみる 連想配列(Associative arrays)については、以下の関連記事を参照。
https://dk521123.hatenablog.com/entry/2015/02/20/001600
buildspec.yml
サンプル・その1と同じなので省略
get-value-by-env-n-key.sh
#!/bin/bash ENV="$1" KEY="$2" declare -A SETTINGS; SETTINGS=( # for prod ["prod@s3_bucket1"]="s3-buket-pd001" ["prod@s3_bucket2"]="s3-buket-pd002" ["prod@s3_bucket3"]="s3-buket-pd003" # for stage ["stage@s3_bucket1"]="s3-buket-sg001" ["stage@s3_bucket2"]="s3-buket-sg002" ["stage@s3_bucket3"]="s3-buket-sg003" # for dev ["dev@s3_bucket1"]="s3-buket-dv001" ["dev@s3_bucket2"]="s3-buket-dv002" ["dev@s3_bucket3"]="s3-buket-dv003" # others ["s3_bucket1"]="s3-buket-${ENV}001" ["s3_bucket2"]="s3-buket-${ENV}002" ["s3_bucket3"]="s3-buket-${ENV}003" ) case "${ENV}" in prod | stage | dev) RETURN_VALUE=${SETTINGS[${ENV}@${KEY}]} ;; *) RETURN_VALUE=${SETTINGS[${KEY}]} ;; esac echo "${RETURN_VALUE}"
■ 総括:個人的な意見
以下に色々書いたが、状況によって使い分ければいい、、、
【案1】について
規模がデカければ、物凄い環境変数の量になる。 ただし、小規模なら、楽だし、分かりやすい。
【案2】について
設計(各の命名規則含む)をしっかりしてたら、一番いいが 仕様変更などのイレギュラーなことに対して、柔軟性に欠ける。
【案3】について
JSONにより、データと処理を分離できるので、可読性はあがるかも。 ただ、全環境JSONに記載しないとならないので、若干、柔軟性に欠けるかも。
【案4】について
一番、柔軟に対処できるかも。
関連記事
CodeBuild ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/01/21/221122
各開発フェーズにおける環境の呼び方
https://dk521123.hatenablog.com/entry/2020/04/16/113816
jq コマンド ~ コマンドで JSON を扱う ~
https://dk521123.hatenablog.com/entry/2020/02/01/000000
条件分岐 ~ if / case ~
https://dk521123.hatenablog.com/entry/2015/05/01/000043
シェル について ~基本構文編~
https://dk521123.hatenablog.com/entry/2015/02/20/001600