マネージド ID を使用して Azure Functions から Azure SQL Database へ接続する

# はじめに
マネージド ID を使用して Azure Functions から Azure SQL Database へ接続を試みましたが、少し難しかったので手順をまとめてみます。
既に丁寧に解説されているブログ等もありますが、一度やってみるまでは理解が追いつかないところがあったのでより細かな手順にまとめました。

以下のような連携を行います(マイクロソフトの公式絵に注釈を加えました)
![68747470733a2f2f646f63732e6d6963726f736f66742e636f6d2f6a612d6a702f617a7572652f6163746976652d6469726563746f72792f6d616e616765642d6964656e7469746965732d617a7572652d7265736f75726365732f6d656469612f686f772d6d616e616765642d6964656e7469746965 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/98750c75-0d98-acbb-eac5-e7a704fc4299.png)

([公式絵のURL](https://docs.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/how-managed-identities-work-vm#how-it-works ))

"Azure リソースのマネージド ID の理解" と "マネージド ID を使用して Azure Functions から Azure SQL Database へ接続する" の2部構成です。

# Azure リソースのマネージド ID の理解
## Azure リソースのマネージド ID の ユースケース

Functions や app service から Azure ストレージ、 Azure SQL server へ資格情報の管理無しでアクセスする際に利用

- ![](https://docs.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/media/overview/when-use-managed-identities.png)
     - 画像の引用元 https://docs.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/overview#how-can-i-use-managed-identities-for-azure-resources


## マネージド ID、 サービスプリンシパル、 アプリケーション、クライアント などの整理

- アプリケーション == クライアント
    - Azure AD == サーバー なので、identity を提供する アプリケーションがクライアント という関係になる

- > 内部的には、マネージド ID は特別な種類のサービス プリンシパル  
    - https://docs.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/how-managed-identities-work-vm#how-it-works  

- システム割り当てマネージド ID で発行される オブジェクト ID = (サービス)プリンシパル ID  
- 今のところ サービスプリンシパル　は アプリケーション用の identity と理解している
- > アプリケーションとサービス プリンシパルは 1 対 1 で対応している
    - https://qiita.com/watahani/items/1f3f533097b7a15d6698#%E3%81%BE%E3%81%A8%E3%82%81--rbac-  
- > サービス プリンシパルとアプリケーションはアプリケーション ID で紐づいている
    - https://qiita.com/watahani/items/1f3f533097b7a15d6698#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9-%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B7%E3%83%91%E3%83%AB%E3%81%A8%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E9%96%A2%E4%BF%82  
- マネージド ID の確認方法
    - Azure portal で Azure Active Directory のリソースを選択
    - メニューから "エンタープライズ アプリケーション" を選択
    - "すべてのアプリケーション" からアプリケーションの種類 == マネージド ID で絞り込む
- マネージド サービス ID と Azure 仮想マシン (VM) が連携する様子
    - ![](https://docs.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/media/how-managed-identities-work-vm/data-flow.png)
        - 引用元 https://docs.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/how-managed-identities-work-vm#how-it-works 


## 参考資料

https://qiita.com/Shinya-Yamaguchi/items/edd75f7ee47471a98670

https://qiita.com/watahani/items/1f3f533097b7a15d6698

# マネージド ID を使用して Azure Functions から Azure SQL Database へ接続する

- 任意の関数アプリを deploy する
    - server less プラン で問題無し
    - 今回は "functions-sql-managedid" という名前で作成
- Functions に システム割り当てマネージド ID を割り当てる
    - ![スクリーンショット 2022-02-01 21.52.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/6b413fc8-64c7-7e17-76d4-75843eeaacaf.png)
- オブジェクト (プリンシパル) ID をメモしておく
    - ![スクリーンショット 2022-02-02 21.59.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/3e66aca0-bb75-b5c3-4d32-075095aa5023.png)
- Azure Active Directory へ行き "マネージド ID の確認方法" で記載した方法でマネージド IDとアプリケーションIDの紐付きを確認しておく
- SQL server を作成する
    - 以下のような感じで設定
    - ![スクリーンショット 2022-02-01 22.31.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/069c44b6-b8b5-f058-b72d-c0170cccf900.png)
- SQL Server の Azure Active Directory 管理者が自身のユーザアカウントであることを確認する
    - ![スクリーンショット 2022-02-01 22.47.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/3c4ef83b-2438-fc45-8bea-8fe8979326ed.png)
- Functions の マネージド ID に SQL Server への適切なロールを割り当てる
    - ![スクリーンショット 2022-02-01 23.36.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/5cd8a5ce-8d3e-2467-2089-1b5a5ceb426c.png)
- SQL データベースのこちら↓から Azure Data Studio へアクセス
    - ![スクリーンショット 2022-02-01 22.54.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/eae2de53-08f1-82c2-f83f-9a682eb87ead.png)
    - Azure Data Studio は Azure AD での認証をサポートしている
    - 自身の Azure ユーザアカウントで接続する
    - 接続できたら
        - `select * FROM sys.databases;` を実行して、ポータルから作成したDBが存在することを確認する
- ユーザーを追加する
    - `CREATE USER "functions-sql-managedid" FROM EXTERNAL PROVIDER;`
        - "functions-sql-managedid" は アプリケーション名 (functions のマネージドID)と一致するはず
    - `EXEC sp_addrolemember 'db_datareader', "functions-sql-managedid";`
    - `EXEC sp_addrolemember 'db_datawriter', "functions-sql-managedid";`
    - 以下クエリで追加されたことを確認する
        - `SELECT * FROM sys.database_principals where name = 'functions-sql-managedid'`
- テーブルを作成してみる
    - `CREATE TABLE "functions-sql-managedid.test"(id NCHAR(5) PRIMARY KEY, name NVARCHAR(256))`
    -  `select * FROM "functions-sql-managedid.test";` を実行してみる。
- DB に接続するための準備ができたのでコードを実行してみる
    - [こちら](https://www.ether-zone.com/function-pytho-managed-id-sqldb/)の Python コードで接続を試してみてそのまま動かすことができました
    - 上記コードは "マネージド サービス ID と Azure 仮想マシン (VM) が連携する様子" の 5 - 7 に相当します。
    - ![68747470733a2f2f646f63732e6d6963726f736f66742e636f6d2f6a612d6a702f617a7572652f6163746976652d6469726563746f72792f6d616e616765642d6964656e7469746965732d617a7572652d7265736f75726365732f6d656469612f686f772d6d616e616765642d6964656e7469746965732d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/9735a0e1-8c23-ed1f-b5d5-7d3e4e5aa45e.png)



## 参考

https://docs.microsoft.com/ja-jp/azure/azure-sql/database/authentication-aad-configure?tabs=azure-powershell

https://docs.microsoft.com/ja-jp/azure/search/search-howto-managed-identities-sql

https://docs.microsoft.com/ja-jp/azure/azure-sql/database/authentication-aad-configure?tabs=azure-powershell#provision-azure-ad-admin-sql-database

https://docs.microsoft.com/ja-jp/azure/app-service/overview-managed-identity?context=%2Fazure%2Factive-directory%2Fmanaged-identities-azure-resources%2Fcontext%2Fmsi-context&tabs=dotnet#obtain-tokens-for-azure-resources

https://docs.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15

https://docs.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-configure?tabs=azure-powershell#create-and-populate-an-azure-ad-instance

https://igeorgiev.eu/azure/how-to-connect-sql-database-app-service-managed-identity-python-pyodbc/

https://www.ether-zone.com/function-pytho-managed-id-sqldb/

以上です。