つばろぐ

主に C#, .NET, Azure の備忘録です。たまに日記。

Tye で設定された環境変数にアクセスする仕組みを調べた

これまでの Tye の記事で使っているサンプルアプリケーションは、バックエンドアプリケーションにホストした API をフロントエンドアプリケーションから呼び出して、データを画面に表示するというものです。

f:id:tech-tsubaki:20200927223507p:plain

このとき、それぞれのアプリケーションでは2つの環境変数にアクセスしています。
今回の記事では Tye の仕組みの中で、どのように環境変数を取得しているかを調べてみました。

backend > Startup.cs

バックエンドアプリケーションでは Redis の接続文字列をスタートアップで取得しています。

services.AddStackExchangeRedisCache(o =>
{
    o.Configuration = Configuration.GetConnectionString("redis");
});

ただし IConfiguration.GetConnectionStringASP.NET Core 標準の機能で取得しているため、一般的なアクセスの仕方になっています。
では "redis" という接続文字列はどこで設定されているでしょうか。
通常は appsettings.json や OS の環境変数に書きますが、 Tye の場合は tye.yaml で定義することができます。

- name: redis
  image: redis
  bindings:
  - port: 6379
    connectionString: "${host}:${port}"

ローカルで Tye を動かす tye run コマンドのときに、実際にどのような環境変数が設定されているかを調べるために、環境変数を取得するエンドポイントを Startup.cs に書いてみました。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 中略
    app.Map("/configs", HandleMapConfigs);
    // 中略
}

private void HandleMapConfigs(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        var connectionStrings = Configuration.AsEnumerable();
        var content = new System.Text.StringBuilder();
        foreach (var config in connectionStrings)
        {
            content.AppendLine($"{config.Key} -> {config.Value}");
        }
        await context.Response.WriteAsync(content.ToString());
    });
}

動かしてみると接続文字列としての環境変数がセットされていました。なので IConfiguration.GetConnectionString("redis") で取得できるということですね。

ConnectionStrings -> 
ConnectionStrings:REDIS -> localhost:6379

frontend > Startup.cs

次はフロントエンドアプリケーションです。ここではスタートアップでバックエンドアプリケーションの URI を取得しています。
このとき使用しているメソッドは Microsoft.Extensions.Configuration.TyeConfigurationExtensions.GetServiceUri という Tye 独自の拡張メソッドです。

services.AddHttpClient<WeatherClient>(client =>
{
    client.BaseAddress = Configuration.GetServiceUri("backend");
});

https://github.com/dotnet/tye/blob/083a97f353069ef8a091651d4c9ca445c994b2e5/src/Microsoft.Tye.Extensions.Configuration/TyeConfigurationExtensions.cs#L11

このメソッドでは IConfiguration から以下のキーの値を取得しています。

  • service:backend:host
  • service:backend:port
  • service:backend:protocol

前述の環境変数を取得する処理をバックエンドアプリケーションにも追加したうえで、値一覧を見てみると service:backend から始まる設定がありました。

SERVICE:BACKEND -> 
SERVICE:BACKEND:PROTOCOL -> http
SERVICE:BACKEND:PORT -> 64699
SERVICE:BACKEND:HTTPS -> 
SERVICE:BACKEND:HTTPS:PROTOCOL -> https
SERVICE:BACKEND:HTTPS:PORT -> 64700
SERVICE:BACKEND:HTTPS:HOST -> localhost
SERVICE:BACKEND:HOST -> localhost

そのため Configuration.GetServiceUri("backend")http://localhost:64699/ という URI を取得することができ、この URI がバックエンドアプリケーションの URI ということになります。