🏃‍♂️

Cloud Run と Secret Manager をいい感じに連携する

2021/07/07に公開

概要

前回の記事でCloud BuildとSecret Managerをいい感じに連携する方法について書いたのですが、まだプレビューですが、最近Secret ManagerがCloud Runにも対応したので、これまでのやり方とこれからのやり方について説明したいと思います。
https://cloud.google.com/secret-manager/docs/release-notes?hl=ja#May_12_2021

やりたいこと

Cloud Run実行時にDB_PASSWORDなどの秘匿情報を環境変数に展開したい

これまでのやり方

これまではCloud RunからSecret Managerの情報を取得して環境変数に展開する方法はサポートされていませんでした。
なので、Secret Managerからデータを取得して環境変数に展開するようなShellを作成して、Entrypointでコンテナ起動時に実行するというやり方を取っていました。

以下の様な感じです

# get-secrets.sh
#!/bin/bash

secret_prefix="secret:"

for i in $(printenv | grep ${secret_prefix})
do
  key=$(echo ${i} | cut -d'=' -f 1)
  val=$(echo ${i} | cut -d'=' -f 2-)
  if [[ ${val} == ${secret_prefix}* ]]
  then
    val=$(echo ${val} | sed -e "s/${secret_prefix}//g")
    projectId=$(echo ${val} | cut -d'/' -f 1)
    secret=$(echo ${val} | cut -d'/' -f 2)

    if [[ -n ${projectId} ]]
    then
      project="--project=${projectId}"
    fi

    secretName=$(echo ${secret} | cut -d'#' -f 1)
    version="latest"
    if [[ ${val} == *#* ]]
    then
      version=$(echo ${val} | cut -d'#' -f 2)
    fi
    plain="$(gcloud beta secrets versions access --secret=${secretName} ${version} ${project})"
    #For multiline management
    export $key="$(echo $plain | sed -e 's/\n//g')"
  fi
done

exec "$@"

get-secrets.sh では、 環境変数を読み取って、対応する秘匿情報をSecert Managerから取得して環境変数に展開しています。
例えば、 DB_PASSWORD: secret:/STG_DB_PASSWORD という環境変数が合った場合、Secret Managerの STG_DB_PASSWORD というSecretの値を取得して、DB_PASSWORDという名前の環境変数として展開してくれます。

# Dockerfile
FROM node:14-slim

#####################################
#                                   #
# Packageのインストールとかビルドとか... #
#                                   #
####################################

RUN apt-get update && apt-get install curl gnupg -y
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \
  && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg  add - \
  && apt-get update -y && apt-get install google-cloud-sdk -y

RUN chmod +x /app/get-secrets.sh

ENTRYPOINT [ "/app/get-secrets.sh" ]

CMD ["/usr/local/bin/node", "build/app.js"]

Dockerfileでは、get-secrets.sh をEntrypointに指定しています。
その前のブロックでは、 google-cloud-sdk をインストールしています。
get-secrets.sh では、gcloudコマンドを実行してSecret Managerから値を取得するため、gcloudコマンドをDocker Imageに含める必要があります。

個人的にはアプリケーションを動かす以外のミドルウェアはDocker Imageに含めたくなかったので、あまりやりたくはありませんでしたが、他に方法がなかったので妥協していました。

これからのやり方

Secret ManagerがCloud Runに対応してくれたので、EntrypointでSecret Managerからデータを取得するShellが不要になりました。
Cloud Runのコンソールか、gcloudコマンドでSecretの設定することができます。
コンソールでは、リビジョンの作成画面の「変数とシークレット」タブからSecretsを設定することができます。

1つ目のSelectBoxでSecretを選択して、2個目のSelectBoxで参照の方法を選択します。
参照の方法は環境変数に展開するか、ファイルとしてマウントするかの2種類を選択できます。
最後に、環境変数に展開することを選択した場合は環境変数名を入力し、マウントすることを選んだ場合は、ファイルパスを入力します。

とても便利な機能なのですが、2021年7月現在ではプレビューとなっていますので、取り扱いには注意が必要です。

詳しくはこちらのドキュメントに書いてあります。
https://cloud.google.com/run/docs/configuring/secrets?hl=ja

まとめ

Secret ManagerがCloud Runに対応してくれたおかげで、Cloud Runで秘匿情報を扱うのがかなり楽になりました。
まだプレビュー版なので本番で利用するには不安がありますが、個人的にはかなり嬉しいアップデートでした。GAが待ち遠しいです。

Discussion