LoginSignup
2
1

More than 1 year has passed since last update.

【Terraform de Azure】 Azureで事前に準備しておくべきこと

Last updated at Posted at 2022-01-06

概要

「Infrastructure as Code」ということで、Terraform を用いて Azureを構成するときに、あらかじめ Azureに仕込んでおくべきことを記載しています。 おおまかな流れは以下となります。

  1. Terraform の構成ファイル「tfstate」の保存場所の作成(ローカルに保存する場合は不要)
  2. Terraform でAzure上に環境構築するためのサービスプリンシパルの作成
  3. 確認のため、Terraform でリソースグループを作成してみる

ローカル環境

  • macOS Monterey 12.0.1
  • Azure CLI 2.28.0
  • terraform v1.0.11

前提条件

  1. Azure環境がすでに用意されていること(テナント/サブスクリプション)
  2. ローカル環境に「azure cli」がインストールされていること
  3. ローカル環境に「terraform」環境が構成されていること

準備

Terraform の構成ファイル 「tfstate」 の保存場所の作成 (ローカルに保存する場合は不要)

## ローカル環境変数の定義
export RG_TF_NAME=rg-ituru-tfstate
export SUBS_NAME=PSG2-01
export STORAGE_TF_ACCOUNT=iturutfstate
export STORAGE_TF_CONTAINER=tfstate

## 使用するテナントへのログイン
$ az login --tenant <tenant_id>

## 使用サブスクリプションの定義
$ az account set --subscription $SUBS_NAME

## teffarom tfstate 用のリソースグループ作成
$ az group create --name $RG_TF_NAME --location japaneast

## teffarom tfstate 用のストレージアカウントの作成
$ az storage account create --name $STORAGE_TF_ACCOUNT --resource-group $RG_TF_NAME -l japaneast --sku Standard_LRS --enable-hierarchical-namespace true

## teffarom tfstate ファイルを保存するコンテナの作成
$ az storage container create --name $STORAGE_TF_CONTAINER --account-name $STORAGE_TF_ACCOUNT

## teffarom tfstate 用のストレージアカウントの認証情報の取得
$ az storage account keys list --account-name $STORAGE_TF_ACCOUNT --subscription $SUBS_NAME --resource-group $RG_TF_NAME --output table
CreationTime                      KeyName    Permissions    Value
--------------------------------  ---------  -------------  ----------------------------------------------------------------------------------------
2021-12-04T16:11:49.888094+00:00  key1       FULL           pppppppppppppppppppppppppppp....ppppp
2021-12-04T16:11:49.888094+00:00  key2       FULL           qqqqqqqqqqqqqqqqqqqqqqqqqqqq....qqqqq

## Terraform のためのローカル環境変数の定義
export ARM_ACCESS_KEY="<storage_account_key1>"

Teffarom でAzure上に環境構築するためのサービスプリンシパルの作成

## ローカル環境変数の定義
export SP_TF_NAME=sp_itutu_terraform

## サービスプリンシパルの有効期限を2年で作成します(ロール割当なしで)
$ az ad sp create-for-rbac --name $SP_TF_NAME --skip-assignment --years 2
{
  "appId": "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx",      --> AZURE_CLIENT_ID として terraform実行ローカル環境変数として登録
  "displayName": "<ServicePrincial名>",
  "name": "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx",
  "password": "hogehogehogehogehogehogehogehogege",     --> AZURE_CLIENT_SECRET として terraform実行ローカル環境変数として登録
  "tenant": "zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz"      --> AZURE_TENANT_ID として terraform実行ローカル環境変数として登録
}

## 必要なスコープに必要なロールを割り与えるための appId の取得
$ APP_ID=$(az ad sp list --display-name $SP_TF_NAME --query '[].{ID:appId}' --output tsv)

## 必要なスコープに必要なロールを割り与えるための サブスクリプションID の取得
$ SUBS_ID=$(az account show --query "id" --output tsv)

## 必要なスコープに必要なロールの割当て
## 今回はSubscription各種リソースを定義するので、スコープ:Subscription ロール:Contributor(共同作成者)とします
$ az role assignment create --assignee $APP_ID --scope /subscriptions/$SUBS_ID --role Contributor

Terraform でリソースグループを作成してみる

terraform 定義ファイルの作成

メイン定義ファイル

main.tf
# プロバイダーの定義
terraform {
  required_providers {
    azurerm =  "~> 2.33"
  }

  # tfstate ファイルの保存先(ローカルに保存の場合、不要)
  backend "azurerm" {
    storage_account_name = "iturutfstate"
    container_name       = "tfstate"
    key                  = "test01/terraform.tfstate"
  }
}

# Azureプロバイダ
provider "azurerm" {
  features {}
  tenant_id     = var.ARM_TENANT_ID
  client_id     = var.ARM_CLIENT_ID
  client_secret = var.ARM_CLIENT_SECRET
}

# リソースグループ
resource "azurerm_resource_group" "this" {
  name     = var.resource_group_name
  location = var.region
  tags     = var.tags_def
}

パラメータ定義ファイル

variables.tf
# 環境変数(Azureサービスプリンシパル)
variable ARM_TENANT_ID {}
variable ARM_CLIENT_ID {}
variable ARM_CLIENT_SECRET {}

# タグ情報
variable tags_def {
  default = {
    owner      = "ituru"
    period     = "2022-03-31"
    CostCenter = "psg2"
  }
}

# 各種パラメータ 
variable resource_group_name {}
variable region {}

パラメータ値定義ファイル

terraform.tfvars
# 環境変数の定義(Azureサービスプリンシパル)
ARM_TENANT_ID       = "zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz"
ARM_CLIENT_ID       = "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx"
ARM_CLIENT_SECRET   = "hogehogehogehogehogehogehogehogege"

# パラメータ値の定義
resource_group_name = "rg_ituru_test"     // リソースグループ名
region              = "japaneast"         // 利用リージョン

terraform の実行

## init
$ terraform init

Initializing the backend...

Successfully configured the backend "azurerm"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Using previously-installed hashicorp/azurerm v2.88.1

Terraform has been successfully initialized!


## plan
$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.this will be created
  + resource "azurerm_resource_group" "this" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "rg-ituru-test"
      + tags     = {
          + "CostCenter" = "psg2"
          + "owner"      = "ituru"
          + "period"     = "2022-03-31"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.


## apply
$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.this will be created
  + resource "azurerm_resource_group" "this" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "rg-ituru-test"
      + tags     = {
          + "CostCenter" = "psg2"
          + "owner"      = "ituru"
          + "period"     = "2022-03-31"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_resource_group.this: Creating...
azurerm_resource_group.this: Creation complete after 0s [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

terraform 実行後の確認

## 作成されたリソースグループの確認
$ az group show --name rg-ituru-test
{
  "id": "/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test",
  "location": "japaneast",
  "managedBy": null,
  "name": "rg-ituru-test",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": {
    "CostCenter": "psg2",
    "owner": "ituru",
    "period": "2022-03-31"
  },
  "type": "Microsoft.Resources/resourceGroups"
}


## tfstateファイルの確認
## コンテナー内の BLOB を一覧表示する
$ az storage blob list --account-name $STORAGE_TF_ACCOUNT --container-name $STORAGE_TF_CONTAINER --output table
Name                            Blob Type    Blob Tier    Length    Content Type      Last Modified              Snapshot
------------------------------  -----------  -----------  --------  ----------------  -------------------------  ----------
test01                          BlockBlob    Hot                                      2022-01-05T10:26:47+00:00
test01/terraform.tfstate        BlockBlob    Hot          1037      application/json  2022-01-05T10:38:36+00:00

ローカルの作業ディレクトの状況

$ tree -a         
.
├── .terraform
│   ├── providers
│   │   └── registry.terraform.io
│   │       └── hashicorp
│   │           └── azurerm
│   │               └── 2.88.1
│   │                   └── darwin_amd64
│   │                       └── terraform-provider-azurerm_v2.88.1_x5
│   └── terraform.tfstate
├── .terraform.lock.hcl
├── main.tf
├── terraform.tfvars
└── variables.tf

terraform による作成したリソースの削除

$ terraform destroy

azurerm_resource_group.this: Refreshing state... [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # azurerm_resource_group.this will be destroyed
  - resource "azurerm_resource_group" "this" {
      - id       = "/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test" -> null
      - location = "japaneast" -> null
      - name     = "rg-ituru-test" -> null
      - tags     = {
          - "CostCenter" = "psg2"
          - "owner"      = "ituru"
          - "period"     = "2022-03-31"
        } -> null
    }

Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

azurerm_resource_group.this: Destroying... [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test]
azurerm_resource_group.this: Still destroying... [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test, 10s elapsed]
azurerm_resource_group.this: Destruction complete after 15s

Destroy complete! Resources: 1 destroyed.
$ az group show --name rg-ituru-test
(ResourceGroupNotFound) Resource group 'rg-ituru-test' could not be found.

$ az storage blob list --account-name $STORAGE_TF_ACCOUNT --container-name $STORAGE_TF_CONTAINER --output table
Name                            Blob Type    Blob Tier    Length    Content Type      Last Modified              Snapshot
------------------------------  -----------  -----------  --------  ----------------  -------------------------  ----------
test01                          BlockBlob    Hot                                      2022-01-05T10:26:47+00:00
test01/terraform.tfstate        BlockBlob    Hot          156       application/json  2022-01-05T10:49:52+00:00

まとめ

これで、Terraform でAzure環境を構成できる準備が整いました。terraform の tfstateファイル は上記で作成したストレージアカウントのコンテナに保存されるようになります。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1