マネージド ID を使用して Azure Database for PostgreSQL ‐ フレキシブル サーバーに接続する

適用対象: Azure Database for PostgreSQL - フレキシブル サーバー

システム割り当てとユーザー割り当ての両方のマネージド ID を使用して、Azure Database for PostgreSQL フレキシブル サーバーに対する認証を行うことができます。 この記事では、Azure 仮想マシン (VM) のシステム割り当てマネージド ID を使って、Azure Database for PostgreSQL フレキシブル サーバーにアクセスする方法について説明します。 マネージド ID は Azure によって自動的に管理され、資格情報をコードに挿入しなくても、Microsoft Entra 認証をサポートするサービスで認証を行うことができるようにするものです。

学習内容は次のとおりです。

  • VM に Azure Database for PostgreSQL フレキシブル サーバー インスタンスへのアクセスを許可します。
  • VM のシステム割り当て ID を表すユーザーをデータベースに作成します。
  • VM ID を使用してアクセス トークンを取得し、それを使用して Azure Database for PostgreSQL フレキシブル サーバー インスタンスにクエリを実行します。
  • C# サンプル アプリケーションにトークン取得を実装します。

前提条件

  • Azure リソースのマネージド ID 機能に慣れていない場合は、「Azure リソースのマネージド ID とは」を参照してください。 Azure アカウントをお持ちでない場合は、無料のアカウントにサインアップしてから先に進んでください。
  • 必要なリソース作成およびロール管理を実行するため、お使いのアカウントには、適切な範囲 (サブスクリプションまたはリソース グループ) を対象とする "所有者" アクセス許可が必要となります。 ロールの割り当てでお困りの場合、「Azure portal を使用して Azure ロールを割り当てる」を参照してください。
  • マネージド ID を使用したデータベースへのアクセスに使用する Azure VM (Ubuntu Linux を実行しているものなど) が必要です
  • Microsoft Entra 認証が構成されている Azure Database for PostgreSQL フレキシブル サーバー インスタンスが必要
  • C# の例を理解するため、まず C# を使用した接続方法に関するガイドをご覧ください

VM 用のシステム割り当てマネージド ID を作成する

az vm identity assignidentity assign コマンドを使用して、既存の VM に対するシステム割り当て ID を有効にします。

az vm identity assign -g myResourceGroup -n myVm

システム割り当てマネージド ID のアプリケーション ID を取得します。これは、次のいくつかの手順で必要です。

# Get the client ID (application ID) of the system-assigned managed identity

az ad sp list --display-name vm-name --query [*].appId --out tsv

マネージド ID 用の Azure Database for PostgreSQL フレキシブル サーバー ユーザーを作成する

次に、Microsoft Entra 管理者ユーザーとして Azure Database for PostgreSQL フレキシブル サーバー データベースに接続し、次の SQL ステートメントを実行します。<identity_name> をシステム割り当てマネージド ID を作成したリソースの名前に置き換えます:

pgaadauth_create_principal は Postgres データベースで実行する必要があることに注意してください。

select * from pgaadauth_create_principal('<identity_name>', false, false);

成功は次のようになります:

    pgaadauth_create_principal
-----------------------------------
 Created role for "<identity_name>"
(1 row)

Microsoft Entra ID 対応データベース ロールの管理の詳細については、「Microsoft Entra ID 対応 Azure Database for PostgreSQL ‐ フレキシブル サーバー ロールを管理する方法」を参照してください

ID 名をロール名、Microsoft Entra トークンをパスワードとして認証すると、マネージド ID にアクセスできるようになりました。

Note

マネージド ID が無効な場合は、ERROR: Could not validate AAD user <ObjectId> because its name is not found in the tenant. [...] エラーが返されます。

Note

"No function matches..." のようなエラーが表示された場合は、作成した別のデータベースではなく、postgres データベースに接続していることを確認してください。

Azure Instance Metadata Service からアクセス トークンを取得する

この段階で、アプリケーションは Azure Instance Metadata Service からアクセス トークンを取得して、データベースでの認証に使用できるようになっています。

このトークンの取得は、http://169.254.169.254/metadata/identity/oauth2/token に対して HTTP 要求を実行し、次のパラメーターを渡すことによって行われます。

  • api-version = 2018-02-01
  • resource = https://ossrdbms-aad.database.windows.net
  • client_id = CLIENT_ID (前の手順で取得したもの)

access_token フィールドを含む JSON の結果が返されます。この長いテキスト値が、データベースに接続するときにパスワードとして使用する必要があるマネージド ID アクセス トークンです。

テストのために、シェルで次のコマンドを実行できます。

注意

curljqpsql クライアントがインストールされている必要があることにご注意ください。

# Retrieve the access token

export PGPASSWORD=`curl -s 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fossrdbms-aad.database.windows.net&client_id=CLIENT_ID' -H Metadata:true | jq -r .access_token`

# Connect to the database

psql -h SERVER --user USER DBNAME

これで、前に構成したデータベースに接続できました。

C# でマネージド ID を使用して接続する

このセクションでは、VM のユーザー割り当てマネージド ID を使用してアクセス トークンを取得し、それを使用して Azure Database for PostgreSQL フレキシブル サーバーを呼び出す方法を説明します。 Azure Database for PostgreSQL フレキシブル サーバーでは Microsoft Entra 認証がネイティブにサポートされるため、Azure リソース用マネージド ID を使って取得されたアクセス トークンを直接受け入れることができます。 Azure Database for PostgreSQL フレキシブル サーバー への接続を作成する場合は、[パスワード] フィールドにアクセス トークンを渡します。

アクセス トークンを使用して Azure Database for PostgreSQL フレキシブル サーバーへの接続を開く .NET のコード例を次に示します。 システム割り当てマネージド ID を使って、Microsoft Entra ID からアクセス トークンを取得するには、このコードを VM 上で実行する必要があります。 HOST、USER (<identity_name> で)、および DATABASE の値を置き換えます。

using System;
using System.Net;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Npgsql;
using Azure.Identity;

namespace Driver
{
    class Script
    {
        // Obtain connection string information from the portal for use in the following variables
        private static string Host = "HOST";
        private static string User = "USER";
        private static string Database = "DATABASE";

        static async Task Main(string[] args)
        {
            //
            // Get an access token for PostgreSQL.
            //
            Console.Out.WriteLine("Getting access token from Azure AD...");

            // Azure AD resource ID for Azure Database for PostgreSQL Flexible Server is https://ossrdbms-aad.database.windows.net/
            string accessToken = null;

            try
            {
                // Call managed identities for Azure resources endpoint.
                var sqlServerTokenProvider = new DefaultAzureCredential();
                accessToken = (await sqlServerTokenProvider.GetTokenAsync(
                    new Azure.Core.TokenRequestContext(scopes: new string[] { "https://ossrdbms-aad.database.windows.net/.default" }) { })).Token;

            }
            catch (Exception e)
            {
                Console.Out.WriteLine("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
                System.Environment.Exit(1);
            }

            //
            // Open a connection to the PostgreSQL server using the access token.
            //
            string connString =
                String.Format(
                    "Server={0}; User Id={1}; Database={2}; Port={3}; Password={4}; SSLMode=Prefer",
                    Host,
                    User,
                    Database,
                    5432,
                    accessToken);

            using (var conn = new NpgsqlConnection(connString))
            {
                Console.Out.WriteLine("Opening connection using access token...");
                conn.Open();

                using (var command = new NpgsqlCommand("SELECT version()", conn))
                {

                    var reader = command.ExecuteReader();
                    while (reader.Read())
                    {
                        Console.WriteLine("\nConnected!\n\nPostgres version: {0}", reader.GetString(0));
                    }
                }
            }
        }
    }
}

このコマンドを実行すると、次のような出力が表示されます。

Getting access token from Azure AD...
Opening connection using access token...

Connected!

Postgres version: PostgreSQL 11.11, compiled by Visual C++ build 1800, 64-bit

次のステップ