🐉

TerraformerではじめるAzure IaC

2022/02/28に公開

はじめに

みなさん、IaCやってますか?
IaCがもたらす恩恵は多岐に渡り、単なる効率化に止まらず、私たちの開発者体験を向上させてくれます。
一方でうまく使いこなせないと、IaCの恩恵を受けられないだけでなく、かえって疲弊してしまいます。
(IaCについてはどこかでしっかり書きたいな)

理想は開発の初期段階からIaCを導入していることですが、なかなかそうもいきませんよね。
参画したプロジェクトがIaCを導入していないこともあると思います。
既存のリソースからコードに落とし込んでくれるツールがあったら便利だと思いませんか?

それを実現できるツールがTerraformerになります。
今回はTerraformerを使い始めるまでを簡単にまとめてみました。
※本記事はAzureの利用前提で話を進めます。

Terraformerとは

Terraformerは、既存のインフラストラクチャからTerraformコードを生成してくれるツールになります。
https://github.com/GoogleCloudPlatform/terraformer

動作環境

  • Ubuntu: 18.04
  • azure-cli: 2.28.0
  • tfenv: 2.2.3
  • Terraform: v1.1.5 on linux_amd64

導入手順

Azure環境構築

まずはAzureのリソースを使って検証のための環境を用意します。
(ローカル環境は整理されておらず、ごちゃごちゃしているので真っ新な環境で検証します)

まずはAzure CLIを使ってログインしましょう。GUIでアクセスできない人は--use-device-codeオプションとか使うと便利です。

az login

次にリソースグループを作成します。名前やロケーションは好きなもので大丈夫です。

❯❯❯ az group create -n rg-terraformer -l japaneast       
{
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg-terraformer",
  "location": "japaneast",
  "managedBy": null,
  "name": "rg-terraformer",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}

VMに使用するイメージ確認を確認します。
UbuntuLTSのような一般的なイメージには短縮版であるUrnAliasというものが割り当てられています。これを使用するとCLIからでも簡単にVMを作成できてしまいます。

❯❯❯ az vm image list -f ubuntu -otable  
You are viewing an offline list of images, use --all to retrieve an up-to-date list
Offer         Publisher    Sku        Urn                                      UrnAlias    Version
------------  -----------  ---------  ---------------------------------------  ----------  ---------
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:latest  UbuntuLTS   latest

VMのサイズも大切ですね。ちょっとした検証ではいつもBシリーズを使用しています。

❯❯❯ az vm list-sizes -l japaneast --query "[?contains(name,'Standard_B')]" -otable 
Name            NumberOfCores    OsDiskSizeInMb    ResourceDiskSizeInMb    MemoryInMb    MaxDataDiskCount
--------------  ---------------  ----------------  ----------------------  ------------  ------------------
Standard_B1ls   1                1047552           4096                    512           2
Standard_B1ms   1                1047552           4096                    2048          2
Standard_B1s    1                1047552           4096                    1024          2
Standard_B2ms   2                1047552           16384                   8192          4
Standard_B2s    2                1047552           8192                    4096          4
Standard_B4ms   4                1047552           32768                   16384         8
Standard_B8ms   8                1047552           65536                   32768         16
Standard_B12ms  12               1047552           98304                   49152         16
Standard_B16ms  16               1047552           131072                  65536         32
Standard_B20ms  20               1047552           163840                  81920         32

早速VMを作っていきましょう(※警告は一旦無視します)

❯❯❯ az vm create -n vm-terraformer -g rg-terraformer --image UbuntuLTS --size Standard_B2s --admin-username tfadmin --generate-ssh-keys 
It is recommended to use parameter "--public-ip-sku Standard" to create new VM with Standard public IP. Please note that the default public IP used for VM creation will be changed from Basic to Standard in the future.
{
  "fqdns": "",
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg-terraformer/providers/Microsoft.Compute/virtualMachines/vm-terraformer",
  "location": "japaneast",
  "macAddress": "00-0D-3A-CC-E6-89",
  "powerState": "VM running",
  "privateIpAddress": "10.0.0.4",
  "publicIpAddress": "20.89.89.152",
  "resourceGroup": "rg-terraformer",
  "zones": ""
}

作成したVMに入って作業をしていきます。

❯❯❯ set VM_GIP (az vm list-ip-addresses --query '[].virtualMachine.{name: name, gip: network.publicIpAddresses[0].ipAddress}' -o tsv | grep terraformer | awk '{print $2}')   

❯❯❯ echo $VM_GIP     
20.89.89.152

# userはVM作成時に指定済み
❯❯❯ ssh tfadmin@$VM_GIP 
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1067-azure x86_64)
...
tfadmin@vm-terraformer:~$

Terraformのインストール

tfenvを使ってterraformをインストールしていきます。
githubのManual手順に従います。
https://github.com/tfutils/tfenv

tfadmin@vm-terraformer:~$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
Cloning into '/home/tfadmin/.tfenv'...
remote: Enumerating objects: 1569, done.
remote: Counting objects: 100% (384/384), done.
remote: Compressing objects: 100% (150/150), done.
remote: Total 1569 (delta 240), reused 344 (delta 220), pack-reused 1185
Receiving objects: 100% (1569/1569), 337.44 KiB | 11.64 MiB/s, done.
Resolving deltas: 100% (1003/1003), done.

echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
tfadmin@vm-terraformer:~$ source ~/.bash_profile
tfadmin@vm-terraformer:~$ which tfenv
/home/tfadmin/.tfenv/bin/tfenv

インストール可能なバージョンを確認します。

tfadmin@vm-terraformer:~$ tfenv list-remote | head -5
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
tfadmin@vm-terraformer:~$

とりあえず1.1.5をいれてみます。

tfadmin@vm-terraformer:~$ tfenv install 1.1.5
Installing Terraform v1.1.5
Downloading release tarball from https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_linux_amd64.zip
##################################################################################################################################################################################################### 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_SHA256SUMS
No keybase install found, skipping OpenPGP signature verification
/home/tfadmin/.tfenv/libexec/tfenv-install: line 270: unzip: command not found
Tarball unzip failed

unzipがないと言われたのでapt installを行います。

sudo apt update && sudo apt install zip
tfadmin@vm-terraformer:~$ which zip
/usr/bin/zip
tfadmin@vm-terraformer:~$

再トライでうまくいきました。

tfadmin@vm-terraformer:~$ tfenv install 1.1.5
Installing Terraform v1.1.5
Downloading release tarball from https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_linux_amd64.zip
##################################################################################################################################################################################################### 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_SHA256SUMS
No keybase install found, skipping OpenPGP signature verification
Archive:  /tmp/tfenv_download.c9kBsb/terraform_1.1.5_linux_amd64.zip
  inflating: /home/tfadmin/.tfenv/versions/1.1.5/terraform
Installation of terraform v1.1.5 successful. To make this your default version, run 'tfenv use 1.1.5'
tfadmin@vm-terraformer:~$ tfenv use 1.1.5
Switching default version to v1.1.5
Switching completed
tfadmin@vm-terraformer:~$ terraform version
Terraform v1.1.5
on linux_amd64

Your version of Terraform is out of date! The latest version
is 1.1.6. You can update by downloading from https://www.terraform.io/downloads.html
tfadmin@vm-terraformer:~$ which terraform
/home/tfadmin/.tfenv/bin/terraform
tfadmin@vm-terraformer:~$

Azure CLIのインストール

terraformerを使う上で必要になるのでインストールします。
下記を参考に行いました。
https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-linux?pivots=apt

1コマンドでインストールできるのは便利ですね。

tfadmin@vm-terraformer:~$ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
Hit:1 http://azure.archive.ubuntu.com/ubuntu bionic InRelease
#長いので省略
Setting up azure-cli (2.33.1-1~bionic) ...

tfadmin@vm-terraformer:~$ which az
/usr/bin/az

tfadmin@vm-terraformer:~$ az version
{
  "azure-cli": "2.33.1",
  "azure-cli-core": "2.33.1",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {}
}

Terraformerのインストール

公式のインストール手順にしたがいます。
https://github.com/GoogleCloudPlatform/terraformer#installation

tfadmin@vm-terraformer:~$ export PROVIDER=azure
tfadmin@vm-terraformer:~$ curl -LO https://github.com/GoogleCloudPlatform/terraformer/releases/download/$(curl -s https://api.github.com/repos/GoogleCloudPlatform/terraformer/releases/latest | grep tag_name | cut -d '"' -f 4)/terraformer-${PROVIDER}-linux-amd64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   668  100   668    0     0   2640      0 --:--:-- --:--:-- --:--:--  2640
100 71.9M  100 71.9M    0     0  10.9M      0  0:00:06  0:00:06 --:--:-- 13.2M
tfadmin@vm-terraformer:~$ chmod +x terraformer-${PROVIDER}-linux-amd64

tfadmin@vm-terraformer:~$ sudo mv terraformer-${PROVIDER}-linux-amd64 /usr/local/bin/terraformer

tfadmin@vm-terraformer:~$ terraformer version
Terraformer v0.8.18
tfadmin@vm-terraformer:~$ which terraformer
/usr/local/bin/terraformer

Terraformerの利用

とりあえず公式手順に記載されているコマンドを実行してみます。

tfadmin@vm-terraformer:~$ terraformer import azure -r resource_group --filter=resource_group=/subscriptions/$ARM_SUBSCRIPTION_ID/resourceGroups/rg-terraformer
2022/02/21 14:51:01 Testing if Service Principal / Client Certificate is applicable for Authentication..
2022/02/21 14:51:01 Testing if Multi Tenant Service Principal / Client Secret is applicable for Authentication..
2022/02/21 14:51:01 Testing if Service Principal / Client Secret is applicable for Authentication..
2022/02/21 14:51:01 Testing if Managed Service Identity is applicable for Authentication..
2022/02/21 14:51:01 Testing if Obtaining a token from the Azure CLI is applicable for Authentication..
2022/02/21 14:51:01 Using Obtaining a token from the Azure CLI for Authentication
2022/02/21 14:51:01 An Azure Environment with name "" was not found: autorest/azure: There is no cloud environment matching the name "AZURECLOUD"

Azure CLIは最新バージョンだとTerraformerがうまく動作しないようなのでversion 2.28にダウングレードします。
ダウングレードの方法も下記ページに記載ありました。
https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-linux?pivots=apt#install-specific-version

tfadmin@vm-terraformer:~$ sudo apt-get update
Hit:1 http://azure.archive.ubuntu.com/ubuntu bionic InRelease
#長いので省略
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
tfadmin@vm-terraformer:~$ curl -sL https://packages.microsoft.com/keys/microsoft.asc |
>     gpg --dearmor |
>     sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null
tfadmin@vm-terraformer:~$ AZ_REPO=$(lsb_release -cs)
tfadmin@vm-terraformer:~$ echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" |
>     sudo tee /etc/apt/sources.list.d/azure-cli.list
deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ bionic main
tfadmin@vm-terraformer:~$ sudo apt-get update
Reading package lists... Done

tfadmin@vm-terraformer:~$ apt-cache policy azure-cli | grep 2.28
  Installed: 2.28.0-1~bionic
 *** 2.28.0-1~bionic 500

azure-cli 2.28をインストールします。

tfadmin@vm-terraformer:~$ sudo apt-get install azure-cli=2.28.0-1~bionic
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be DOWNGRADED:
  azure-cli
0 upgraded, 0 newly installed, 1 downgraded, 0 to remove and 4 not upgraded.
Need to get 63.7 MB of archives.
After this operation, 72.0 MB disk space will be freed.
Do you want to continue? [Y/n] Y
Get:1 https://packages.microsoft.com/repos/azure-cli bionic/main amd64 azure-cli all 2.28.0-1~bionic [63.7 MB]
Fetched 63.7 MB in 2s (27.2 MB/s)
dpkg: warning: downgrading azure-cli from 2.33.1-1~bionic to 2.28.0-1~bionic
(Reading database ... 141421 files and directories currently installed.)
Preparing to unpack .../azure-cli_2.28.0-1~bionic_all.deb ...
Unpacking azure-cli (2.28.0-1~bionic) over (2.33.1-1~bionic) ...
Setting up azure-cli (2.28.0-1~bionic) ...

ダウングレードした後は再度az loginが必要です。

tfadmin@vm-terraformer:~$ az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code HM437JA5E to authenticate.
[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
    "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "isDefault": true,
    "managedByTenants": [],
    "name": "PCZXXXX",
    "state": "Enabled",
    "tenantId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
    "user": {
      "name": "<user_name>",
      "type": "user"
    }
  }
]

もう一度terraformer importを実行してみます。

tfadmin@vm-terraformer:~$ terraformer import azure -r resource_group --filter=resource_group=/subscriptions/$ARM_SUBSCRIPTION_ID/resourceGroups/rg-terraformer
2022/02/21 17:32:55 Testing if Service Principal / Client Certificate is applicable for Authentication..
2022/02/21 17:32:55 Testing if Multi Tenant Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:32:55 Testing if Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:32:55 Testing if Managed Service Identity is applicable for Authentication..
2022/02/21 17:32:55 Testing if Obtaining a token from the Azure CLI is applicable for Authentication..
2022/02/21 17:32:55 Using Obtaining a token from the Azure CLI for Authentication
2022/02/21 17:32:55 Getting OAuth config for endpoint https://login.microsoftonline.com/ with  tenant zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz
2022/02/21 17:33:10 Testing if Service Principal / Client Certificate is applicable for Authentication..
2022/02/21 17:33:10 Testing if Multi Tenant Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:33:10 Testing if Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:33:10 Testing if Managed Service Identity is applicable for Authentication..
2022/02/21 17:33:10 Testing if Obtaining a token from the Azure CLI is applicable for Authentication..
2022/02/21 17:33:10 Using Obtaining a token from the Azure CLI for Authentication
2022/02/21 17:33:10 Getting OAuth config for endpoint https://login.microsoftonline.com/ with  tenant zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz
2022/02/21 17:33:11 azurerm importing... resource_group
2022/02/21 17:33:11 azurerm done importing resource_group
2022/02/21 17:33:11 Number of resources for service resource_group: 1
2022/02/21 17:33:11 Refreshing state... azurerm_resource_group.tfer--rg-terraformer
2022/02/21 17:33:11 Filtered number of resources for service resource_group: 1
2022/02/21 17:33:11 azurerm Connecting....
2022/02/21 17:33:11 azurerm save resource_group
2022/02/21 17:33:11 azurerm save tfstate for resource_group
tfadmin@vm-terraformer:~$ ls

うまくいったようなので中身を確認してみます。

tfadmin@vm-terraformer:~$ ls
generated  init.tf
tfadmin@vm-terraformer:~$ cat generated/azurerm/resource_group/
outputs.tf         provider.tf        resource_group.tf  terraform.tfstate
tfadmin@vm-terraformer:~$ cat generated/azurerm/resource_group/resource_group.tf
resource "azurerm_resource_group" "tfer--rg-terraformer" {
  location = "japaneast"
  name     = "rg-terraformer"
}

いい感じにterraformのコードが生成されています。
もう少し踏み込んで特定のリソースグループ内のVMをimportしてみます。

tfadmin@vm-terraformer:~$ terraformer import azure -R rg-terraformer -r virtual_machine
2022/02/21 17:48:41 Testing if Service Principal / Client Certificate is applicable for Authentication..
2022/02/21 17:48:41 Testing if Multi Tenant Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:48:41 Testing if Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:48:41 Testing if Managed Service Identity is applicable for Authentication..
2022/02/21 17:48:41 Testing if Obtaining a token from the Azure CLI is applicable for Authentication..
2022/02/21 17:48:41 Using Obtaining a token from the Azure CLI for Authentication
2022/02/21 17:48:41 Getting OAuth config for endpoint https://login.microsoftonline.com/ with  tenant zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz
2022/02/21 17:48:51 Testing if Service Principal / Client Certificate is applicable for Authentication..
2022/02/21 17:48:51 Testing if Multi Tenant Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:48:51 Testing if Service Principal / Client Secret is applicable for Authentication..
2022/02/21 17:48:51 Testing if Managed Service Identity is applicable for Authentication..
2022/02/21 17:48:51 Testing if Obtaining a token from the Azure CLI is applicable for Authentication..
2022/02/21 17:48:51 Using Obtaining a token from the Azure CLI for Authentication
2022/02/21 17:48:51 Getting OAuth config for endpoint https://login.microsoftonline.com/ with  tenant zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz
2022/02/21 17:48:51 azurerm importing... virtual_machine
2022/02/21 17:48:52 azurerm done importing virtual_machine
2022/02/21 17:48:52 Number of resources for service virtual_machine: 1
2022/02/21 17:48:52 Refreshing state... azurerm_linux_virtual_machine.tfer--vm-terraformer
2022/02/21 17:48:52 Filtered number of resources for service virtual_machine: 1
2022/02/21 17:48:52 azurerm Connecting....
2022/02/21 17:48:52 azurerm save virtual_machine
2022/02/21 17:48:52 azurerm save tfstate for virtual_machine

tfadmin@vm-terraformer:~$ ls generated/azurerm/
resource_group/  virtual_machine/
tfadmin@vm-terraformer:~$ ls generated/azurerm/virtual_machine/
linux_virtual_machine.tf  outputs.tf  provider.tf  terraform.tfstate
tfadmin@vm-terraformer:~$ ls generated/azurerm/virtual_machine/linux_virtual_machine.tf
generated/azurerm/virtual_machine/linux_virtual_machine.tf
tfadmin@vm-terraformer:~$ cat generated/azurerm/virtual_machine/linux_virtual_machine.tf
resource "azurerm_linux_virtual_machine" "tfer--vm-terraformer" {
  admin_ssh_key {
    public_key = "ssh-rsa <~~~~>"
    username   = "tfadmin"
  }

  admin_username                  = "tfadmin"
  allow_extension_operations      = "true"
  computer_name                   = "vm-terraformer"
  disable_password_authentication = "true"
  encryption_at_host_enabled      = "false"
  extensions_time_budget          = "PT1H30M"
  location                        = "japaneast"
  max_bid_price                   = "-1"
  name                            = "vm-terraformer"
  network_interface_ids           = ["/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg-terraformer/providers/Microsoft.Network/networkInterfaces/vm-terraformerVMNic"]

  os_disk {
    caching                   = "ReadWrite"
    disk_size_gb              = "30"
    name                      = "vm-terraformer_OsDisk_1_0083db50da6c47bca0e3d1750184adb5"
    storage_account_type      = "Premium_LRS"
    write_accelerator_enabled = "false"
  }

  patch_mode            = "ImageDefault"
  platform_fault_domain = "-1"
  priority              = "Regular"
  provision_vm_agent    = "true"
  resource_group_name   = "rg-terraformer"
  secure_boot_enabled   = "false"
  size                  = "Standard_B2s"

  source_image_reference {
    offer     = "UbuntuServer"
    publisher = "Canonical"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  vtpm_enabled = "false"
}
tfadmin@vm-terraformer:~$

まとめ

azure-cliの最新バージョンには対応できていないようですが、とても簡単に既存リソースをterraformのコードに落とし込むことができました。
key情報などもそのまま落としてくるようなので、そのまま使うのは注意が必要そうです。
もちろん三大クラウド(Google Cloud, AWS, Azure)にも対応していますが、他にもKubernetes, Datadog, PagerDutyと様々なものに対応しているようです。
時間があればDatadogとかも試してみたいです。

Discussion