API_KEYなどの秘匿情報をどのように保持して、どのように呼び出しているのか、みなさん当たり前のようにやっているはずなのに、ずっと謎だったので調べながらわかったことを残しておきます。
##対象者
- (私のような)webpack初心者
- サーバレス(JAM Stack等)でなんか作りたい人
- GitLab Runner (CI/CD pipeline)が使える
##やりたかったこと
サーバレスな環境でAPIを叩きたかった(が、API_KEYをベタ書きしたら死ぬ)
##わかったこと
ローカルと本番では以下の二つの方法を分ける必要がある
- ローカルの.envファイルからビルドする方法
- GitLabに環境変数を登録しCI/CDでビルドする方法
##1.ローカルでの使用
ローカルでは.envファイルを用意してそれをビルド時に読むようにすればOKです。
具体的に見ていきます。
私の場合、dotenv-webpackというプラグインを利用しました。使い方は簡単で、
npm install dotenv-webpack --save-dev
でインストール後、
.envファイルに入れたい環境変数を書きます。
// .env
DB_HOST=127.0.0.1
DB_PASS=foobar
API_KEY=mysecretkey
あとはwebpack.configにプラグインを追加すれば
const Dotenv = require('dotenv-webpack');
module.exports = {
...
plugins: [
new Dotenv()
]
...
};
好きなjsファイルで呼ぶことができます。
console.log(process.env.DB_HOST);
// '127.0.0.1'
バンドル後は以下のようになります。
console.log('127.0.0.1');
(dotenv-webpackのreadmeそのままですね。。)
ローカルでビルドする分にはこれで十分です。
しかし.envファイルを公開されているGitLab(hub)にあげるのはセキュリティー的に危険ですので、.envはgitignoreします。
でも、書いたコードは公開したい、、!!!
そこでGitLabのCI機能を用いて、以下のように対処しました。
##2.本番環境での使用
まず、環境変数の置き場所ですがGitLabでは、Project > (サイドバーの) Settings > CI/CD > Variables
で登録することができます。
(参考:https://qiita.com/ynott/items/4c5085b4cd6221bb71c5#%E5%A4%89%E6%95%B0-1)
ここで登録した環境変数を使うには.gitlab-ci.ymlファイルをいじる必要があります。
参考のため、環境変数と関係のない部分も載せます。
image: python:3.6.5
variables:
S3_BUCKET: <バケット名>
AWS_DEFAULT_REGION: ap-northeast-1
stages:
- build
- deploy
bulid:
image: node:10.13.0
stage: build
only:
- master
before_script:
- npm install
# .envを作成し、環境変数を追加する
- echo "BASE_URL = $BASE_URL" > .env
- echo "API_KEY = $API_KEY" >> .env
cache:
paths:
- node_modules/
script:
- echo start to build
- npm run build
artifacts:
paths:
- dist/
expire_in: 30 minutes
after_script:
# .envを削除する
- rm .env
deploy:
image: python:latest
stage: deploy
only:
- master
before_script:
- pip install awscli
script:
- echo start to deploy
- aws s3 sync ./dist s3://<ドメイン>.com --cache-control noCache --content-language ja-JP
beforeScript内で.envファイルを作成し、そこに先ほど登録した環境変数を入れています。
yamlファイル内で$ENV_NAMEとすれば環境変数を使うことができます。(なお、>が上書きで、>>が追記です。)
そして、作られた.envファイルを使ってビルドします。
ビルドされたartifacts(dist)をS3にデプロイしているのですが、このままだと.envをそのままあげるのと同じなので
デプロイ前に.envファイルを削除しています。
これでデプロイされたファイルには秘匿情報が含まれないようにできました。
手探りでやったので他にもっといい方法、もしくは、ここ違くね?等あれば教えてください、、!!