Motivation
CI において、 AWS_ACCESS_KEY_ID
といった環境変数を CI スクリプトに与えたい状況はよくあることです。
しかし、複数の環境に対応する場合に、AWS_ACCESS_KEY_ID="${DEV_AWS_ACCESS_KEY_ID}"
(DEV 環境用の変数を使う例) などと都度書くのは手間がかかります。
このような場合に、接頭辞の付いた環境変数を一括で展開する bash script を用いれば、CI スクリプトをシンプルにしつつ実現することが可能になります。
Script Usage
GitLab CI の例ですが、以下のようにして使います:
.my_ci_job: &my_ci_job # 全環境で共通の CI Job 定義
script:
- 'source ./setup-environment-variables.sh "${ENVNAME}" AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY REPOSITORY_URL'
#
# 以下、任意のスクリプトを記述する。下記は筆者の例:
#
- $(aws ecr get-login --no-include-email)
- docker build -t $REPOSITORY_URL:latest .
- docker push $REPOSITORY_URL:latest
my_ci_job_dev: # 上記の Job に ENVNAME=DEV を与えて実行
<<: *my_ci_job
variables:
ENVNAME: DEV
my_ci_job_prod: # 上記の Job に ENVNAME=PROD を与えて実行
<<: *my_ci_job
variables:
ENVNAME: PROD
上記の CI 定義に加えて、CI 環境の設定で DEV_AWS_ACCESS_KEY_ID
および PROD_AWS_ACCESS_KEY_ID
等の変数を定義します。
CI スクリプト中の ./setup-environment-variables.sh
は、${ENVNAMEの値}_AWS_ACCESS_KEY_ID
の環境変数を AWS_ACCESS_KEY_ID
変数に展開するため、CI job 定義は環境に関わらず 1 回記述するだけで良くなっています。
Script
以下が setup-environment-variables.sh
の内容です:
# Usage: source ./setup-environment-variables.sh PREFIX NAME ...
# Example: source ./setup-environment-variables.sh DEV AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
#
# Copies environment variable from [PREFIX]_[NAME] to [NAME].
# e.g. Copy DEV_AWS_ACCESS_KEY_ID variable into AWS_ACCESS_KEY_ID
# Useful for CI.
#
# Arguments:
# $1 : Prefix of variable name
# $n : Name of variables to copy
if [ -z "$1" ]; then
echo "Usage Example: source ./setup-environment-variables.sh DEV AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY" 1>&2; exit 1
fi
PREFIX="$1"
shift
for var_basename in "$@"
do
dest_name="${var_basename}"
src_name="${PREFIX}_${var_basename}"
src_value="${!src_name}"
if [ -z "${src_value}" ]; then
echo "Missing variable: ${src_name}" 1>&2; exit 1
fi
declare -x "$dest_name=${src_value}"
done
Bash 前提のスクリプトになっていますが、多くの CI ツールは bash で動作するため使えるのではないでしょうか。
Variable indirection と declare を使うことで目的を実現しています。
また指定された変数が存在しない・空である場合にエラー終了するため、CI での変数定義の不足をわかりやすく検知できるようにも実装してあります。