Azure Deployment Environments の基礎

## Introduction
個人的にイケてるサービスだと思い、使ってみたので紹介します。

ARM テンプレートや、[Bicep](https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/overview?tabs=bicep) を書いたけど、テンプレート化された環境を毎回利用者が「使いたい！」となった時に払い出すのが面倒ではないでしょうか。

例ですが、[**Azure Deployment Environments**](https://learn.microsoft.com/ja-jp/azure/deployment-environments/) はプラットフォームエンジニアが [IaC](https://learn.microsoft.com/ja-jp/devops/deliver/what-is-infrastructure-as-code) テンプレートを管理し、開発者がアプリのインフラが必要になった時、申請や権限の設定を毎回行うことなく、開発者が「ボタンを一押し!」で環境を Azure 上に構築できるサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/e0a5d7e4-f84d-941a-ea65-a0b7a222417c.png)

:::note info
 2024 年 6 月時点では Azure Resource Manager (ARM) テンプレート、 Bicep、[その他 IaC](https://learn.microsoft.com/en-us/azure/deployment-environments/configure-environment-definition#add-an-environment-definition) (実行コンテナを Azure Container Registry を利用して作成する必要あり)をサポートしています。
:::

また更にそこに RBAC などの権限の設定や、環境を使用しなくなった時に環境を削除をするライフサイクルの管理なども運用の面では必要になります。

そのような IaC を活用するにあたって障害となるような側面であったり、さらにリードタイムを縮めてテンプレートを展開していくことができます。


今回の記事では、Azure Deployment Environments の考え方と、Azure で利用する際のそれぞれのサービスの関係性に関して紹介します。最後に簡単なデモも載せました。どんな流れで Azure の環境が作られるのか参考にしたい方は是非視聴してみてください。

また応用編の CICD を利用した IaC のテンプレートの展開方法に関しては別記事で紹介します。

実際に Azure Deployment Environments を使って環境作成したい方は Microsoft 公式ドキュメントを参照してください。
**英語版のサイトでないと、ドキュメントの構成がおかしいので、英語版を読むことを推奨します。**

https://learn.microsoft.com/en-us/azure/deployment-environments/quickstart-create-and-configure-devcenter 

## Azure Deployment Environments とは？
Intoroduction で説明した通りですが、特に**プラットフォームエンジニアと開発者の境界**を意識して説明をすると以下の特徴があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/1d2a7adc-7f8f-9a67-8e7d-999140d208a0.png)


* 開発が事前に構成されたインフラストラクチャのテンプレートを使用して、動的にリソースグループに展開して利用ができるセルフサービス環境を用意できる
* テンプレート化された環境を使用するため、一貫したセキュリティやガバナンスを効かせたインフラストラクチャを提供することができる
* プラットフォームエンジニアの環境の払い出しや開発者のインフラ設計の負担を軽減できる

この様な役割の境界線を理解しておくことは Azure Deployment Environments を利用する上で重要なことだと感じます。そのうえで、利用シナリオをいくつか次のセクションで紹介します。

### 利用シナリオ
以下の様な利用シナリオが考えられます。

**サンドボックス環境**
* 利用者が Azure リソースを自由に作成して試せる環境を提供
* 共同作成者などの権限を払い出されるリソースグループに持たせることで自由度を与える
* 空のテンプレートを使用​

**ラボ環境**
* 開発したアプリケーションの動作検証など
* 読み取り権限のみなどの最小限の権限を与える
* アプリケーションをデプロイする為のテンプレート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/bb97e882-90d4-8f9a-9d0a-aff370eed2d0.png)

**IaC の CI/CD パイプライン**

製品ライフサイクル環境 (開発、テスト、ステージング、運用前、運用など) の作成、更新などで利用できます。

また CI/CD パイプラインを組み込むことで以下のことを可能にできます。
* 開発者やテスト担当者は、再利用可能なテンプレートを使って環境を迅速に展開する
* 最新バージョンのアプリケーションをテストできる
* 開発チームは、環境を CI/CD パイプラインに接続して、DevOps シナリオを有効にすることができる
* プラットフォームエンジニアのチームは、コストとセキュリティ アラートの追跡と、複数のプロジェクトやデベロッパー センターにわたる環境の管理を一元的に行える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/7bbf211b-02a9-4934-a4c0-0193f945d872.png)


## Azure での構成
ここからは実際に Azure Deployment Environments を使いたいというときに、必要になる知識、そしてそれぞれのコンポーネントの結びつきや、少し複雑な RBAC の設定に関して説明します。

まず Azure Deployment Environments はいくつかの登場人物がいます。以下のリストと図がその説明になります。
- **デベロッパーセンター**
     - 開発プロジェクトのコレクションを含む最上位のリソース
     - Microsoft Dev Box も同じデベロッパーセンターを使用してリソースを整理できる

- **プロジェクト**
     - 開発するプロジェクト ( e コマースアプリケーションなど)
     - デベロッパーセンターの設定が自動的に適用される環境
- **環境**
     - アプリケーションをデプロイするための事前構成された Azure 環境
- **カタログ**
    - IaC テンプレート一式を整理するリソース
    - デプロイ環境ではリポジトリの指定されたフォルダをスキャンして環境定義を検索する

- **環境の種類**
    - 開発チームがデプロイできる環境の種類
    - プロジェクト単位で環境の種類ごとに Azure リソースが作成されるターゲット サブスクリプションを構成できる

- **Git プロバイダー**
    - IaC テンプレートを管理する
    - GitHub、Azure DevOps に対応

それぞれの登場人物は以下の図の様な関係性です。
ちょっと分かりにくいと思いう方は図の下の備考を参考にしてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/97eeb1ec-506c-0cbc-f1bb-f1278876033c.png)

:::note info
簡単に何が行われているかのまとめです。
* IaC テンプレートを GitHub のレポジトリに登録
* そのテンプレートを Deployment Environments のカタログを紐づける (KeyVault に格納した GitHub の Personal Access Token を使用します)
* 環境の種類ごとに、カタログを紐づける
* 開発者は開発者ポータルで、環境の種類を選択、そしてテンプレートを選択します
* 作成ボタンを押すだけ

以上の操作で環境を簡単に展開できます。
:::

### 環境定義 (.yaml)
前段で説明した、レポジトリに保管しておくテンプレートファイルのみではなく、他に yaml ファイルで「なんのテンプレートを使うのか？ パラメータは？」といったことを定義する環境定義が必要です。

これがカタログがスキャンしに行くファイルになります。
    以下が[環境定義のプロパティ](https://learn.microsoft.com/ja-jp/azure/deployment-environments/concept-environment-yaml#definitions)になります。2024 年 6 月現在で更新がない部分もあった為、追記してあります。

| プロパティ | Type | 説明 | 必須 | 使用例 |
|------------|------|------|------|--------|
| `name` | string | カタログ アイテムの表示名 | 〇 | |
| `version` | string | カタログ アイテムのバージョン | | 1.0.0 |
| `summary` | string | カタログ アイテムに関する短い概要文字列 |   | |
| `description` | string | カタログ アイテムの説明 |   | |
| `runner` | string | アクションの実行時に使用するコンテナー イメージ |   | ARM テンプレート, Bicep, または自作した Azure Container Registry に登録したカスタムコンテナ ({YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}) |
| `templatePath` | string | エントリ テンプレート ファイルの相対パス | 〇 |main.tf, main.bicep,.json |
| `Parameters` | string | 環境を作成し、アクションを実行するときに使用する入力パラメーター |   | #/definitions/Parameter |

例としては以下の様に記述します。
また私の検証に用いた GitHub のリポジトリはこちらになるので参考にしてみてください。(更新かけるかもしれないので、参考までに。また上位のディレクトリで GitHub Actions の Workflow を定義していますが、そちらに関して別記事で解説します。)

https://github.com/TakumiSeo/Azure-Deployment-Env-ACSS-Bicep/tree/main/Environments

```yaml
name: FunctionApp
version: 1.0.0
summary: Azure Function App Environment
description: Deploys an Azure Function App, Storage Account, and Application Insights
runner: ARM
templatePath: azuredeploy.json

parameters:
  - id: name
    name: Name
    description: 'Name of the Function App.'
    type: string
    required: true

  - id: supportsHttpsTrafficOnly
    name: 'Supports Https Traffic Only'
    description: 'Allows https traffic only to Storage Account and Functions App if set to true.'
    type: boolean
```

## カタログと Github/Azure DevOps の連携
IaC テンプレートを Azure Deployment Environments で使用するためにはそもそも、リポジトリにテンプレートを取りに行かないといけません。その方法について解説します。
Build 2024 でのスピーカーのコメントによると、Git プロバイダーならどこからでも、テンプレートを取ってこれるようになると話していましたが、今現在は GitHub と Azure DevOps 関連付けることで、IaC テンプレートを使用することができます。

https://learn.microsoft.com/ja-jp/azure/deployment-environments/how-to-configure-catalog?tabs=DevOpsRepoMSI#add-a-catalog

 **GitHub**
認証の方法としては 2 通りあります。
- GitHub アプリ
    - GitHub アカウントでサインインして認証
- 個人用アクセストークン
    - Key Vault のシークレットに 個人用アクセストークンを格納して認証
    - 個人用アクセストークンに関しては[こちら](https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)を参照

関係性としては以下の矢印の部分を担います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/6bf4dd59-ca62-529c-9912-2d6f2a816e37.png)

また Azure Portal では以下のように設定をします.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/0b447354-c7c1-f4ed-7666-fae7eee1d5e9.png)

**Azure DevOps**
認証の方法は、デベロッパーセンターのマネージド ID に対して Azure DevOps でアクセス許可を割り当てます。

:::note warn
サービスプリンシパルを追加する際の注意事項です。
* システム割り当てマネージド アカウントを使用する場合はマネージド アカウントのオブジェクト ID ではなく、デベロッパー センターの名前を指定してください
* ユーザー割り当てマネージド アカウントを使用する場合はマネージド アカウントの名前を使用してください
:::

## 権限
何となくお気づきのように、それぞれのコンポーネントが繋がって、環境の作成までたどり着きます。
つまりそれぞれの結びつきには「権限 - RBAC」の設定が必要不可欠になります。
このセクションでは、環境作成の大まかな流れを確認し、それぞれのコンポーネントにどのような権限が必要かを解説します。

**開発者が環境作成(開発者ポータルをポチッとしたとき)の流れ**

1\. 開発者が環境作成の為、開発者ポータルから、作成ボタンを押すと、デベロッパーセンターにリクエストが飛びます

2\. デベロッパーセンターが サブスクリプションレベルのほぼ所有者権限(ほぼの意味は後述)を持つマネージド ID により、リソースグループの作成をします

3\. そしてテンプレートの展開のために、デベロッパーセンターのマネージド ID が サンドボックスなどのプロジェクトの環境の種類のマネージド ID に対して 所有者権限の付与を行います

3\. その結果プロジェクトの環境の種類のマネージド ID により、テンプレートの展開が行われる形になります

4\. 最後に環境の作成を実行した開発者に対して RBAC の付与が行われます。(後述しますが、どんな権限を与えるかは設定で選べます)

### デベロッパーセンター レベルでの権限設定
ここでは、デベロッパーセンターに必要な権限を、このリソースが何をする必要があるかを「実装する操作」、どんなことをする権限がいるのかを「必要な権限」そして、オプションでプロジェクトの管理者 (開発者のリーダーなど) に 開発者ポータルのみでなく、 Azure Portal から操作させる場合に必要な権限に関して説明します。

**実装する操作**
* リソースグループの作成
* プロジェクトのマネージド ID に対する所有者権限の付与
* Personal Aceess Token を使用して GitHub と連携する場合は KeyVault のシークレットの読み取り

**必要な権限 (デベロッパーセンターのマネージド ID に対して)**
* 共同作成者
* ユーザー アクセス 管理者
* (キー コンテナー シークレット ユーザー)
ドキュメントにはこう書いてありますが、そうです、もうこれは所有者権限です。

**プロジェクトの管理者にポータルから操作させる場合**
* IAM で 管理者に 閲覧者 権限を付与
* プロジェクト単位で DevCenter Project Admin を付与

### プロジェクトレベルでの権限設定
プロジェクトには開発者が必要です。ただチームとして動くため、メンバーが増えたり減ったりもします。
その点を踏まえて、「利用するロール」で開発者の中で誰がどんな権限をプロジェクトリソースに対して持つべきか、そして[プロジェクトメンバーの増減方法]でメンバーの管理方法に関して解説します。

**利用するロール**
- DevCenter Project Admin
    - 開発者プロジェクトを管理するユーザー
- Deployment Environment Users
    - 環境を作成する開発者 (これを持ってれば、開発者ポータルから環境作成ができます)
- DevCenter Dev Box User
    - DevBox を利用する開発者

**プロジェクトのメンバーの増減方法**
DevCenter Project Admin ロールでは開発プロジェクトの設定変更は可能ですが、開発プロジェクトの新規作成や、メンバーの追加／削除はできません。
その為、Deployment Environment Users のロールを開発メンバーに与えるためには、User Access Administrator の権限を持つ管理者にメンバーの追加を依頼するか、自身が持つ必要があります。

つまりメンバーの管理は以下の方法が考えられます。
* 開発プロジェクトのスコープでプロジェクト管理者に User Access Administrator ロールを付与
* 権限付与の管理者に申請をしてメンバーを追加する
* Entra ID グループを開発プロジェクトに静的に割り当てておき、ユーザの増減については Entra ID 管理者に委任（＝Azure 側での権限付与・削除の操作はなし）

**例**
* 開発プロジェクトのの管理者: DevCenter Project Admin
* 開発者: Deployment Environment Users

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/04da5ba6-3528-d021-1908-0a03e0628c44.png)


### プロジェクトの環境の種類レベルでの権限設定
開発者が作成のボタンを押した時の流れを覚えていますでしょうか？
最後のフローで、「最後に環境の作成を実行した開発者に対して RBAC の付与が行われます」とありました。
そこを担うのがプロジェクトの環境の種類に割り当てられたマネージド ID です。
こちらに関しては、まず Azure Portal の設定画面を見て頂いた方が分かりやすいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693422/699342ac-16cc-bdb3-8526-58876f190853.png)

以上の図のように設定すべき項目は「環境作成者のロール」(ボタンをポチっと押した人に対する権限)と「追加のアクセス」(同時に権限を渡したい人を指定)です。

- 環境作成者のロール
    - 環境の作成を要求したユーザーに払い出す権限 (1 つのみ)
- 追加のアクセス
    - 追加のアクセス：それ以外に環境の作成時に権限を与えるユーザーとその権限 （プロジェクトの管理者など）
- 例
    - Sandbox 環境
        - 作成した開発者に共同作成者
        - 追加のアクセスで、共同で使う開発者に共同作成者

以上の権限設定を行うことで、環境作成をすることができます。

## デモ
結局どんな画面でどうやって開発者ポータルから環境作成するの？リソースグループはどのように作成されるの？
などと思う方もいると思うので、以下にデモのリンクを載せます。単純な流れのビデオですので、実際に作成する方法に関しては、Introduction でリンクを載せました、チュートリアルを参照してください。

https://youtu.be/glY0uWZxMOs

## Wrap Up
本記事では Azure Deployment Environments に関して、そのユースケースや Azure での登場人物の説明、また少しややこしい権限設定に関して解説しました。
実際に CI/CD を用いて実装したケースに関しては、今後ブログにまとめます。
なにかご質問やアドバイスがあれば、おねがいします～
ではでは