背景
クラウドコンピューティングの分野において、AWS と GCP に並ぶ存在として Azure が注目されています。Azure は多様なサービスを提供し、Azure DevOps や Azure Synapse など、AWS や GCP とは異なるツールやサービスがあります。それぞれのサービスごとに、ヘッダーや構成などにも違いがあり、AWS や GCP と比べると微妙に仕様が異なります。
このような状況の中で、Azure の導入にあたり、開発や管理のコストを効果的に削減するためには、Infrastructure as Code (IaC) の導入が有効です。特に、Azure 環境のインフラストラクチャをコードで管理する手段として、Terraform の導入が注目されています。Terraform を利用することで、Azure のリソースを効率的かつ再現性の高い方法で構築、管理することが可能となります。今回はそういったterraformの導入方法をまとめたいと思います。
設計
リポジトリ | Azure DevOps Repos | Cloud Source Repositories | AWS CodeCommit |
cicd | Azure DevOps Pipelines | Cloud Build | AWS CodeBuild + AWS CodePipeline |
terraform 実行権限主体 | Azureアプリ | GCP Service Account | AWS IAM role |
state管理場所 | Azure Storage Account (container) | Cloud Storage | AWS S3 |
環境構築 | terraform | terraform | terraform |
図1:Blob (オブジェクト) Storage の概要 – Azure Storage | Microsoft Docs
構成を考える上で気になった点は以下の内容である。
- AWS・GCPとStorageの概念が違い、ストレージアカウント配下にファイル以外にキューなど様々なものが紐づいて管理ができる
- リポジトリや実行環境はAWS・GCPと同様Azure DevOpsというサービスにまとまっている
- Azure Resource ManagerというAzure内部に管理サービスを持っており、Azureだけを利用する場合はterraformより優れいてる面もありそうだった
手順
storage周りの準備
tfstateを管理するstarage周りは先に手動で準備しておく必要があるので、 resource group・strage account・storage containerの3つをコンソールや以下コマンドで準備しておきます。
$ az login
$ az group create --name {RESOURCE_GROUP_NAME} --location japaneast
$ az storage account create --resource-group {RESOURCE_GROUP_NAME} --name {STORAGE_ACCOUNT_NAME} --sku Standard_LRS --encryption-services blob
$ account_key=$(az storage account keys list --resource-group {RESOURCE_GROUP_NAME} --account-name {STORAGE_ACCOUNT_NAME} --query '[0].value' -o tsv)
$ az storage container create --name {CONTAINER_NAME} --account-name {STORAGE_ACCOUNT_NAME} --account-key $account_key
$ az storage container list --account-name {STORAGE_ACCOUNT_NAME} --account-key $account_key --output table
terraform用のアカウント準備
図2:Azure構成概略図
- Microsoft Entraセンターの「アプリケーション>アプリの登録」よりterraformで利用するアプリの新規登録を行う
- 概要に記載のある「アプリケーション (クライアント) ID」「ディレクトリ (テナント) ID」をメモしておく
- 「証明書とシークレット>クライアントシークレット>新しいクライアントシークレット」よりシークレットを作成し、「クライアントシークレット」をメモしておく
- サブスクリプションより契約中のプランを選択し、「アクセス制御(IAM)>ロールの割り当て>ロールの割り当ての追加」より作成したアプリにロールを追加する。
- 契約中プランの「サブスクリプションID」をメモしておく
Azure DevOps周りの準備
図3:Azure構成概略図
- Azure DevOps Reposでリポジトリの作成
- Azure DevOps Pipelinesにてリポジトリを接続し、
azure-pipelines.yml
をリポジトリのルートフォルダに作成
リポジトリの中身
azure-pipelines.yml
:Azure DevOps Pipelineの実行内容を管理- /tf:terraformファイルを格納するフォルダ
├── azure-pipelines.yml
└── tf
├── backend.tf
└── variables.tf
azure-pipelines.yml
の中身
- Azure DevOps Pipeline のライブラリを利用
- 不要なシークレット払い出しを避けるためAzure DevOpsのService Connectionの利用を推奨している記事も多いですが、terraformの場合はこの認証方法が利用できないため注意が必要です
##[error]Terraform backend initialization for AzureRM only support service principal authorization
というエラーが発生する- AWS・GCPではサービスに対しては類似の方法ができるため、別の問題でできていない可能性はあります
- 環境変数にてメモしていたARM_SUBSCRIPTION_ID・ARM_CLIENT_ID・ARM_TENANT_ID・ARM_CLIENT_SECRETを渡すことで認証を通しています
The subscription is not registered to use namespace 'Microsoft.Synapse'
といったエラーが出ることがあり、リソース プロバイダーの登録エラーの解決が必要な場合があります
trigger:
- main
variables:
- group: sandbox-azure-sinkcapital
- name: TerraformVersion
value: '1.7.5'
- name: terraformWorkingDirectory
value: 'tf'
steps:
- task: JasonBJohnson.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-installer.TerraformInstaller@0
displayName: 'Install Terraform'
inputs:
terraformVersion: $(terraformVersion)
- task: TerraformCLI@0
displayName: 'Terraform Version'
inputs:
command: 'version'
# - task: TerraformCLI@0
# displayName: 'Terraform Format'
# inputs:
# workingDirectory: $(terraformWorkingDirectory)
# command: 'fmt'
# commandOptions: '-recursive'
- task: TerraformCLI@0
displayName: 'Run terraform init'
inputs:
workingDirectory: $(terraformWorkingDirectory)
command: 'init'
env:
ARM_SUBSCRIPTION_ID: $(azure_subscription_id)
ARM_CLIENT_ID: $(azure_client_id)
ARM_TENANT_ID: $(azure_tenant_id)
ARM_CLIENT_SECRET: $(azure_client_secret)
# - task: TerraformCLI@0
# displayName: 'Run terraform plan'
# inputs:
# command: plan
# workingDirectory: $(terraformWorkingDirectory)
# env:
# ARM_SUBSCRIPTION_ID: $(azure_subscription_id)
# ARM_CLIENT_ID: $(azure_client_id)
# ARM_TENANT_ID: $(azure_tenant_id)
# ARM_CLIENT_SECRET: $(azure_client_secret)
- task: TerraformCLI@0
displayName: 'Run terraform apply'
inputs:
workingDirectory: $(terraformWorkingDirectory)
command: apply
env:
ARM_SUBSCRIPTION_ID: $(azure_subscription_id)
ARM_CLIENT_ID: $(azure_client_id)
ARM_TENANT_ID: $(azure_tenant_id)
ARM_CLIENT_SECRET: $(azure_client_secret)
backend.tf
の中身
- 「storage周りの準備」にて指定したストレージ情報を記載する
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.95.0"
}
}
backend azurerm {
resource_group_name = "{RESOURCE_GROUP_NAME}"
storage_account_name = "{STORAGE_ACCOUNT_NAME}"
container_name = "{CONTAINER_NAME}"
key = "terraform.tfstate"
}
}
provider azurerm {
skip_provider_registration = true
features {}
}
感想
今回Azureにてterraform環境を整えましたが、AWS・GCPとはstorageや権限の概念が異なり最初の設定が少し難しかった印象です。 ただterrraformを利用しているので一通り実行できるようになった後は他クラウドと変わらず開発が行えました。 AzureはExcelなどMicrosft製品との連携が強く、今後Microsft製品を多く利用される環境にて導入を進めさせていただければと思います。