Azure Blob Storageの権限設定

Azure CLIを使ってBlob Storageにアクセスする際に、閲覧・書き込みでユーザ権限を分ける方法です。

# ストレージアカウント作成

* ストレージアカウントを作って、[test]というコンテナーを作成しておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/98827fad-2db6-f277-3a46-f1b9a48130b5.png)

* testコンテナーに、適当にファイルをアップロードしておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/c9575d09-ad9f-24ec-704c-e8e03f23d0d4.png)

# Blob閲覧者用サービスプリンシパル作成

* Azure ADを選択して、[アプリの登録]→[新しいアプリケーションの登録]の順に選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/126ba278-e805-e01f-bde1-c32e3830fb89.png)

* アプリ名を入れます。サインオンURLは使わないので適当で。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/b672f54f-13e8-3e04-9a24-22c73383a23b.png)

* 作成されたらアプリケーションIDをメモっておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/69098d6c-c485-e105-8452-7dd7b2661adf.png)

* [設定]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/a283c3c9-b0ea-eee2-d6b7-500403c45964.png)

* [キー]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/9af49d9b-a56f-e605-6064-335ee1bcbfed.png)

* 説明に[token]を、有効期限は要件次第ですが今回は[期限なし]を選択して、[保存]を押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/2e1eaebb-eb3a-2be0-0d1d-63ff765b854f.png)

* キーが表示されるのでメモしておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/9be1db95-5311-e4e1-cf76-71249689ee1a.png)

# Blob書き込み権限用サービスプリンシパル作成

閲覧者用の手順でサービスプリンシパルを作成します。今回は[BlobWriter]という名前で作りました。

# ストレージアカウントに権限を付与する

* ストレージアカウントを選択して、[アクセス制御(IAM)]→[ロールの割り当て]→[追加]の順に選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/11c5cfb6-33df-4078-d48c-6c96d52450ba.png)

* [ロールの割り当ての追加]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/f4613328-1ed5-0064-7f52-35d87ff534f7.png)

* 役割に[ストレージBLOBデータ閲覧者]を選び、先程作った[BlobReader]サービスプリンシパルに権限を与えます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/2c448276-a769-acef-5b55-5be1620dbe70.png)

* 今度は役割に[ストレージBLOBデータ共同作成者]を選び、先ほど作った[BlobWriter]サービスプリンシパルに権限を与えます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/797ae720-adc1-61cb-3c13-8b55b48a50ea.png)

# Azure Active DirectoryテナントID取得

* AADの[プロパティ]を選択し、[ディレクトリID]をメモしておきます。 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/1ac8731e-e01d-9c97-4746-235b645f849b.png)

# Azure CLIで閲覧者権限のテスト

* 閲覧者用サービスプリンシパルでログインします。操作端末は、Azure CLIが入っていれば、LinuxでもWindowsでもなんでもよいです。

```
$ az login --service-principal -u [事前にメモしたアプリケーションID] -p [事前にメモしたtoken] --tenant [事前にメモしたテナントID]
```

* コンテナー内のBlobリストが表示できるか試します。JSONでBlob情報が取得できればOKです。

```
$ az storage blob list --container-name [コンテナー名] --account-name [ストレージアカウント名] --auth-mode login
```

* コンテナーにBlobをアップロードできるか試します。エラーになればOKです。

```
$ az storage blob upload --container-name [コンテナー名] --name bbb.txt --file bbb.txt --account-name [ストレージアカウント名] --auth-mode login
```

# Azure CLIで書き込み権限のテスト

* 次に書き込み権限のテストをします。一度ログアウトします。

```
$ az logout
```

* 書き込み権限用サービスプリンシパルでログインします。

```
$ az login --service-principal -u [事前にメモしたアプリケーションID] -p [事前にメモしたtoken] --tenant [事前にメモしたテナントID]
```

* コンテナー内のBlobリストが表示できるか試します。JSONでBlob情報が取得できればOKです。

```
$ az storage blob list --container-name [コンテナー名] --account-name [ストレージアカウント名] --auth-mode login
```

* コンテナーにBlobをアップロードできるか試します。アップロードできればOKです。

```
$ az storage blob upload --container-name [コンテナー名] --name bbb.txt --file bbb.txt --account-name [ストレージアカウント名] --auth-mode login
```

# コンテナー単位で権限制御する

* コンテナーを選択してIAM設定すれば可能です。コンテナー単位にする場合、ストレージアカウントのIAM権限は設定しなくても大丈夫です。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/ea081e91-387f-1bca-b4c1-f2afa169ab13.png)

# No subscriptions were foundエラーが出る

* ```az login```コマンド実行時に以下のエラーが出ることがあります。

```
No subscriptions were found for '[アプリケーションID]'. If this is expected, use '--allow-no-subscriptions' to have tenant level accesses
```

* これは対象のサービスプリンシパルに何も権限が当たっていないときに出力されるので、何かIAM権限を与えたあとに```az login```してみてください。