SpringBootのProfileとAzure AppConfigurationの組み合わせでハマった話

最近、Azureに楽しく翻弄されています。
そして、AppConfigurationを導入することになって、クイックスタートのソースコードは動くのに、実ソースコードの方からはなかなかアクセスできん、ぐぬぬとなってたけど、無事解決できたので、忘れないうちに残しておきます。

## 環境

- SpringBoot 2.6+
- Java 11
- Azure Configuration

## 結論

環境ごとにProfileをわけてると、ActiveProfilesで有効になったprofile名で、AppConfigurationのLabelを参照しようとするので、Labelにprofileと同じ値を設定するか、bootstrap-{profile}.yml にlabel-filterを設定して、任意の値を参照させるのが良いです。

:::note info
`application-${profile}.yml` じゃなくて、`bootstrap-${profile}.yml` です。(大事)
:::

```bootstrap-${profile}.yml
spring:
  cloud:
    azure:
      appconfiguration:
        stores:
          - connection-string: ${APP_CONFIGURATION_CONNECTION_STRING}
            selects:
              - label-filter: hogelabel  # ここをprofileか任意のラベルにする
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38628/51e71b79-9de6-bf44-831a-dad2c15dc349.png)

## 詳細

あとで見つけたんですが、ここに書いてました。
これ、チュートリアルの方にリンクを貼っておいてくれないもんだろうか。。

[Spring Cloud Azure App Configuration Client Usage](https://microsoft.github.io/spring-cloud-azure/docs/azure-app-configuration/2.5.0/reference/html/index.html#client-usage)

> By default, if no configurations are set, then the configurations starting with /application/ are loaded with a default label of (No Label) unless a Spring Profile is set in which case the default label is your Spring Profile. Because the store is empty no configurations are loaded, but the Azure App Configuration Property Source is still generated.

> A property source named /application/https://<name-of-your-store>.azconfig.io/ is created containing the properties of that store.The label used in the request is appended to the end of the name, if no label is set the character \0 is there, as an empty space.

つまり、デフォルトだと、
`/application/ + key名 + / (No Label)` で探す挙動っぽいですね。

Profileを使ってる場合は、Labelにprofileの値を指定して探すみたいです。

> The default label is `${spring.profiles.active}`. If `${spring.profiles.active}` is not set then configuration with the null label seen as (No Label) in the portal are loaded.

ログ出したらいたので、ここまで探せ出せたんですが、なかなかたどり着けなかった。。。


```
[BootstrapPropertySource {name='bootstrapProperties-/application/https://hogehoge-app-conf.azconfig.io/dev}]
```


### 『/application/』ってなんぞや

今回変えなかったんですが、key-filterっていうので別の値を探すようにできるみたいです。
『*』 って指定したら何でも探してくれるんだろうか。未検証。

> Configurations are loaded by their key and label. By default, the configurations that start with the key /application/ are loaded.

[Selecting Configurations](https://microsoft.github.io/spring-cloud-azure/docs/azure-app-configuration/2.5.0/reference/html/index.html#selecting-configurations)


### bootstrap.properties/bootstrap.yml ってなんぞや

> A Spring Cloud application operates by creating a “bootstrap” context, which is a parent context for the main application. It is responsible for loading configuration properties from the external sources and for decrypting properties in the local external configuration files. 

[1. Spring Cloud Context: Application Context Services](https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html)

外部ソースとしてConfigをロードする機構っぽい。
挙動としては、application.yml より先に読み込まれる。（まあそうか）

環境ごとにファイル接続先を変えたいとかあれば、application.yml と同様
``bootstrap-${profile}.yml`` で良い。

[1.3 Changing the Location of Bootstrap Properties](https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html#customizing-bootstrap-properties)

## 本家サンプルコード

[Configuration を使用して Java Spring アプリを作成する](https://docs.microsoft.com/ja-jp/azure/azure-app-configuration/quickstart-java-spring-app)


## 雑感

しかし、環境ごとにAppConfigurationを分けるのが良いって公式で言ってるけど、Labelにprofileを指定するのはなんとももどかしい気がしたり。
Spring Cloud Config 周りのドキュメントにもこの形式の書き方がちらほらあるので、そこから継承したやり方なんですかね？まだまだ奥が深い。

とりあえず、App Configuration に移行したら、application.ymlに書いてたあれこれがとてもスッキリしたので良かったわ


## 参考

[設定の外部化](https://spring.pleiades.io/spring-boot/docs/current/reference/html/features.html#features.external-config)