【ハンズオン】WindowsでAzure CLI・Azure Powershell・Terraformをインストールして触ってみる

# きっかけ
自己学習のため、Azureの無料アカウントを作成した。GUIでの操作と同時にTerraformも学びたかったためインストールを行う。

https://learn.microsoft.com/ja-jp/azure/developer/terraform/overview

> **次のステップ**
>環境に応じて、Terraform をインストールして構成します。
>
>**Terraform の構成**: まだ行っていない場合は、次のいずれかのオプションを使用して Terraform を構成します。
>
>* [Bash を使用して Azure Cloud Shell で Terraform を構成する](https://learn.microsoft.com/ja-jp/azure/developer/terraform/get-started-cloud-shell-bash)
>* [PowerShell を使用して Azure Cloud Shell で Terraform を構成する](https://learn.microsoft.com/ja-jp/azure/developer/terraform/get-started-cloud-shell-powershell)
>* [Bash を使用して Windows で Terraform を構成する](https://learn.microsoft.com/ja-jp/azure/developer/terraform/get-started-windows-bash)
>* [PowerShell を使用して Windows で Terraform を構成する](https://learn.microsoft.com/ja-jp/azure/developer/terraform/get-started-windows-powershell)

Terraformのインストール方法が4つ案内されていたが、一番下の方法で行っていく。

# 本記事の内容

https://learn.microsoft.com/ja-jp/azure/developer/terraform/get-started-windows-powershell

上記のMS記事内では下記の内容が説明されている。

今回は、1~7までを行っていく。

> 1. 最新バージョンの PowerShell をインストールする
> 2. 新しい PowerShell Az モジュールをインストールする
> 3. Azure CLI をインストールする
> 4. Terraform をインストールする
> 5. Terraform と Azure の一般的な認証シナリオを理解する
> 6. Microsoft アカウントを使用して、Cloud Shell から認証する (Bash または PowerShell を使用)
> 7. Microsoft アカウントを使用して、Windows から認証する (Bash または PowerShell を使用)
> 8. Azure CLI を使用してサービス プリンシパルを作成する
> 9. Azure PowerShell を使用してサービス プリンシパルを作成する
> 10. 環境変数でサービス プリンシパルの資格情報を指定する
> 11. Terraform プロバイダー ブロックでサービス プリンシパルの資格情報を指定する

# 前提条件
>:::note warn
>環境を構成する
>Azure サブスクリプション:Azure サブスクリプションをお持ちでない場合は、開始する前に [無料アカウント](https://azure.microsoft.com/free/?ref=microsoft.com&utm_source=microsoft.com&utm_medium=docs&utm_campaign=visualstudio) を作成してください。
>:::

恐縮だが、私のQiita記事を参考に挙げておく。

https://qiita.com/riv_infra/items/a9ae0d03c0146952185b

# 1\. 最新バージョンの PowerShell をインストールする
> Azure リソースの操作を可能にする最新の PowerShell モジュールは、Azure PowerShell Az モジュールと呼ばれています。 Azure PowerShell Az モジュールを使用する場合、すべてのプラットフォームで**推奨されるバージョンは PowerShell 7 (またはそれ以降)** です。

Windowsに標準でインストールされているPowerShellは推奨されない。
```PowerShell:command1
$PSVersionTable.PSVersion
```
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/d03cd95a-3223-7dab-df8a-11de83cf4288.png">

推奨バージョンが入っていない方は以下記事を参考。

https://learn.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4

私は推奨方法のWingetパッケージを使用したインストールを行ったので、その流れを記載しておく。

## [Winget を使用して PowerShell をインストールする (推奨)](https://learn.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4#install-powershell-using-winget-recommended)

公開済みのwingetパッケージを使用して最新バージョンのPowerShellを検索。
```PowerShell:command2
winget search Microsoft.PowerShell
```
id パラメーターを使用して PowerShellをインストール。
```PowerShell:command3
winget install --id Microsoft.Powershell --source winget
```
プレビュー版をインストールする場合はこちら
```PowerShell:command4
winget install --id Microsoft.Powershell.Preview --source winget
```

# 2\. 新しい PowerShell Az モジュールをインストールする

参考にしていたMS記事内にはAzモジュールのインストール方法がなかった。
下記のMS記事を参考にインストールしていく。

https://learn.microsoft.com/ja-jp/powershell/azure/install-azps-windows?view=azps-12.2.0&tabs=powershell&pivots=windows-psgallery

既にAzure PowerShellモジュールがインストール済みでないか確認。
インストール済みの場合、後からでてくるUpdate-Moduleのみ実行すればよいと思われる。
```PowerShell:command5
Get-Module -Name Az -ListAvailable
```

## 前提条件
AzureRM PowerShell モジュールがインストールされているかどうかを確認
```PowerShell:command6
Get-Module -Name AzureRM -ListAvailable
```
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/1a4a2863-67e9-6f9c-a038-8f7dd81e9ae7.png">

>:::note warn
>AzureRM PowerShell モジュールがインストールされている場合は、次に進む前に、「[Az と AzureRM の共存](https://learn.microsoft.com/ja-jp/powershell/azure/troubleshooting?view=azps-12.2.0#az-and-azurerm-coexistence)」を参照してください。
>:::

## PowerShell スクリプトの実行ポリシーの確認・変更
```PowerShell:command7
Get-ExecutionPolicy -List
```
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/94e0c574-b0ff-e2d8-3320-079fa95abd9d.png">

```PowerShell:command8
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/90651bdc-536f-701f-fe6b-7d88b5564dc5.png">

実行ポリシーの詳細については、「[about_Execution_Policies](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies)」を参照

## Az PowerShell モジュールのインストール
インストール
```PowerShell:command9
Install-Module -Name Az -Repository PSGallery -Force
```
更新
```PowerShell:command10
Update-Module -Name Az -Force
```

<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/6993fa3a-eecb-a648-ee3e-f5154652f413.png">

## PowerShellでAzureにサインイン

```PowerShell:commnad11
Connect-AzAccount
```
対象を選択する。個人で作った場合はほとんどMicrosoftアカウント？
<img width="220" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/d51e989c-bda5-e51b-0e6d-92c8c605f2cd.png"><img width="180" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/724c4d2a-82bd-0e06-356b-605fa554be04.png"><img width="180" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/ba4e4ff1-1278-baea-daa5-d03598c3e075.png">

サインインできた。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/d40728c3-0440-eeea-447e-5a7711980f6a.png">

## [お試し]PowerShellでリソースグループの作成
```Powershell:command12
$rg = @{
    Name = 'test-rg'
    Location = 'eastus2'
}
New-AzResourceGroup @rg
```
<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/3edda865-b4e4-c4a2-980f-563eaadffaaf.png">

確認
```PowerShell:command13
Get-AzResourceGroup -ResourceGroupName 'test-rg'
```

<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/234052dd-6169-eee7-2767-b6cf7b40d4a6.png">

Azure Portalでもリソースグループが作成されたことを確認できた。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/562beb11-8781-5ca4-22c3-027dc99325c3.png">

終わったらAzureからサインアウトしておく。
```PowerShell:command14
Disconncet-AzAccount
```
<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/08f2b7ef-a7c9-38c8-34e3-0f70095d4af2.png">

# 3\. Azure CLI をインストールする

>[Terraform で Azure に対して認証を行う](https://www.terraform.io/docs/providers/azurerm/guides/azure_cli.html)には、[Azure CLI をインストール](https://learn.microsoft.com/ja-jp/cli/azure/install-azure-cli-windows)する必要があります。

https://learn.microsoft.com/ja-jp/cli/azure/install-azure-cli-windows?tabs=azure-cli

>Azure CLI の現在のバージョンは **2.63.0** です。 最新リリースについては、[リリース ノート](https://learn.microsoft.com/ja-jp/cli/azure/release-notes-azure-cli)をご覧ください。 

## Azure CLIが既にインストール済みでないか確認
```:Azure CLI1
az --version
```
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/b45d7a7b-4de8-e3de-f257-d772dc89ab95.png">

出力の最下行に`Your CLI is up-to-date.`とあれば最新バージョン。
最新バージョンでなければ後述の**Azure CLIの更新**の実施を推奨。

## Azure CLIのインストール

インストール方法は4種類ある。今回は2で行う。
>1. Microsoftインストーラー(MSI)
>2. PowerShellを使用したMicrosoftインストーラー(MSI)
>3. Windows パッケージ マネージャー
>4. ZIPパッケージ(プレビュー段階)

**管理者**でPowerShellを起動し、下記のコマンドを実行。
```PowerShell:command16
$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://aka.ms/installazurecliwindowsx64 -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; Remove-Item .\AzureCLI.msi
```
今回は、64 ビットの方で、インストールするため、URL を`https://aka.ms/installazurecliwindowsx64` に変更している。
>2.51.0 以降では、Azure CLI には 64 ビット MSI も用意されており、パフォーマンスを向上させるために推奨されます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/eba7c2ab-7bb9-d6f8-e96f-35c6ab23cdea.png">

## インストールの確認
PowerShellのターミナルを再起動する(コマンドプロンプトでもよい）。
以下のコマンドを実行し、インストールできたか確認。
```:Azure CLI2
az
```

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/ac5286a3-c81c-f8a9-4115-b7ec1f219619.png">

```:Azure CLI3
az --version
```
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/b45d7a7b-4de8-e3de-f257-d772dc89ab95.png">

出力の最下行に`Your CLI is up-to-date.`となければ**更新**を推奨。

## Azure CLIの更新

>バージョン 2.11.0 以降の Azure CLI には、最新バージョンに更新するためのツール内コマンドが用意されています。
```:Azure CLI4
az upgrade
```
>  `az upgrade` オプションの詳細については、[コマンド リファレンス ページ](https://learn.microsoft.com/ja-jp/cli/azure/reference-index#az_upgrade)をご覧ください。

## Azure CLIを用いたAzureへのサインイン

https://learn.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli

> Azure CLI を使用する場合、次の4つの認証オプションがあります。
>
>1. [Azure Cloud Shell](https://learn.microsoft.com/ja-jp/azure/cloud-shell/overview)
>2. [対話操作でサインインする](https://learn.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli-interactively)
>3. [サービス プリンシパルを使用してサインインする](https://learn.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli-service-principal)
>4. [マネージド ID を使用してサインインする](https://learn.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli-managed-identity)

今回は、2で行う。

https://learn.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli-interactively

```:Azure CLI5
az login
```

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/49af48b4-4b86-d0a7-75cb-c280301ae5b4.png">
<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/49fc1496-08b3-473e-c557-b6135e77a9a2.png"><img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/07918d59-4a4b-af6a-ccaa-0f467ea8a331.png">
<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/93d84fb0-760f-a076-c50c-701264b3db19.png">

>Azure CLI バージョン 2.61.0 以降では、複数のサブスクリプションにアクセスできる場合は、次の例に示すように、ログイン時に Azure サブスクリプションを選択するように求められます。
>
>次回ログインすると、以前に選択したテナントとサブスクリプションが既定値としてマークされ、その番号の横にアスタリスク (*) が付きます。 これにより、Enterキーを押して既定のサブスクリプションを選択できます。

既定のサブスクリプションを変更する場合は以下のコマンドを実行。
```:Azure CLI6
az account set --subscription "<subscription ID or name>"
```
詳細についてはこちら。

https://learn.microsoft.com/ja-jp/cli/azure/manage-azure-subscriptions-azure-cli?tabs=bash

## [お試し]Azure CLIでリソースグループを作成

```:Azure CLI7
az group create --name demoResourceGroup --location westus
```
<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/77783708-e182-5e8f-aff0-fb6c575843ba.png">

```:Azure CLI8
az group show --name 'demoResourceGroup'
```

<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/87ebf36c-7168-408f-ccd5-5e517ffc3ee3.png">

作業が終わったらサインアウトしておく。
```:Azure CLI9
az logout
```

# 4\. Terraform をインストールする

>1\. [Terraform をダウンロードします](https://www.terraform.io/downloads.html)。 この記事は、Terraform バージョン 1.1.4 を使用してテストされました。

MS記事では1.1.4で実施されたようだが、2024/08/17現在の最新は1.9.4だったため、この最新バージョンをインストールする。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/95af784c-30c7-8290-59a4-fcb0efb707fd.png">

32bit版の方は386、64bit版の方はAMD64を選択。
違いについては下記のサイトが参考になった。呼び名の歴史の話が面白かった。

https://blog.future.ad.jp/small-talk-about-it-001-why-is-amd64-even-though-the-intel-cpu

>2\. ダウンロードから、任意のディレクトリ (例: `c:\terraform`) に実行可能ファイルを抽出します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/8d1b8b23-70fa-b9db-376c-56bff56cb7ad.png">

## 環境変数PATHにterraformのパスを追加
>3\. 実行可能ファイルを含むディレクトリが含まれるように、システムのグローバル PATH 環境変数を更新します。

「Windows」+「R」キーを同時押し→ 「sysdm.cpl」
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/fa630181-b372-592e-bdc8-2a65948b6a55.png">
「詳細設定」タブ → 「環境変数」
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/f705361b-5074-e9b4-9eaf-1e47c6b99429.png">

下の「システム環境変数」の「Path」を選択 → 「編集」
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/b701a52d-d5a7-132a-50ab-24c2c3ad2441.png">

「新規」
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/1bb6e84d-dff7-32f5-7b7b-c24f0a585c62.png">

terraform.exeを格納したパス(今回であれば`C:\terraform`)を入力 → 「OK」
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/b11fc741-61b7-b17f-26b0-4acf8b29e4fc.png">

>4\. ターミナル ウィンドウを開きます。

更新された環境変数PATHの読み込みが必要なため、ターミナルを開きなおす。
>5\. terraform コマンドでグローバル パス構成を確認します。
```
terraform --version
```
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/0be0771f-a6bf-013e-92ed-f0618d124c61.png">

Terraform バージョン 1.9.4でもMS記事の手順でインストールができた。

# 5\. Terraform と Azure の一般的な認証シナリオを理解する

https://learn.microsoft.com/ja-jp/azure/developer/terraform/authenticate-to-azure?tabs=azure-powershell

> Azure サブスクリプションに対して Terraform コマンドを使用するには、まず、そのサブスクリプションに対して Terraform を認証する必要があります。

>:::note info
>Terraform では、**Azure CLI を使用した Azure への認証のみ**がサポートされます。 Azure PowerShell を使用した認証はサポートされていません。 そのため、Terraform の作業を行うときには Azure PowerShell モジュールを使用できますが、まず Azure CLI を使用して Azure に対する認証を行う必要があります。
>:::

# 6\. Microsoft アカウントを使用して、Cloud Shell から認証する (Bash または PowerShell を使用)
今回は、一時的な検証目的のため、ストレージアカウントの作成が不要なCloud Shell エフェメラル セッションを使用する。

https://learn.microsoft.com/ja-jp/azure/cloud-shell/get-started/ephemeral?tabs=azurecli

## 前提条件
>Azure Cloud Shell を使用する前に、**Microsoft.CloudShell** リソース プロバイダーを登録する必要があります。 リソースへのアクセスは、サブスクリプションに登録する必要があるプロバイダー名前空間を通じて有効になります。 名前空間はサブスクリプションごとに 1 回だけ登録する必要があります。

## リソースプロバイダーとは

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/overview

上記MS記事より引用したが、以下画像の部分の赤枠のリソースを提供するサービス。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/d0f01534-6aa9-1eae-0a50-eb58a95814ef.png">

>リソース プロバイダー - Azure リソースを提供するサービス。 一般的なリソースプロバイダーの一例として、仮想マシン リソースを提供する `Microsoft.Compute` があります。

> Azure リソース プロバイダーは、特定の Azure サービスの機能を有効化する REST 操作のセットです。

リソースプロバイダーは、以下記事にもある通り、一部のリソースを除き、必要な時に自動で登録される。

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/resource-providers-and-types

>一部のリソース プロバイダーが既定で登録されています。 既定で登録されているリソース プロバイダーの一覧については、「[Azure サービスのリソース プロバイダー](https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/azure-services-resource-providers)」を参照してください。
>
>その他のリソース プロバイダーは、特定のアクションを実行すると自動的に登録されます。

ただ今回は、MS記事の手順に従い手動で登録する。

## リソースプロバイダーの登録

>* Azure portal にサインインします。
>* Azure portal のメニューでサブスクリプションを検索します。 使用可能なオプションから、それを選択します。
>* 表示するサブスクリプションを選択します。
>* 左側のメニューの [設定] で、 [リソース プロバイダー] を選択します。
>* 検索ボックスに「cloudshell」と入力して、リソース プロバイダーを検索します。
>* プロバイダーの一覧から Microsoft.CloudShell リソース プロバイダー登録を選択します。
>* [登録] を選択して、状態を [登録解除] から [登録済み] に変更します。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/16173db9-7a0e-5390-f74f-8aff7baf29ab.png">

少し待つ。今回は1,2分程度だった。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/85ffc641-cd13-796d-47f4-0f1ab987741a.png">

登録が完了した。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/2215f7fc-b2d3-2cf4-e5e0-be47e4b103e8.png">

## Cloud Shell の起動

>* Azure Portal 上部のナビゲーションから Cloud Shell を起動します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/7d16eba4-495b-97be-87d9-5c25fc0acc06.png">

>* 初めて Cloud Shell を起動すると、どのシェルを使うかを確認するダイアログが表示されます。

今回は「PowerShell」を選択。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/fbf9bfad-1c66-4122-1ff9-8f935a0f3d61.png">

>* [使用を開始する] ウィンドウで、エフェメラル セッションに [ストレージ アカウントは不要] を選択します。 ドロップダウン メニューを使って、Cloud Shell に使うサブスクリプションを選び、[適用] ボタンを選びます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/73a1d7bc-39b3-b4ff-6a3c-4449c56ed819.png">

Cloud Shellが起動できた。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/1dfc5ef5-c6b1-0050-8c7e-a330ae7fd730.png">

## 認証済みかつ構成済みの Azure ワークステーション
> Azure CLI または Azure PowerShell コマンドレットを介してすばやくリソースにアクセスできるよう、Cloud Shell では安全に自動認証が行われます。 Cloud Shell に[インストールされているツールの一覧](https://learn.microsoft.com/ja-jp/azure/cloud-shell/features#preinstalled-tools)はこちらからご覧いただけます。

認証済みなので、わざわざaz loginコマンドを実行する必要がない。
インストール済みのモジュールを確認してみる。
```PowerShell:command15
Get-Module -ListAvailable
```
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/83677cef-2b64-6fe9-0208-7c08805c949f.png">

# 7\. Microsoft アカウントを使用して、Windows から認証する (Bash または PowerShell を使用)

## Azure CLIでAzureへのサインイン

PowerShellを起動し、`az login`でAzureにサインインする。

再掲
>:::note info
>Terraform では、**Azure CLI を使用した Azure への認証のみ**がサポートされます。 Azure PowerShell を使用した認証はサポートされていません。 そのため、Terraform の作業を行うときには Azure PowerShell モジュールを使用できますが、まず Azure CLI を使用して Azure に対する認証を行う必要があります。
>:::

# クイック スタート: Terraform を使用して Azure リソース グループを作成する

https://learn.microsoft.com/ja-jp/azure/developer/terraform/create-resource-group?tabs=azure-cli

>この記事では、次のことについて説明します。
>
>* [random_pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) を使用して Azure リソース グループ名のランダムな値を作成する。
>* [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) を使用して Azure リソース グループを作成する。

> The resource `random_pet` generates random pet names that are intended to be used as unique identifiers for other resources.

## Terraform コードを実装する

>:::note info
>この記事のサンプル コードは、[Azure Terraform GitHub リポジトリ](https://github.com/Azure/terraform/tree/master/quickstart/101-resource-group)にあります。
:::

> サンプルの Terraform コードをテストするディレクトリを作成し、それを現在のディレクトリにします。

下記4つの.tfファイルを作成し、そのディレクトリに格納する。

>  **providers.tf**
> ```:providers.tf
> terraform {
>   required_providers {
>     azurerm = {
>       source  = "hashicorp/azurerm"
>       version = "~>3.0"
>     }
>     random = {
>       source  = "hashicorp/random"
>       version = "~>3.0"
>     }
>   }
> }
> 
> provider "azurerm" {
>   features {}
> }
> ```
> **main.tf**
> ```:main.tf
> resource "random_pet" "rg_name" {
>   prefix = var.resource_group_name_prefix
> }
> 
> resource "azurerm_resource_group" "rg" {
>   location = var.resource_group_location
>   name     = random_pet.rg_name.id
> }
> ```
> **variables.tf**
> ```:variables.tf
> variable "resource_group_location" {
>   type        = string
>   default     = "eastus"
>   description = "Location of the resource group."
> }
> 
> variable "resource_group_name_prefix" {
>   type        = string
>   default     = "rg"
>   description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
> }
> ```
> **outputs.tf**
> ```:outputs.tf
> output "resource_group_name" {
>   value = azurerm_resource_group.rg.name
> }
> ```

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/03a4fa2b-1f33-4ece-a2fe-06efe2de4103.png">

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/186363d9-f024-0f8a-07e8-737858023857.png">

## Terraform を初期化する

> [terraform init](https://www.terraform.io/docs/commands/init.html) を実行して、Terraform のデプロイを初期化します。 このコマンドによって、Azure リソースを管理するために必要な Azure プロバイダーがダウンロードされます。

```
terraform init -upgrade
```
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/e7b65069-7661-cab2-9111-a3f25845f123.png">

## Terraform 実行プランを作成する

> [terraform plan](https://www.terraform.io/docs/commands/plan.html) を実行して、実行プランを作成します。

```
terraform plan -out main.tfplan
```
>* `terraform plan` コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、**実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認**できます。

結果が出力されるまで3分ほどかかった。
<img width="850" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/abdd6c1c-843b-3da1-731d-959490786c9b.png">

## Terraform 実行プランを適用する

> [terraform apply](https://www.terraform.io/docs/commands/apply.html) を実行して、クラウド インフラストラクチャに実行プランを適用します。

```
terraform apply main.tfplan
```
20秒ほどで実行が完了した。
<img width="650" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/08972451-5e7f-928d-b948-c25cde6bb14a.png">

今回は`random_pet`でリソースグループのidが`rg-sure-glider`となった。

## 結果を確認する

>1\. Azure リソース グループ名を取得します。
```PowerShell:command16
$resource_group_name=$(terraform output -raw resource_group_name)
```
<img width="650" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/e8161c2b-6ee9-f5e6-2819-ac01dde02aec.png">

>2\. [Get-AzResourceGroup](https://learn.microsoft.com/ja-jp/powershell/module/az.resources/Get-AzResourceGroup) を実行して、リソース グループを表示します。

```PowerShell:command17
Get-AzResourceGroup -Name $resource_group_name
```
リソースグループが作成できたことを確認。
<img width="650" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/3ccb688f-6839-7fd7-e19c-b989233e64ac.png">

### [お試し]terraform import で既存のリソースをterraform管理下にする

MS記事ではこの後リソースのクリーンアップとなるが、先ほどコマンドで作成したリソースをterraform管理下にしてから一緒に削除を試してみる。


https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group

#### Importについて

> Resource Groups can be imported using the `resource id`, e.g.
```
terraform import azurerm_resource_group.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1
```
上記コマンドの2つ目の引数は`resource id`なのは分かったが、1つ目の引数がよくわからなかったので調べてみた。
```
resource "azurerm_resource_group" "example" {
  name     = "example"
  location = "West Europe"
}
```
`azurerm_resource_group`がterraformのazurerm providerの一種なのはわかったが`example`が何なのか公式ドキュメントを読んでもすぐには見つからなかったので、ChatGPTに聞いてみた。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/40761093-9f01-4145-b321-41cb73c26ab3.png">

terraform内だけの名前らしい。

#### `resource id`の取得

Azure Portalの場合
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/596d8285-df89-ad3d-4ce4-f5d930418159.png">

PowerShellの場合
```PowerShell:command18
(Get-AzResourceGroup -Name 'test-rg').ResourceId | clip
```
パイプラインでclipに渡すことで、クリップボードにコピーできる。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/2a2f8685-44e9-e337-9106-8ca8aa090c57.png">

最近知ったので使ってみたかった。

https://gigazine.net/news/20240812-windows-clip-command-clipboard/

#### terraform importの実行

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/9f581d93-424c-1bdb-9d94-cbc7d062958a.png">

実行すると、エラーとなった。先にmain.tfにresourceブロックを書いておく必要があるらしい。

以下のように追記。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/108c78d2-aef8-4056-846d-147cd364accb.png">

:::note warn
この書き方は良くない。この後実行するコマンドでエラーが発生するのでその際にlocationとnameを追加する。
:::

気を取り直して再実行。
<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/96365bbb-4ad6-d8f5-0157-264604062ea3.png">

importできた。

## リソースをクリーンアップする

>Terraform を使用して作成したリソースが不要になった場合は、次の手順を実行します。

>1\. [terraform plan](https://www.terraform.io/docs/commands/plan.html) を実行して、`destroy` フラグを指定します。

```
terraform plan -destroy -out main.destroy.tfplan
```

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/cfae2720-91ee-7054-f861-e89b7165749b.png">

`resource`ブロックにlocationとnameが必要らしい。

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group

よく読むとちゃんと書いてあった。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/66e240f2-58e5-0e68-bb1d-e1a17678ce1d.png">

rg.tfvarsを新規作成。
```:rg.tfvars
resource_group_name     = "test-rg"
resource_group_location = "East US 2"
```

下記を追加。
```:main.tf
resource "azurerm_resource_group" "example" {
  location = var.resource_group_location
  name = var.resource_group_name
}
```

こちらも追加。
```:variables.tf
variable "resource_group_name" {
  description = "The name of the resource group."
  type        = string
  default     = "test-rg"
}
```

文法や構文が正しいかどうかを確認。
```
terraform validate
```

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/56e0a039-becb-f838-4094-18c2fa90aba3.png">

実行プランの作成が完了。
<img width="850" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/4a9e69b5-98ac-849e-2dbf-57c4e977446f.png">

>2\. [terraform apply](https://www.terraform.io/docs/commands/apply.html) を実行して、実行プランを適用します。

```
terraform apply main.destroy.tfplan
```

削除完了。
<img width="850" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/68f401d2-60b0-f8f9-417c-26a05a51d601.png">

Azure Portalでもterraform管理下のリソースグループが削除されたことを確認。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/6fa56b93-97a7-4c48-1fd2-50ab94e3fe12.png">

# おわりに

WindowsやPowershellでTerraformを試す記事はあまりなかったので、初めてTerraformを触れる方には多少は読む価値のある記事になっていると良いなと思いました。
これからも主にAzureやMicrosoft関連について記事を投稿していくので、気になる方いらっしゃれば是非フォローお願いします🥰