はじめに
前回の記事 では Cloud Build を使って Springbootアプリ を GAE にデプロイしてみました。
今回は前回と同様 Cloud Build を使いつつ、DBパスワード や APIキー など
リポジトリにそのまま保存したくない機密データを 暗号化して保護してみます。
今回やることの概要
事前に機密データを Cloud KMS の対称鍵 で 暗号化しておき、Cloud Build の
途中のステップでそれを 復号して アプリに渡します。
事前準備
下記の手順で対称鍵を作成し、Cloud Build から使用できるようにしておきます。
- Google Cloud KMS API を有効にする
- キーリングを作成する
- 対称鍵を作成する
- Cloud Build のサービスアカウントに対称鍵へのアクセス権を付与する
Google Cloud KMS API を有効にする
次の通りWEBコンソールでポチポチするか、またはCUIで行います。
または
> gcloud services enable cloudkms.googleapis.com
Operation "operations/acf.0186f101-c31d-4fb1-bd09-387cc9a35c0e" finished successfully.
キーリングを作成する
公式のここ によると、鍵はいずれかのキーリングに含める必要があります。
ここを参考に キーリングを作成します。
> gcloud kms keyrings create wai-no-keyring --location=global
対称鍵を作成する
対称鍵も作成します。
> gcloud kms keys create wai-no-key --location=global --keyring=wai-no-keyring --purpose=encryption
以上で鍵の作成まで出来ました。
結果をWEBコンソールで確認すると次のような感じ。
Cloud Build サービス アカウントに対称鍵へのアクセス権を付与する
公式のここ を参考に Cloud Build から作成した鍵にアクセスできるようにします。
> gcloud kms keys add-iam-policy-binding wai-no-key --location=global --keyring=wai-no-keyring --member=serviceAccount:70479915102@cloudbuild.gserviceaccount.com --role=roles/cloudkms.cryptoKeyDecrypter
Updated IAM policy for key [wai-no-key].
bindings:
- members:
- serviceAccount:70479915102@cloudbuild.gserviceaccount.com
role: roles/cloudkms.cryptoKeyDecrypter
etag: BwWQCawaIKM=
version: 1
以上で事前準備は完了です。
暗号化する
今回はSpring前提ということで、保護したい情報を application-prod.yml に記載して、
このファイルを暗号化することにします。
次のような手順になります。
- application-prod.yml を作成する
- application-prod.yml を暗号化して application-prod.yml.enc を作成する
- 本番環境では application-prod.yml を参照するよう指定する
application-prod.yml を作成する
application.yml をコピって適当に作ります。
certain-setting-value: わいの恥ずかしいひみつ
application-prod.yml を暗号化して application-prod.yml.enc を作成する
公式のここ を参考に暗号化します。
> gcloud kms encrypt --location global --keyring wai-no-keyring --key wai-no-key --plaintext-file application-prod.yml --ciphertext-file application-prod.yml.enc
上記コマンドで生成された .encファイル のみを src\main\resources に追加します。
本番で application-prod.yml を参照するよう指定する
app.yaml に次のように 環境変数を追加 して、本番では application-prod.yml を参照するようにします。
env_variables:
SPRING_PROFILES_ACTIVE: 'prod'
以上で暗号化は完了です。
復号する処理を仕込む
公式の こことか こことか を参考に前回作った cloudbuild.yaml に復号処理を追記します。
次の通り。
steps:
#--------------------------------------------------------------------------------
# (1/3) build と deploy に使うカスタムイメージを作成 (Including gcloud, jdk, maven)
#--------------------------------------------------------------------------------
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '--tag=gcr.io/$PROJECT_ID/gcloud-maven', '-f', 'Dockerfile.gcloud-maven', '.']
#--------------------------------------------------------------------------------
# (2/3) application-prod.yml を復号
#--------------------------------------------------------------------------------
- name: 'gcr.io/$PROJECT_ID/gcloud-maven'
args:
- gcloud
- kms
- decrypt
- --ciphertext-file=src/main/resources/application-prod.yml.enc
- --plaintext-file=src/main/resources/application-prod.yml
- --location=global
- --keyring=wai-no-keyring
- --key=wai-no-key
#--------------------------------------------------------------------------------
# (3/3) カスタムイメージで build と deploy を行う
#--------------------------------------------------------------------------------
- name: 'gcr.io/$PROJECT_ID/gcloud-maven'
args: ['mvn', 'clean', 'package', 'appengine:deploy']
images: ['gcr.io/$PROJECT_ID/gcloud-maven']
timeout: 1200s
以上でデプロイ出来るようになりました。
デプロイして動作確認する
前回の記事と同じコマンドでデプロイします。
次の通り。
> gcloud builds submit
Creating temporary tarball archive of 10 file(s) totalling 4.5 KiB before compression.
Some files were not included in the source upload.
(中略)
Step #2: [INFO] GCLOUD: .................................done.
Step #2: [INFO] GCLOUD: Deployed service [default] to [https://springboot-webapp-project.appspot.com]
Step #2: [INFO] GCLOUD:
Step #2: [INFO] GCLOUD: You can stream logs from the command line by running:
Step #2: [INFO] GCLOUD: $ gcloud app logs tail -s default
Step #2: [INFO] GCLOUD:
Step #2: [INFO] GCLOUD: To view your application in the web browser run:
Step #2: [INFO] GCLOUD: $ gcloud app browse --project=springboot-webapp-project
Step #2: [INFO] ------------------------------------------------------------------------
Step #2: [INFO] BUILD SUCCESS
Step #2: [INFO] ------------------------------------------------------------------------
Step #2: [INFO] Total time: 06:16 min
Step #2: [INFO] Finished at: 2019-08-14T03:01:35+00:00
Step #2: [INFO] Final Memory: 34M/101M
Step #2: [INFO] ------------------------------------------------------------------------
Finished Step #2
(後略)
以上で確認できました。
さいごに
今回は暗号化した機密ファイルを リポジトリで管理する イメージで作りましたが、
代わりに Cloud Storage に保存しておいて取得する作りにもできそうな気がします。
以上です。