Spring Boot アプリケーションで Azure Key Vault からのシークレットをロード

このチュートリアルでは、Spring Boot アプリケーションで Key Vault を使用して、機密性の高い構成データを保護し、Key Vault から構成プロパティを取得する方法について説明します。 Key Vault は、パスワードやデータベース接続文字列などの汎用シークレットのセキュリティで保護されたストレージを提供します。

前提条件

重要

この記事の手順を完了するには、Spring Boot 2.5 以降のバージョンが必要です。

Azure Key Vault にシークレットを設定

このチュートリアルでは、Spring Boot アプリケーションで Key Vault からデータベース資格情報を読み取る方法について説明します。 Key Vault から資格情報を読み取るために、最初にデータベース資格情報を Key Vault に格納する必要があります。

H2 データベースの URL を新しいシークレットとして Key Vault に格納するには、「クイック スタート: Azure portal を使用して Azure Key Vault からシークレットを設定および取得する」を参照してください 。 このチュートリアルでは、名前 h2url と値 jdbc:h2:~/testdb;user=sa;password=password を使用してシークレットを設定します。

Note

シークレットを設定した後、「Key Vault アクセス ポリシーの割り当て」の手順に従って、アプリに Key Vault へのアクセス権を付与します。

Azure Key Vault からシークレットを読み取る

データベース資格情報が Key Vault に格納されたので、Spring Cloud Azure で取得できます。

Spring Cloud Azure Key Vault Starter モジュールをインストールするには、次の依存関係を pom.xml ファイルに追加します。

  • Spring Cloud Azure 部品表 (BOM):

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>com.azure.spring</groupId>
          <artifactId>spring-cloud-azure-dependencies</artifactId>
          <version>5.18.0</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    

    Note

    Spring Boot 2.xを使用している場合は、 spring-cloud-azure-dependencies バージョンを 4.19.0に設定してください。 この部品表(BOM)は、 pom.xml ファイルの <dependencyManagement> セクションで設定する必要があります。 これにより、すべてのSpring Cloud Azure依存関係が同じバージョンを使用していることが保証されます。 このBOMに使用されるバージョンの詳細については、「Spring Cloud Azureのどのバージョンを使うべきか」を参照してください。

  • Spring Cloud Azure Key Vault Starter アーティファクト:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-keyvault</artifactId>
    </dependency>
    

Spring Cloud Azure には、Key Vault からシークレットを読み取るための方法がいくつかあります。 次の方法を個別に使用することも、さまざまなユース ケースに合わせて組み合わせて使用することもできます。

  • Azure SDK for Key Vault を使用します。
  • Spring KeyVault PropertySource を使用します。

Azure SDK for Key Vault を使用

Azure SDK for Key Vault には、Key Vault のシークレットを管理するための SecretClient があります。

次のコード例では、Azure Key Vault から H2 データベース資格情報を取得するための SecretClient の使用方法を示します。

Key Vault から Azure SDK を使用してシークレットを読み取るために、次の手順に従ってアプリケーションを構成します。

  1. application.properties 構成ファイルで Key Vault エンドポイントを構成します。

    spring.cloud.azure.keyvault.secret.endpoint=https://<your-keyvault-name>.vault.azure.net/
    
  2. 次の例に示すように、Spring アプリケーションに SecretClient Bean を挿入し、getSecret メソッドを使用してシークレットを取得します。

    import com.azure.security.keyvault.secrets.SecretClient;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class SecretClientApplication implements CommandLineRunner {
    
        // Spring Cloud Azure will automatically inject SecretClient in your ApplicationContext.
        private final SecretClient secretClient;
    
        public SecretClientApplication(SecretClient secretClient) {
            this.secretClient = secretClient;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(SecretClientApplication.class, args);
        }
    
        @Override
        public void run(String... args) {
            System.out.println("h2url: " + secretClient.getSecret("h2url").getValue());
        }
    }
    

    ヒント

    このチュートリアルでは、構成またはコードに認証操作はありません。 ただし、Azure サービスに接続するには認証が必要です。 認証を完了するには、Azure ID を使用する必要があります。 Spring Cloud Azure では、DefaultAzureCredential を使用します。これは、コードを変更せずに資格情報を取得できるようにするために、Azure ID ライブラリで提供されます。

    DefaultAzureCredential は複数の認証方法をサポートしており、実行時に使用する方法が決定されます。 このアプローチを採用すると、環境固有のコードを実装することなく、異なる環境 (ローカルと運用環境など) で異なる認証方法をアプリに使用できます。 詳細については、DefaultAzureCredential を参照してください。

    ローカル開発環境で認証を完了するには、Azure CLI、Visual Studio Code、PowerShell、またはその他の方法を使用できます。 詳細については、「Java 開発環境での Azure 認証」を参照してください。 Azure ホスティング環境で認証を完了するには、ユーザー割り当てマネージド ID を使用することをお勧めします。 詳細については、「Azure リソースのマネージド ID とは」を参照してください。

  3. アプリケーションを起動します。 次の例のようなログが表示されます。

    h2url: jdbc:h2:~/testdb;user=sa;password=password
    

自分で SecretClient Bean をビルドできますが、プロセスは複雑です。 Spring Boot アプリケーションでは、プロパティを管理し、ビルダー パターンを学習し、Spring アプリケーション コンテキストにクライアントを登録する必要があります。 次のコード例は、SecretClient Bean をビルドする方法を示しています。

import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SecretClientConfiguration {

    @Bean
    public SecretClient createSecretClient() {
        return new SecretClientBuilder()
            .vaultUrl("https://<your-key-vault-url>.vault.azure.net/")
            .credential(new DefaultAzureCredentialBuilder().build())
            .buildClient();
    }

}

次の一覧は、このコードが柔軟でもグレースフルでもない理由の一部を示しています。

  • Key Vault エンドポイントはハード コーディングされています。
  • Spring 環境から構成を取得するために @Value を使用する場合、application.properties ファイルに IDE ヒントを含めることはできません。
  • マイクロサービス シナリオがある場合は、各プロジェクトでコードを複製する必要があり、間違いを犯しやすく、一貫性を保つのは困難です。

幸いなことに、Spring Cloud Azure では、自分で SecretClient Bean をビルドする必要はありません。 代わりに、SecretClient を直接挿入し、既に使い慣れている構成プロパティを使用して、Key Vault を構成できます。 詳細については、「構成例」を参照してください。

Spring Cloud Azure には、さまざまなシナリオに対して次のグローバル構成も用意されています。 詳細については、『Spring Cloud Azure 開発者ガイド』の「Azure サービス SDK のグローバル構成」セクションを参照してください。

  • プロキシ オプション。
  • 再試行オプション。
  • HTTP トランスポート クライアント オプション。

別の Azure クラウドに接続することもできます。 詳細については、「さまざまなAzureクラウドへの接続」を参照してください。

Spring Key Vault PropertySource を使用する

前のセクションでは、アプリケーションの起動後にシークレットを読み取るために SecretClientCommandLineRunner で使用する方法を示しました。 ただし、Spring Boot アプリケーションでは、アプリケーションを開始する前にシークレットの読み取りが必要です。 たとえば、アプリケーションを開始する前に、データソースのパスワード プロパティが必要です。 データソースのパスワードを Key Vault に格納し、Spring 自動構成を使用してデータソースを取得する場合は、前のシナリオは機能しません。

この場合、Spring Cloud Azure は、アプリケーション コンテキストを構築する前に Key Vault からシークレットをロードする Spring 環境統合を提供します。 シークレットを使用して、Spring アプリケーション コンテキストの初期化中に Bean を構築および構成できます。 この方法は、Key Vault からシークレットにアクセスするための透過的な方法であり、コードの変更は必要ありません。

次のコード例では、H2 データベース資格情報を取得して、Azure Key Vault からデータソースをビルドするための PropertySource の使用方法を示します。

Key Vault から H2 データベースの URL を取得し、Spring Data JPA を使用して H2 データベースからデータを格納するには、次の手順に従ってアプリケーションを構成します。

  1. 次の Key Vault エンドポイントとデータソース プロパティを application.properties 構成ファイルに追加します。

    logging.level.org.hibernate.SQL=DEBUG
    
    spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=https://<your-keyvault-name>.vault.azure.net/
    spring.datasource.url=${h2url}
    
    spring.jpa.hibernate.ddl-auto=create-drop
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    

    ヒント

    Spring Cloud Azure プロパティの構成の例については、『Spring Cloud Azure 開発者ガイド』の「構成の例」セクションを参照してください。

    ヒント

    この例は、H2 データベースを使用する単純なデータベース シナリオです。 運用環境で Azure Database for MySQL または Azure Database for PostgreSQL を使用し、データベースの URL、ユーザー名、パスワードを Azure Key Vault に格納することをお勧めします。 パスワードを回避する場合は、パスワードレス接続をお勧めします。 詳細については、「Azure サービスのパスワードレス接続」を参照してください。

  2. 新しい Todo Java クラスを作成します。 このクラスは、JPA によって自動的に作成される、todo テーブルにマップされたドメイン モデルです。 次のコードは、getters メソッドと setters メソッドを無視します。

    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    @Entity
    public class Todo {
    
        public Todo() {
        }
    
        public Todo(String description, String details, boolean done) {
            this.description = description;
            this.details = details;
            this.done = done;
        }
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String description;
    
        private String details;
    
        private boolean done;
    
    }
    
  3. スタートアップ クラス ファイルを編集して、次の内容を表示します。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.context.event.ApplicationReadyEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.annotation.Bean;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    import java.util.stream.Stream;
    
    @SpringBootApplication
    public class KeyvaultApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(KeyvaultApplication.class, args);
        }
    
        @Bean
        ApplicationListener<ApplicationReadyEvent> basicsApplicationListener(TodoRepository repository) {
            return event->repository
                .saveAll(Stream.of("A", "B", "C").map(name->new Todo("configuration", "congratulations, you have set up "
                    + "correctly!", true)).toList())
                .forEach(System.out::println);
        }
    
    }
    
    interface TodoRepository extends JpaRepository<Todo, Long> {
    
    }
    
  4. アプリケーションを起動します。 アプリケーションは、Key Vault から H2 データベースの URL を取得し、H2 データベースに接続して、データベースにデータを格納します。 次の例のようなログが表示されます。

    2023-01-13 15:51:35.498 DEBUG 5616 --- [main] org.hibernate.SQL: insert into todo (description, details, done, id) values (?, ?, ?, ?)
    com.contoso.keyvault.Todo@1f
    

Azure Spring Apps にデプロイする

Spring Boot アプリケーションがローカルで実行されたので、運用環境に移行します。 Azure Spring Apps では、コードを変更せずに、Spring Boot アプリケーションを Azure に簡単にデプロイできます。 Spring アプリケーションのインフラストラクチャはこのサービスによって管理されるため、開発者はコードに専念できます。 Azure Spring Apps では、包括的な監視と診断、構成管理、サービス検出、CI/CD 統合、ブルー/グリーン デプロイなどを使用して、ライフサイクルを管理できます。 Azure Spring Apps にアプリケーションをデプロイするには、「初めてのアプリケーションを Azure Spring Apps にデプロイする」を参照してください。

次のステップ