sopsを使ってGoogle App Engineの環境変数に安全に値を設定する方法

2 min read読了の目安(約2400字

Google App Engineにデプロイするためにはapp.yamlという設定ファイルを書く必要があります。
その中に環境変数も記載するのですが、例えばAPI Keyなどのリポジトリに直接コミットしたくない値は当然そのまま平文でベタ書きしたくありません。
僕のチームではsopsを使ってその辺りを解決しているので紹介します。

sopsとは

https://github.com/mozilla/sops
sopsはAWS KMSやGCP KMSで管理された暗号鍵を使って任意のファイルを暗号化したり復号したりできるコマンドラインのソフトウェアです。
僕のチームでは主にGCPを使っているので以下の例も基本的にはGCP KMSを使う前提で書いています。(が、AWSを使っても手順自体はほとんど変わらないと思います。)

手順

app.yamlから暗号化したい環境変数の設定ファイルを切り出す

app.yamlはincludesというディレクティブを使って他のファイルに書いた内容を取り込むことができます。
includesについては下記のように古いバージョンのドキュメントにしか記載がないのですが、GAE Standardのgo1.11〜go1.14、nodejs12でも使えることが確認できています。

https://cloud.google.com/appengine/docs/standard/python/config/appref

この 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)こちらを使ってみても良いかもしれません。