TerraformがAzure Stack Providerをリリースしたので試しました。
We've just released a new @HashICorp #Terraform Provider for @Azure Stack: https://t.co/twYuFQcBra #Azure
— Tom Harvey 🇩🇪 (@tombuildsstuff) 2018年6月20日
なお、TerraformのAzure Stack対応はAzureと異なるProviderとして実装されました。そのため、Azureで利用しているtfファイルをそのまま利用できません。tfファイルの内容を置換する必要があります。AnsibleのようなAzureで利用しているコードをそのまま利用できる実装方式にしてほしかった。AnsibleのAzure Stack対応は、Azureモジュールを使う際の環境変数AZURE_CLOUD_ENVIRONMENTにAzure StackのAPIエンドポイントを格納する形です。
環境
- Azure Stack:ASDK 1.0.180513.1
- PowerShell: Azure Stack Admin 1.3.0
- Terraform: Terraform v0.11.7 + provider.azurestack v0.1.0
やってみた
まずはTerraformが利用するサービスプリンシパルを作ります。Cloud Shellを利用して、Azure Stackにログインするときに利用するAzure Active Directoryに、サービスプリンシパルを作成します。
~$ az ad sp create-for-rbac --name AzsTerraform --password PASSWORD
Retrying role assignment creation: 1/36
Retrying role assignment creation: 2/36
{
"appId": "appId",
"displayName": "AzsTerraform",
"name": "http://AzsTerraform",
"password": "PASSWORD",
"tenant": "tenant"
}
作成したサービスプリンシパルをAzure StackのサブスクリプションにOwner権限で追加します。Contributor権限だとTerraformがエラーになりました。なぜだろう。
PS C:\Users\AzureStackAdmin\Documents> Get-AzureRmRoleAssignment
RoleAssignmentId : /subscriptions/1cbd8150-0f4f-4815-89e8-fb34b865a628/providers/Microsoft.Authorization/roleAssignme
nts/a25a046c-dab9-4951-9a00-9434aac9baab
Scope : /subscriptions/1cbd8150-0f4f-4815-89e8-fb34b865a628
DisplayName : AzsTerraform
SignInName :
RoleDefinitionName : Owner
RoleDefinitionId : 8e3af657-a8ff-443c-a75c-2fe8c4bcb635
ObjectId : f6a96431-8336-4539-9fd9-7f1879019e08
ObjectType : ServicePrincipal
Azure Stackのテナント領域にPowerShellで接続して、リソースグループを作ります。
PS C:\Users\AzureStackAdmin\Documents> $ArmEndpoint = "https://management.local.azurestack.external"
PS C:\Users\AzureStackAdmin\Documents> Add-AzureRMEnvironment -Name "AzureStackUser" -ArmEndpoint $ArmEndpoint
PS C:\Users\AzureStackAdmin\Documents> Login-AzureRmAccount -EnvironmentName "AzureStackUser" `
PS C:\Users\AzureStackAdmin\Documents> New-AzureRmResourceGroup -Name azsterraform -Location local
tfファイルを作ります。providerの部分には、RBACに登録したサービスプリンシパルの情報を追記します。ご利用のAzure Stackにあわせてarm_endpointを変更してください。
provider "azurestack" {
arm_endpoint = "https://management.local.azurestack.external"
subscription_id = "subscription_id"
client_id = "client_id"
client_secret = "client_secret"
tenant_id = "tenant_id"
}
tfファイルにリソースを追記します。基本的な記法はAzureと同じです。“azure_“ではなく"azurestack_“になったのが本当に惜しい。
resource "azurestack_resource_group" "test" {
name = "azsterraform"
location = "local"
}
resource "azurestack_virtual_network" "test" {
name = "acctvn"
address_space = ["10.0.0.0/16"]
location = "${azurestack_resource_group.test.location}"
resource_group_name = "${azurestack_resource_group.test.name}"
}
resource "azurestack_subnet" "test" {
name = "acctsub"
resource_group_name = "${azurestack_resource_group.test.name}"
virtual_network_name = "${azurestack_virtual_network.test.name}"
address_prefix = "10.0.2.0/24"
}
resource "azurestack_network_interface" "test" {
name = "acctni"
location = "${azurestack_resource_group.test.location}"
resource_group_name = "${azurestack_resource_group.test.name}"
ip_configuration {
name = "testconfiguration1"
subnet_id = "${azurestack_subnet.test.id}"
private_ip_address_allocation = "dynamic"
}
}
resource "azurestack_storage_account" "test" {
name = "accsa"
resource_group_name = "${azurestack_resource_group.test.name}"
location = "${azurestack_resource_group.test.location}"
account_tier = "Standard"
account_replication_type = "LRS"
tags {
environment = "staging"
}
}
resource "azurestack_storage_container" "test" {
name = "vhds"
resource_group_name = "${azurestack_resource_group.test.name}"
storage_account_name = "${azurestack_storage_account.test.name}"
container_access_type = "private"
}
resource "azurestack_virtual_machine" "test" {
name = "acctvm"
location = "${azurestack_resource_group.test.location}"
resource_group_name = "${azurestack_resource_group.test.name}"
network_interface_ids = ["${azurestack_network_interface.test.id}"]
vm_size = "Standard_F2"
storage_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2016-Datacenter"
version = "latest"
}
storage_os_disk {
name = "myosdisk1"
vhd_uri = "${azurestack_storage_account.test.primary_blob_endpoint}${azurestack_storage_container.test.name}/myosdisk1.vhd"
caching = "ReadWrite"
create_option = "FromImage"
}
# Optional data disks
storage_data_disk {
name = "datadisk0"
vhd_uri = "${azurestack_storage_account.test.primary_blob_endpoint}${azurestack_storage_container.test.name}/datadisk0.vhd"
disk_size_gb = "1023"
create_option = "Empty"
lun = 0
}
os_profile {
computer_name = "hostname"
admin_username = "testadmin"
admin_password = "Password1234!"
}
os_profile_windows_config {
provision_vm_agent = true
}
tags {
environment = "staging"
}
}
“terraform init"してAzure Stack Providerをインストールします。
PS C:\Users\AzureStackAdmin\Documents> .\terraform.exe init
“terraform plan"でDry-runしたうえで、“terraform apply"します
PS C:\Users\AzureStackAdmin\Documents> .\terraform.exe plan
(中略)
PS C:\Users\AzureStackAdmin\Documents> .\terraform.exe apply
(中略)
Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
Virtual Machineができました。tfファイルの書き方がほんの少し違いますが、Azure Providerを同じ使い勝手でVirtual Machineを作れました。
PS C:\Users\AzureStackAdmin\Documents> Get-AzureRmVM | ft
ResourceGroupName Name Location VmSize OsType NIC ProvisioningState
----------------- ---- -------- ------ ------ --- -----------------
AZSTERRAFORM acctvm local Standard_F2 Windows acctni Succeeded