sopsを使ってGoogle App Engineの環境変数に安全に値を設定する方法
Google App Engineにデプロイするためにはapp.yamlという設定ファイルを書く必要があります。
その中に環境変数も記載するのですが、例えばAPI Keyなどのリポジトリに直接コミットしたくない値は当然そのまま平文でベタ書きしたくありません。
僕のチームではsopsを使ってその辺りを解決しているので紹介します。
sopsとは
僕のチームでは主にGCPを使っているので以下の例も基本的にはGCP KMSを使う前提で書いています。(が、AWSを使っても手順自体はほとんど変わらないと思います。)
手順
app.yamlから暗号化したい環境変数の設定ファイルを切り出す
app.yamlはincludes
というディレクティブを使って他のファイルに書いた内容を取り込むことができます。
includes
については下記のように古いバージョンのドキュメントにしか記載がないのですが、GAE Standardのgo1.11〜go1.14、nodejs12でも使えることが確認できています。
この includes
を使って以下のように設定します。
app.yaml (秘匿しなくていい値はベタ書き)
runtime: go114
env_variables:
DB_HOST: /cloudsql/PROJECT_ID:asia-northeast1:INSATNCE_NAME
DB_NAME: dbname
includes:
- secret.yaml
secret.yaml (秘匿したい値はこちら)
env_variables:
DB_USER: root
DB_PASSWORD: password
secret.yamlをsopsで暗号化する
そしてsopsでsecret.yamlを暗号化してしまえばOKです。
sopsの設定方法と使い方については以下のREADMEに詳しく載っているのでそれを参照してください。
2.2 Encrypting using GCP KMS
暗号化時にいちいちコマンドラインオプションとしてKMS ResourceIDを指定するのは面倒なので .sops.yaml
を作ってコミットしてしまうのをお勧めします。
.sops.yaml
creation_rules:
- gcp_kms: projects/my-project/locations/global/keyRings/sops/cryptoKeys/sops-key # KMS ResourceID を記載
設定できたら以下のようにして暗号化して保存。(当然元のsecret.yamlは削除するなり .gitignore に入れるなり忘れずに)
$ sops -e secret.yaml > secret.enc.yaml
これで出来上がったsecret.enc.yamlはGCP KMSで生成した暗号鍵で暗号化されています。
つまり中身を見るにはその暗号鍵を使って復号できる権限が付与されたアカウントやサービスアカウントが必要になるため、リポジトリにコミットしてしまっても大丈夫である、という認識です。
GitHub Actionsでデプロイする
GitHub Actionsのyamlから必要そうなところだけ抜粋すると以下のようになります。
普通にsopsのバイナリをダウンロードしてきてgcloud app deploy前に復号しているだけです。シンプルですね。
GOOGLE_APPLICATION_CREDENTIALS
で指定しているサービスアカウントにも忘れずに該当の暗号鍵を使った復号権限を付与してあげてください。
- name: Install sops
run: |
wget https://github.com/mozilla/sops/releases/download/v3.6.1/sops_3.6.1_amd64.deb
sudo dpkg -i sops_3.6.1_amd64.deb
- uses: google-github-actions/setup-gcloud@master
with:
version: "321.0.0"
export_default_credentials: true
service_account_key: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS}}
- name: Deploy
run: |
sops -d secret.enc.yaml > secret.yaml
gcloud app deploy
今調べてみたらsopsをインストールしてくれるActionがあるようなので(https://github.com/mdgreenwald/mozilla-sops-action)こちらを使ってみても良いかもしれません。
Discussion