Azure DevOps で Self-hosted 環境を構築する方法

# はじめに

Microsoft-hosted はスゴく便利な環境ではあるのですが、リモートデスクトップ接続できないので、クラウド上でどのような状況になっているのか分からないといった事や、物理的にクラウドではできない事を、今回の Self-hosted で構築しようと思います。

Self-hosted の環境を構築する上での手順は以下の通りです。

- 端末（VPS でも自分の端末でもいいです）の用意
- [Personal Access Tokens (PAT) の取得](#pat-personal-access-tokens-の取得)
- [エージェントの登録](#エージェントの登録)

# Personal Access Tokens (PAT) の取得

Personal Access Tokens (以下 PAT) とは [Azure DevOps](https://azure.microsoft.com/ja-jp/services/devops/) へのアクセスを行う際に利用するトークンです。
このトークンにはそれぞれどのようなアクセス権を持つトークンであるかを設定することができます。

例えば…

- ソースコード (Azure Repos) の閲覧のみが可能なトークン
- タスク管理 (Azure Boards) の読み書きが可能なトークン
- 全てにアクセス可能なトークン

などがあります。

今回は Self-hosted で利用するエージェントのために必要なトークンを登録します。

## PAT の登録方法

エージェント登録のために必要なアクセス権は「**Agent Pools**」です。

[Azure DevOps](https://azure.microsoft.com/ja-jp/services/devops/) の管理画面の右上にあるアカウントアイコンを選択すると「Personal access tokens」という項目があると思いますので、それを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/f0222221-a096-1119-3942-fee52cd69b79.png)

そうすると以下のような画面が表示されると思います。(図ではすでに何点か登録済みですが…)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/60b72783-4ea3-6e7c-e3e6-e5c2aeed1e47.png)

それの左上にある「+ New Token」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/32c529bd-d7d1-ce38-42f7-5701adaf887b.png)

そうすると以下のような「Create a new personal access token」というサブウィンドウが開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/d533b8b5-34c5-d7f0-5f3e-30a79329fa87.png)

それぞれ設定する項目は以下です。

- Name：トークンを識別するための名前
- Organization：所属する組織
- Expiration (UTC)：トークンの有効期限
- Scopes：トークンのアクセス権

名前は適当に分かりやすい名前にしてもらえばいいですが、私は Unity のビルド用ですので「Unity Build Agent」とつけました。
Scopes (トークンのアクセス権) ですが、デフォルトでは…

- Work Items
- Code
- Build
- Release
- Test Management
- Packaging

しか表示されていませんので下にある「Show all scopes」を選択することで図にある「Agent Pools」が表示されます。
「Read」だけでは Agent の登録が行なえませんので「Read & manage」にチェックを入れて「Create」を選択してください。

「Success!」と表示されるとトークンの作成に成功しています。
ちなみにトークン作成のエラーは見たことがないのでどんな表示になるのか分かりません…。

また、警告表示されているように**作成したトークンは二度と表示することが出来ませんので必ずコピーしておいてください。**
もしコピーに失敗していた時は「Regenerate」で再発行が可能ですが、新しいトークンとなりますので注意してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/8d4d336e-0c81-4812-4da4-f082521508e2.png)

作成が完了すると先程の名前 (ここでは「Unity Build Agent」) のトークンが作成されているのが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/d9bbba30-d575-d069-9a0e-2c68f0d3e161.png)

これで PAT を利用する準備が整いましたので、ソースコードのクローンなどができるようになります。

# エージェントの登録
エージェントの登録ですが、今回は自分自身が利用している Windows 端末をエージェントとして登録します。

エージェントの登録は「Organization settings」から行います。Azure DevOps の左側にあるサイドバーの「Organization settings」から「Agent pools」を選択します。
※「Project settings」から行うことも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/62e5fc84-2364-266a-2618-75935243adfd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/9fd30145-6684-df23-c658-3e93763222d5.png)

「Agent pools」を選択すると、現在登録されているエージェントプール（登録されているエージェントのグループの事）の一覧が表示されます。実際にエージェントを登録するにはそれぞれのエージェントプールの配下に登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/b2536558-24b9-c8cd-76f7-3b8a2c54154f.png)
この画像で言えば「Azure Pipelines」「Default」「UE Agent for Windows」「Unity Agent for Mac」「Unity Agent for Windows」の5つのエージェントプールが登録されています。
標準では「Azure Pipelines」「Default」この2つがすでに登録されていると思いますが、このまま使うのもいいですし新しくエージェントプールを作成するのもどちらでもいいです。
エージェントプールは初回だけ必要ですでにエージェントプールがある場合は、エージェントの登録だけで問題ありません。
チームで利用する場合、エージェントプールだけ情報を開示するだけでいいと思います。

それでは実際にエージェントの登録を行います

まず、画像の右上にある「Add pool」を選択してください。
そうすると以下のようなサブウィンドウが立ち上がると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/6ab437de-c5cc-da16-5ea9-92ef4f47e75c.png)
今回のエージェントプール名は「Unity Agent」とし簡単な説明も追加しています。パーミッションについては、このままデフォルトで構いません。細かくエージェントにパーミッションを与えたい場合は、登録後に変更することができます。

さて、「Create」を押すと先程の一覧に新しいエージェントグループが作成されたと思いますので、作成されたエージェントを選択してください。そうすると以下のような画面になったと思います。デフォルトでは「Jobs」タブが選択されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/2727abda-7393-2025-4be9-55edde2d6fa2.png)
画面上部にあるタブはそれぞれ以下のような感じです。

|タブ名|説明|
|:--|:--|
|Jobs|実行したジョブ履歴|
|Agents|登録されているエージェント一覧|
|Details|エージェントプールの詳細。作成者とか説明とか|
|Security|エージェントのパーミッション|
|Settings|エージェントの設定|
|Maintenance History|メンテナンス履歴|

エージェントの登録はタブにある「Agents」を選択すると以下の画面になりますので「New agent」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/43f962be-3748-8b7a-4deb-760575b2433a.png)

そうすると以下のような画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/04cc7fe0-97c8-b390-8d79-dfe40678fd60.png)
今回は Windows を選択していますので「C:\」になっていますが、Macの場合は「~/$」という表記になっていると思います。
それでは赤枠の「Download」を選択してエージェント登録のためのファイル一式をダウンロードしてください。ダウンロードするファイルはzipファイルですが、画面に記載ある通りに PowerShell で入力すればOKです。コピペでもいいです。

### 自動起動の注意点
**※ここで注意が必要なのはターミナルを実行する際には管理者権限がある状態にしておいてください。後で出てくるエージェントの自動起動をするには管理者権限が必要です。
また、Windows の場合は「C:\」の直下に配置するようにしてください。ユーザーディレクトリの場合、自動起動が出来ない可能性があります。**

## エージェントの起動

では、次は端末側のターミナルの画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/70630b6d-681c-5df8-c361-714043e8e15d.png)
先程の Azure DevOps 側の画面にあった通り、「.\config.cmd」を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/56700a7a-264a-9f4f-a1e5-4a5ff286f031.png)

ここではエージェント登録のためのウィザードになりますが以下の項目の設定が必要です。

|項目|今回の設値|
|:--|:--|
|サーバーURL|https://dev.azure.com/[Origanaization]|
|認証の種類|PAT|
|登録するエージェントプール|Unity Agent|
|エージェント名|好きな名前（デフォルトでは端末名）|
|作業フォルダー|_work（デフォルト）|
|エージェントの自動起動の選択|あり ([自動起動の注意点](#自動起動の注意点))|

先程、取得した [PAT](#pat-personal-access-tokens-の取得) と[エージェントプール](#エージェントの登録)を入力します。それ以外はデフォルトで十分だと思います。
エージェントの自動起動については好みだと思いますが、毎回起動しないといけないのは面倒ですので自動起動でもいいんじゃないかと思います。ちなみにエージェントの起動は「.\config.cmd run」です。

ここで無事にエージェントが登録・起動できると Azure DevOps 上では「Online」になっていることが確認できると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/f5486ce9-ebff-0b1d-eb94-c6a365bf6698.png)


# おわりに

以上で Self-hosted 環境を構築することが出来ました。
実際に Pipelines で利用するにはすごく簡単なのですが簡易的な説明は以下の投稿を参照してください。
[Pipelines の Microsoft-hosted と Self-hosted](https://qiita.com/akiojin/items/1fb2d516399967c183bf)

もっと具体的な Pipelines の説明は後日！