Spring Boot を使用して Secret Manager から認証情報/Secret を取得する

1. 概要

パスワードや API キーなどのシークレットは機密情報であり、安全で暗号化されたストレージに保管し、アクセス制御と監査が可能な安全な場所に保管する必要があります。一部のシステムでは、こうしたシークレットの保存に Vault を使用しています。Google Cloud では、マネージド サービスである Secret Manager を使用してシークレットを安全に保存し、IAM を使用して個々のシークレットへのアクセスを制御できます。

Spring Boot では、Spring Cloud GCP を使用してこれらの Secret を他の Spring プロパティとして参照することで簡単にアクセスできます。

この Codelab では、Secret Manager にシークレットを保存してから、シンプルな Spring Boot マイクロサービスを構築してシークレットを取得します。

学習内容

  • Spring Boot Java アプリケーションを作成して Secret Manager を構成する方法。

必要なもの

  • Google Cloud プロジェクト
  • ChromeFirefox などのブラウザ
  • Linux の標準的なテキスト エディタ(vim、emacs、nano など)を使い慣れていること

このチュートリアルをどのように使用しますか?

通読するのみ 通読し、演習を行う

HTML/CSS ウェブアプリの作成経験をどのように評価されますか。

初心者 中級者 上級者

Google Cloud サービスの使用経験はどの程度ありますか?

<ph type="x-smartling-placeholder"></ph> 初心者 中級 上達 をご覧ください。

2. 設定と要件

セルフペース型の環境設定

  1. Cloud Console にログインし、新しいプロジェクトを作成するか、既存のプロジェクトを再利用します(Gmail アカウントまたは G Suite アカウントをお持ちでない場合は、アカウントを作成する必要があります)。

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

  1. 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Google Cloud Shell

Google Cloud サービスはノートパソコンからリモートで操作できますが、この Codelab では Cloud 上で動作するコマンドライン環境である Google Cloud Shell を使用します。

Cloud Shell をアクティブにする

  1. Cloud Console で、[Cloud Shell をアクティブにする] H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ をクリックします。

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

Cloud Shell を起動したことがない場合、その内容を説明する中間画面が(スクロールしなければ見えない範囲に)が表示されます。その場合は、[続行] をクリックします(以後表示されなくなります)。このワンタイム スクリーンは次のようになります。

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

この仮想マシンには、必要な開発ツールがすべて準備されています。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワーク パフォーマンスが充実しており認証もスムーズです。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。

Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。

  1. Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list

コマンド出力

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

上記のようになっていない場合は、次のコマンドで設定できます。

gcloud config set project <PROJECT_ID>

コマンド出力

Updated property [core/project].

3. シークレットを構成する

Secret Manager を使用するには、まず API を有効にします。

$ gcloud services enable secretmanager.googleapis.com

次に、値が Hellogreeting という名前の Secret を作成します。

$ echo -n "Hello" | \
 gcloud secrets create greeting \
 --data-file=-

このコマンドでは、STDIN を使用して値をコマンドラインに指定します。ただし、シークレットの値を単純にファイルに入れて、--data-file 引数にファイル名を指定することもできます。

gcloud CLI を使用して、すべてのシークレットを一覧表示できます。

$ gcloud secrets list

4. 新しい Spring Boot REST サービスを作成する

Cloud Shell が起動したら、コマンドラインを使用して、Spring Initializr で新しい Spring Boot アプリケーションを生成できます。

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d dependencies=web,cloud-gcp \
  -d bootVersion=3.0.6 \
  -d type=maven-project \
  -d baseDir=hello-secret-manager | tar -xzvf - \
  && cd hello-secret-manager

pom.xml で、Spring Cloud GCP スターターの依存関係を追加します。

pom.xml

<project>
  ...

  <dependencies>
    ...
    <!-- Add Secret Manager Starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
    </dependency>
  </dependencies>

  ...
</project>

src/main/resources/application.properties ファイルに次の構成を追加して、Spring Boot Config Data API を有効にします。

spring.config.import=sm://

これにより、Spring プロパティ ソースが構成され、sm:// の接頭辞を持つプロパティ値(sm://greeting など)を使用してシークレットを参照できるようになります。

プロパティの形式の詳細については、Spring Cloud GCP Secret Manager のドキュメントをご覧ください。application.properties 要件は Spring Cloud GCP 4.x で新しく導入されました。詳しくは、移行ガイドをご覧ください。

新しいクラスファイルを追加して、新しい REST コントローラを作成します。

src/main/java/com/example/demo/HelloSecretController.java

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloSecretController {
  String greeting = "Hi";

  @GetMapping("/")
  public String hello() {
    return greeting + " World!";
  }
}

Spring Boot プラグインを使用して、Spring Boot アプリケーションを通常どおり起動できます。

JAVA_HOME が正しい JDK バージョンに設定されていることを確認します。

$ export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/

このラボのテストをスキップしてアプリケーションを起動してみましょう。

$ ./mvnw -DskipTests spring-boot:run

アプリケーションが起動したら、Cloud Shell ツールバーの「ウェブでプレビュー」アイコン e18df08334f0d809.png をクリックし、[ポート 8080 でプレビュー] を選択します。

しばらくすると、結果が表示されます。

1e9a7884ff113c14.png

5. Secret を取得する

@Value アノテーションを使用すると、sm:// 接頭辞を使用してシークレット プロパティを参照できます。

HelloSecretController クラスで、アノテーションを使用して greeting 値を挿入します。

src/main/java/com/example/demo/HelloSecretController.java

import org.springframework.beans.factory.annotation.Value;

...

@RestController
public class HelloSecretController {
  @Value("${sm://greeting}")
  String greeting;

  ...
}

Spring Boot プラグインを使用して、Spring Boot アプリケーションを通常どおり起動できます。このラボのテストはスキップします。

$ ./mvnw -DskipTests spring-boot:run

アプリケーションが開始したら、Cloud Shell ツールバーのウェブでプレビュー アイコン e18df08334f0d809.png をクリックし、[プレビューのポート: 8080] を選択します。

しばらくすると、結果が表示されます。

「Hello World!」と表示されている実行中のアプリケーションのスクリーンショット

値を application.properties のプロパティにマッピングすることもできます。

src/main/resources/application.properties

greeting=${sm://greeting}

HelloSecretController では、Secret Manager 名ではなく、このより一般的なプロパティ名を参照できます。

src/main/java/com/example/demo/HelloSecretController.java

@RestController
public class HelloSecretController {
  @Value("${greeting}")
  String greeting;
  ...
}

Spring Boot プラグインを使用して、Spring Boot アプリケーションを通常どおり起動できます。このラボのテストはスキップします。

$ ./mvnw -DskipTests spring-boot:run

アプリケーションが起動したら、Cloud Shell ツールバーの「ウェブでプレビュー」アイコン ウェブ プレビュー アイコン をクリックし、[ポート 8080 でプレビュー] を選択します。

シークレット値の更新

sm://greeting の短い構文を使用すると、最新バージョンのシークレットが自動的に使用されます。シークレットの新しいバージョンを作成することで、コードを変更することなくアプリケーションを更新できます。

新しいバージョンを追加して、シークレットの値を更新します。

$ echo -n "Greetings" |
 gcloud secrets versions add greeting \
 --data-file=-

アプリケーションを再起動し、シークレットの新しいバージョンが返されることを確認します。

「Greeings World!」が表示されている実行中のアプリケーションのスクリーンショット

このコンセプトを拡大

この手法は、さまざまな Spring Boot アプリケーション プロファイルを使用する場合に特に役立ちます。たとえば、greeting-devgreeting-staginggreeting-prod などのシークレットを作成できます。各プロファイルで適切な応答メッセージにマッピングします。

greeting-prod Secret を作成します。

$ echo -n "Hola" | \
 gcloud secrets create greeting-prod \
 --data-file=- --replication-policy=automatic

application-prod.properties ファイルを作成します。

src/main/resources/application-prod.properties

greeting=${sm://greeting-prod}

Spring Boot プラグインは通常、ただし prod プロファイルを使用して Spring Boot アプリケーションを起動できます。このラボのテストはスキップします。

$ ./mvnw -DskipTests spring-boot:run -Dspring-boot.run.profiles=prod

アプリケーションが開始したら、Cloud Shell ツールバーのウェブでプレビュー アイコン ウェブ プレビュー アイコン をクリックし、[プレビューのポート: 8080] を選択します。

しばらくすると、結果が表示されます。

「Hola World!」が表示されている、実行中のアプリケーションのスクリーンショット

6. まとめ

このラボでは、sm:// という接頭辞が付いた Spring のプロパティ名を使用し、applications.properties ファイルと @Value アノテーションから値を挿入することで、Secret Manager に保存されているシークレットを使用して構成できるサービスを作成しました。

7. 完了

Java で Secret Manager API を使用する方法を学習しました。

詳細

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。