概要
「Infrastructure as Code」ということで、Terraform を用いて Azure Synapse Analytics を作成し、Synapse Studio に接続し SQLプール を確認してみます。
ローカル環境
- 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 Synapse Analytics を作成してみる
terraform 定義ファイルの作成
プロバイダの定義
# プロバイダーの定義
terraform {
required_providers {
azurerm = "~> 2.33"
}
}
provider "azurerm" {
features {}
tenant_id = var.ARM_TENANT_ID
subscription_id = var.ARM_SUBSCRIPTION_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_SUBSCRIPTION_ID {}
variable ARM_CLIENT_ID {}
variable ARM_CLIENT_SECRET {}
# タグ情報
variable tags_def {
default = {
owner = "ituru"
period = "2022-06-30"
Environment = "CP_Demo"
}
}
# 各種パラメータ
variable resource_group_name {}
variable region {}
variable storage_account {}
variable gen2_name {}
variable workspace_name {}
variable sql_pool_name {}
variable sql_admin {}
variable sql_admin_pass {}
variable fw_rule01 {}
variable home_tokyo_ip {}
variable fw_rule02 {}
variable hq_tokyo_ip {}
variable fw_rule03 {}
variable all_azure_ip {}
パラメータ値定義ファイル
# 環境変数の定義(Azureサービスプリンシパル)
ARM_TENANT_ID = "zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz"
ARM_SUBSCRIPTION_ID = "xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz"
ARM_CLIENT_ID = "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx"
ARM_CLIENT_SECRET = "hogehogehogehogehogehogehogehogege"
# パラメータ値の定義
resource_group_name = "rg_ituru_synapse01" // リソースグループ名
region = "japaneast" // 利用リージョン
storage_account = "iturusynapse" // ストレージアカウント名
gen2_name = "iturucpgen2" // Data Lake Gen2名
workspace_name = "cpworkspace01" // ワークスペース名
sql_pool_name = "cpdemosqldb" // SQL Pool名
sql_admin = "adminadmin" // Synapse管理者名
sql_admin_pass = "HogeHogeHoge1!" // Synapse管理者パスワード
fw_rule01 = "Home_Tokyo" // Firewallルール名_01
home_tokyo_ip = "133.133.133.133" // 東京宅のIPアドレス
fw_rule02 = "HQ_Tokyo" // Firewallルール名_02
hq_tokyo_ip = "155.155.155.155" // 本社のIPアドレス
fw_rule03 = "AllowAllWindowsAzureIps" // Firewallルール名_03
all_azure_ip = "0.0.0.0" // AzureのIPアドレス
Synapse定義ファイル
# Storage Account
resource "azurerm_storage_account" "this" {
name = var.storage_account
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
tags = var.tags_def
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
is_hns_enabled = "true"
}
# Data Lake Gen2
resource "azurerm_storage_data_lake_gen2_filesystem" "this" {
name = var.gen2_name
storage_account_id = azurerm_storage_account.this.id
}
# Synapse Analytics Workspace
resource "azurerm_synapse_workspace" "this" {
name = var.workspace_name
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
storage_data_lake_gen2_filesystem_id = azurerm_storage_data_lake_gen2_filesystem.this.id
sql_administrator_login = var.sql_admin
sql_administrator_login_password = var.sql_admin_pass
tags = var.tags_def
}
# Synapse Analytics SQL Pool
resource "azurerm_synapse_sql_pool" "this" {
name = var.sql_pool_name
synapse_workspace_id = azurerm_synapse_workspace.this.id
sku_name = "DW100c"
create_mode = "Default"
collation = "Japanese_CI_AS"
tags = var.tags_def
}
# Manages a Firewall Rule for Synapse Analytics
resource "azurerm_synapse_firewall_rule" "rule01" {
name = var.fw_rule01
synapse_workspace_id = azurerm_synapse_workspace.this.id
start_ip_address = var.home_tokyo_ip
end_ip_address = var.home_tokyo_ip
}
resource "azurerm_synapse_firewall_rule" "rule02" {
name = var.fw_rule02
synapse_workspace_id = azurerm_synapse_workspace.this.id
start_ip_address = var.hq_tokyo_ip
end_ip_address = var.hq_tokyo_ip
}
resource "azurerm_synapse_firewall_rule" "rule03" {
name = var.fw_rule03
synapse_workspace_id = azurerm_synapse_workspace.this.id
start_ip_address = var.all_azure_ip
end_ip_address = var.all_azure_ip
}
## storage account への roleの割当
data "azurerm_client_config" "current" {}
resource "azurerm_role_assignment" "assign01" {
scope = azurerm_storage_account.this.id
role_definition_name = "Storage Blob Data Contributor"
principal_id = data.azurerm_client_config.current.object_id
}
resource "azurerm_role_assignment" "assign02" {
scope = azurerm_storage_account.this.id
role_definition_name = "Storage Blob Data Contributor"
principal_id = azurerm_synapse_workspace.this.identity[0].principal_id
}
terraform の実行
## init
$ terraform init
:
Terraform has been successfully initialized!
## plan
$ terraform plan
:
Plan: 10 to add, 0 to change, 0 to destroy.
## apply
$ terraform apply
:
Apply complete! Resources: 10 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
├── Synapse.tf
├── main.tf
├── outputs.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
└── variables.tf
terraform 実行後の確認
Azure CLI からの確認
## 作成先サブスクリプションへの接続
$ az account set --subscription '<Subscription_Name>'
## 作成した Synapse Workspace の確認
$ az synapse workspace list --resource-group rg_ituru_synapse01 -o table
Location ManagedResourceGroupName Name ProvisioningState PublicNetworkAccess ResourceGroup SqlAdministratorLogin WorkspaceUid
---------- --------------------------------------------------------------- ------------- ------------------- --------------------- ------------------ ----------------------- ------------------------------------
japaneast synapseworkspace-managedrg-ae333c64-00dd-469f-b06a-0495ac3619e2 cpworkspace01 Succeeded Enabled rg_ituru_synapse01 adminadmin 478d9805-2f84-438b-85c8-0738cecfa3b9
## 作成した Synapse Sql Pool の確認
$ az synapse sql pool list --resource-group rg_ituru_synapse01 --workspace-name cpworkspace01
[
{
"collation": "Japanese_CI_AS",
"createMode": null,
"creationDate": "2022-05-19T23:57:36.547000+00:00",
"id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_synapse01/providers/Microsoft.Synapse/workspaces/cpworkspace01/sqlPools/cpsqlpool01",
"location": "japaneast",
"maxSizeBytes": 263882790666240,
"name": "cpsqlpool01",
"provisioningState": "Succeeded",
"recoverableDatabaseId": null,
"resourceGroup": "rg_ituru_synapse01",
"restorePointInTime": null,
"sku": {
"capacity": 0,
"name": "DW100c",
"tier": null
},
"sourceDatabaseDeletionDate": null,
"sourceDatabaseId": null,
"status": "Online",
"storageAccountType": "GRS",
"tags": {},
"type": "Microsoft.Synapse/workspaces/sqlPools"
}
]
## Firewallルール一覧表示
$ az synapse workspace firewall-rule list --resource-group rg_ituru_synapse01 --workspace-name cpworkspace01
[
{
"endIpAddress": "0.0.0.0",
"id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_synapse01/providers/Microsoft.Synapse/workspaces/cpworkspace01/firewallRules/AllowAllWindowsAzureIps",
"name": "AllowAllWindowsAzureIps",
"provisioningState": "Succeeded",
"resourceGroup": "rg_ituru_synapse01",
"startIpAddress": "0.0.0.0",
"type": "Microsoft.Synapse/workspaces/firewallRules"
},
{
"endIpAddress": "133.133.133.133",
"id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_synapse01/providers/Microsoft.Synapse/workspaces/cpworkspace01/firewallRules/Home_Tokyo",
"name": "Home_Tokyo",
"provisioningState": "Succeeded",
"resourceGroup": "rg_ituru_synapse01",
"startIpAddress": "133.133.133.133",
"type": "Microsoft.Synapse/workspaces/firewallRules"
},
{
"endIpAddress": "155.155.155.155",
"id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_synapse01/providers/Microsoft.Synapse/workspaces/cpworkspace01/firewallRules/HQ_Tokyo",
"name": "HQ_Tokyo",
"provisioningState": "Succeeded",
"resourceGroup": "rg_ituru_synapse01",
"startIpAddress": "155.155.155.155",
"type": "Microsoft.Synapse/workspaces/firewallRules"
}
]
Synapse Studio への接続
Azure Portal へサインインし、上記で作成した Synapse Workspace リソースの 「概要」の画面にある「作業の開始」から「Synapse Studio を開く」を押します。
新たに Synapse Studio の画面が表示されるときに、ポップアップの「読み込めませんでした」エラー画面されます。画面左の「管理」アイコンを選択すると、切り替わった画面上部に「サーバーレス SQL プール (組み込み) へのアクセス権がありません。アクセス権を取得するには、このワークスペースの Synapse 管理者にお問い合わせください」との警告メッセージが表示されます。
正常に Azure Studio を利用するために、Synapse管理者として、Azure Portal にサインインしている自分自身を登録する必要がありますので、画面左の「セキュリティ」-「アクセス制御」を選択し、自身を Synapse管理者 として追加します。
追加後、約3〜5分後に Azure Workplace と Terraformサービスプリンシパル と合わせて Synapse管理者としてアクセス権が付与されたことを確認できます。また、画面上部に表示されていた警告メッセージが消えます。
Synapse Studio の画面左側の「セキュリティ」-「資格情報」を選択することにより資格情報を確認することもできます。
SQLプールの確認
Synapse Studio の画面左側の「Analyticsプール」-「SQLプール」を選択することにより、組み込みのSQLプールと作成したSQLプールがオンラインになっていることを確認できます。
その他
Terraformサービスプリンシパルへの権限追加
本件では、作成するストレージアカウントに、追加で「ストレージBLOB共同作成者」のロールの割当が必要となるため、Terraformサービスプリンシパルに「所有者」の権限を付与しました。
## 必要なスコープに必要なロールを割り与えるための appId の取得
$ APP_ID=$(az ad sp list --display-name sp_itutu_terraform --query '[].{ID:appId}' --output tsv)
## 必要なスコープに必要なロールを割り与えるための サブスクリプションID の取得
$ SUBS_ID=$(az account show --query "id" --output tsv)
## 必要なスコープに必要なロールの割当て
$ az role assignment create --assignee $APP_ID --scope /subscriptions/$SUBS_ID --role Owner
作成したリソースの削除
## destroy
$ terraform destroy
まとめ
これで、Terraform でサクッと Azure環境上に Azure Synapse Analytics を作成できました。 Synapse Studio のポップアップのエラーをなくすために少々てこずりましたが、半IaC化もいいですね。
参考記事
以下の記事を参考にさせていただきました。
azurerm_synapse_sql_pool
azurerm_synapse_firewall_rule
az synapse
ワークスペースのマネージド ID にアクセス許可を付与する