マネージド ID を使用して Azure Database for PostgreSQL に接続する

適用対象: Azure Database for PostgreSQL - 単一サーバー

重要

Azure Database for PostgreSQL - シングル サーバーは廃止パスにあります。 Azure Database for PostgreSQL - フレキシブル サーバーにアップグレードすることを強くお勧めします。 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 アカウントをお持ちでない場合は、無料のアカウントにサインアップしてから先に進んでください。
  • 必要なリソース作成およびロール管理を実行するため、お使いのアカウントには、適切な範囲 (サブスクリプションまたはリソース グループ) を対象とする "所有者" アクセス許可が必要となります。 ロールの割り当てに関するサポートが必要な場合は、Azure ロールの割り当てによる 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 の PostgreSQL ユーザーを作成する

次に、Microsoft Entra 管理者ユーザーとして PostgreSQL データベースに接続し、次の SQL ステートメントを実行します。CLIENT_ID は、システム割り当てマネージド ID 用に取得したクライアント ID に置き換えます。

SET aad_validate_oids_in_tenant = off;
CREATE ROLE myuser WITH LOGIN PASSWORD 'CLIENT_ID' IN ROLE azure_ad_user;

これで、マネージド ID に、ユーザー名 myuser (任意の名前に置き換えてください) を使用して認証するときのアクセス権が付与されました。

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@SERVER DBNAME

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

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

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

アクセス トークンを使用して PostgreSQL への接続を開く .NET のコード例を次に示します。 システム割り当てマネージド ID を使って、Microsoft Entra ID からアクセス トークンを取得するには、このコードを VM 上で実行する必要があります。 HOST、USER、DATABASE、CLIENT_ID の値は置き換えてご使用ください。

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 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

次のステップ