概要
「Infrastructure as Code」ということで、Terraform を用いて Azure Data Factory のデータセットまでの基盤を構築し、この記事 で作成した Azure Database for mysql を source に、Azure Blob を sink 等に指定できる準備をします。
ローカル環境
- macOS Monterey 12.3
- python 3.8.12
- Azure CLI 2.34.1
- terraform v1.0.11
前提条件
- Azure環境がすでに用意されていること(テナント/サブスクリプション)
- ローカル環境に「azure cli」がインストールされていること
- ローカル環境に「terraform」環境が構成されていること
- TerraformでAzure上に環境構築するためのサービスプリンシパルが作成されており、Terraform のためのローカル環境変数が定義されていること
事前準備
この記事 を実行し、Azure Database for mysql のデータベース「iotdummydb」が存在していること
Azure Data Factory の基盤を作成してみます
terraform 定義ファイルの作成
プロバイダの定義
# プロバイダーの定義
terraform {
required_providers {
azurerm = "~> 2.33"
}
}
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
}
パラメータ定義ファイル
# 環境変数(Azureサービスプリンシパル)
variable ARM_TENANT_ID {}
variable ARM_CLIENT_ID {}
variable ARM_CLIENT_SECRET {}
# タグ情報
variable tags_def {
default = {
owner = "ituru"
period = "2022-04-28"
CostCenter = "PSG2"
Environment = "Demo"
}
}
# 各種パラメータ
variable resource_group_name {}
variable region {}
variable datafactory_name {}
variable adf_linked_name {}
variable adf_linked_blob_name {}
variable adf_dataset_name {}
variable adf_dataset_blob_name {}
variable adf_table_name {}
variable storage_account_name {}
variable storage_container_name {}
# コネクション定義
variable connect_str01 {}
パラメータ値定義ファイル
# 環境変数の定義(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_adf01" // リソースグループ名
region = "japaneast" // 利用リージョン
datafactory_name = "ituru-adf01" // DataFactory名
adf_linked_name = "adf_link_mysql01" // ADF Linkサービス名(Source)
adf_dataset_name = "adf_dataset_mysql01" // ADF Dataset名(Source)
adf_linked_blob_name = "adf_link_blob01" // ADF Linkサービス名(Sink)
adf_dataset_blob_name = "adf_dataset_blob01" // ADF Dataset名(Sink)
adf_table_name = "inventory" // ADF Table名
storage_account_name = "ituruadfaccount" // ストレージアカウント名
storage_container_name = "bronze" // ストレージアカウント名
# コネクション定義
connect_str01 = "Server=iturumysql01.mysql.database.azure.com;Port=3306;Database=iotdummydb;User=mysqladmin@iturumysql01;SSLMode=1;UseSystemTrustStore=0;Password=NetworldPsg2!"
Azure Data Factory 定義ファイル
# Azure Data Factory
resource "azurerm_data_factory" "this" {
name = var.datafactory_name
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
}
# ADF Linked Service of MySQL
resource "azurerm_data_factory_linked_service_mysql" "this" {
name = var.adf_linked_name
data_factory_id = azurerm_data_factory.this.id
resource_group_name = azurerm_data_factory.this.resource_group_name
connection_string = var.connect_str01
}
# ADF Dataset of MySQL
resource "azurerm_data_factory_dataset_mysql" "this" {
name = var.adf_dataset_name
data_factory_id = azurerm_data_factory.this.id
resource_group_name = azurerm_data_factory.this.resource_group_name
linked_service_name = azurerm_data_factory_linked_service_mysql.this.name
table_name = try(var.adf_table_name, null)
}
# ADF Linked Service of BLOB
resource "azurerm_data_factory_linked_service_azure_blob_storage" "this" {
name = var.adf_linked_blob_name
data_factory_id = azurerm_data_factory.this.id
resource_group_name = azurerm_data_factory.this.resource_group_name
connection_string = azurerm_storage_account.this.primary_connection_string
}
# ADF Dataset of json(BLOB)
resource "azurerm_data_factory_dataset_json" "this" {
name = var.adf_dataset_blob_name
data_factory_id = azurerm_data_factory.this.id
resource_group_name = azurerm_data_factory.this.resource_group_name
linked_service_name = azurerm_data_factory_linked_service_azure_blob_storage.this.name
azure_blob_storage_location {
container = azurerm_storage_container.this.name
path = "foo/mysql/"
filename = "iotdummy01.json"
}
encoding = "UTF-8"
}
Azure Blob 定義ファイル
# ストレージアカウント
resource "azurerm_storage_account" "this" {
name = var.storage_account_name
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
account_tier = "Standard"
account_replication_type = "LRS"
tags = var.tags_def
}
# ストレージコンテナ_Bronze
resource "azurerm_storage_container" "this" {
name = var.storage_container_name
storage_account_name = azurerm_storage_account.this.name
container_access_type = "private"
}
terraform の実行
## init
$ terraform init
:
Terraform has been successfully initialized!
## plan
$ terraform plan
:
Plan: 8 to add, 0 to change, 0 to destroy.
## apply
$ terraform apply
:
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
ローカルの作業ディレクトの状況
$ tree -a
.
├── .terraform
│ └── providers
│ └── registry.terraform.io
│ └── hashicorp
│ └── azurerm
│ └── 2.99.0
│ └── darwin_amd64
│ └── terraform-provider-azurerm_v2.99.0_x5
├── .terraform.lock.hcl
├── blob.tf
├── datafactory.tf
├── main.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
└── variables.tf
terraform 実行後の確認
Azure CLI からの各種確認
## 作成先サブスクリプションへの接続
$ az account set --subscription '<Subscription_Name>'
## 作成した Data Factory の詳細表示
$ az datafactory list --resource-group rg_ituru_adf01
[
{
"additionalProperties": null,
"createTime": "2022-04-03T16:33:11.794778+00:00",
"eTag": "\"2b002b00-0000-0000-0000-47000470000\"",
"encryption": null,
"globalParameters": null,
"id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_adf01/providers/Microsoft.DataFactory/factories/ituru-adf01",
"identity": null,
"location": "japaneast",
"name": "ituru-adf01",
"provisioningState": "Succeeded",
"publicNetworkAccess": "Enabled",
"repoConfiguration": null,
"resourceGroup": "rg_ituru_adf01",
"tags": {},
"type": "Microsoft.DataFactory/factories",
"version": "2018-06-01"
}
]
## 上記のテーブル表示
$ az datafactory list --resource-group rg_ituru_adf01 -o table
CreateTime ETag Location Name ProvisioningState PublicNetworkAccess ResourceGroup Version
-------------------------------- -------------------------------------- ---------- ----------- ------------------- --------------------- --------------- ----------
2022-04-03T16:33:11.794778+00:00 "2b002b00-0000-0000-0000-47000470000" japaneast ituru-adf01 Succeeded Enabled rg_ituru_adf01 2018-06-01
## 作成した Data Factory の linked-service のリスト表示
$ az datafactory linked-service list --factory-name ituru-adf01 --resource-group rg_ituru_adf01 -o table
Name ResourceGroup
---------------- ---------------
adf_link_mysql01 rg_ituru_adf01
adf_link_blob01 rg_ituru_adf01
## 作成した Data Factory の dataset の一覧表示
$ az datafactory dataset list --factory-name ituru-adf01 --resource-group rg_ituru_adf01 -o table
Name ResourceGroup
------------------- ---------------
adf_dataset_mysql01 rg_ituru_adf01
adf_dataset_blob01 rg_ituru_adf01
## ストレージ・コンテナ情報の表示
$ az storage container list --account-name ituruadfaccount --output table
Name Lease Status Last Modified
------ -------------- -------------------------
bronze 2022-04-05T13:15:46+00:00
テスト接続NGの場合
Azure Data Factory から Azure Database for MySQL のテスト接続がうまくいかなかった場合、リソース:「Azure Database for MySQL」の画面の左側タグから「接続のセキュリティ」を選択し、新たに表示される画面の上部の「Azureサービスへのアクセス許可」を「はい」に設定します。
作成したリソースの削除
## destroy
$ terraform destroy --auto-approve
まとめ
このような感じで、Terraform でサクッと Azure Data Factory から Azure Database for MySQL や Azure BloB と会話できるベース構成を作成できました。 Azure Portal や Azure CLI で構築するのもいいですが、IaC化もいいですね。 が、pipeline や dataset を定義するのは GUI の方がベターかと、、、、、
確認したいこと
Azure Data Factory のGUIから Azure Database for MySQL の Link Service 作成するとき、そのリソースを選択できるが、Terraform で作成すると、単なる MySqlサーバ となっている。データは問題なく取得できているが気になります、、、、、