Azure CloudShell Terraform

  • Terraform
  • VNet
  • VSCode
  • CloudShell
  • 準備 Terraform の認証方法

    Terraform のアクセス方法

    さすが、microsoft といったところか、terraform init するまでに約5時間ほど迷ってしまいました。その時に必要でないことに時間を掛けてしまうのは、私の悪い癖ですね。

    公式サイトによると、Terraform の Azure 認証方法が4種類あると書かれています。

    • Authenticating to Azure using the Azure CLI
    • Authenticating to Azure using Managed Service Identity
    • Authenticating to Azure using a Service Principal and a Client Certificate
    • Authenticating to Azure using a Service Principal and a Client Secret

    これらが、どんな認証方法なのか、どれを選択すべきかということを考えていたら、5時間が経過していました。

    そもそも、microsoft のドキュメントって本当にわかりづ....みなまでは言うまい。

    ★結論★ とりあえず使えるようになれば何でも良いのです。

    CloudShell で Terraform は簡単に使える

    もう、5時間もハマったのがバカらしいです。

    CloudShell には初めから Terraform がインストールされています。また、CloudShell 起動時の Azure Account で認証も済んでいます。

    そう、CloudShell を起動すれば、Terraform init の実行環境は整っていたのです。

    CloudShell を使用する方法は、上記の4種類の中で言うと一番上の「Authenticating to Azure using the Azure CLI」にあたりますね。

    VSCode Clouddrive CloudShell

    以前の記事で、VSCode に CloudShell と Clouddrive を連携する方法を紹介しました。特にファイルの編集画面が CloudShell だと不便ですので、このやり方が推奨です。

    今回も VSCode に Clouddrive と CloudShell が連携済みの状態で作業を進めていきます。

    では、VSCoude で CloudShell を起動します。

    atsushi_koizumi@Azure:~$ ls clouddrive atsushi_koizumi@Azure:~$ terraform --version Terraform v0.12.28 # 適当な作業ディレクトリを作成して移動します atsushi_koizumi@Azure:~$ mkdir -p clouddrive/work/20200712 atsushi_koizumi@Azure:~$ cd clouddrive/work/20200712 atsushi_koizumi@Azure:~/clouddrive/work/20200712$ # main.tf を作成します atsushi_koizumi@Azure:~/clouddrive/work/20200712$ touch main.tf

    Terraform Apply をやってみる

    main.tf

    準備で作成した main.tf に以下のように書き込んでおきます。ちなみに、公式サイトを、ほぼそのままパクっています。

    main.tf
    provider "azurerm" { version = "=2.0.0" features {} } terraform { required_version = "= 0.12.28" } # Create a resource group resource "azurerm_resource_group" "example" { name = "example-resources" location = "West Europe" } # Create a virtual network within the resource group resource "azurerm_virtual_network" "example" { name = "example-network" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location address_space = ["10.0.0.0/16"] }

    terraform init

    まずは、モジュールを取ってきます。

    atsushi_koizumi@Azure:~/clouddrive/work/20200712$ terraform init Initializing the backend... Initializing provider plugins... - Checking for available provider plugins... - Downloading plugin for provider "azurerm" (hashicorp/azurerm) 2.0.0... Terraform has been successfully initialized! atsushi_koizumi@Azure:~/clouddrive/work/20200712$ terraform --version Terraform v0.12.28 + provider.azurerm v2.0.0

    terraform plan

    さあ、続いて plan を実行してみましょう。

    atsushi_koizumi@Azure:~/clouddrive/work/20200712$ terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ Error: Unable to list provider registration status, it is possible that this is due to invalid credentials or the service principal does not have permission to use the Resource Manager API, Azure error: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://management.azure.com/subscriptions/xxxxxxxxxxxx/ providers?api-version=2016-02-01: StatusCode=400 -- Original Error: adal: Refresh request failed. Status Code = '400'. Response body: {"error":{"code":"invalid_request","message": "Timeout waiting for token from portal. Audience: https://management.azure.com/"}} on main.tf line 1, in provider "azurerm": 1: provider "azurerm" {

    バグふんじゃった

    結論としては、azurerm のバージョンが悪かったようです。

    まず、確認することとしては、Azure CLI で同じように resource が作成できるか、ということは確認しておきましょう。terraform は Azure CLI と同じクレデンシャル情報を使用しています。

    一旦、.terraform/ を削除して、azurerm のモジュールを取り直しました。main.tf の azurerm をこのように修正します。

    main.tf
    provider "azurerm" { features {} }

    terraform が自動で azurerm のバージョンを選択してくれます。それではもう一度、やってみましょう。

    atsushi_koizumi@Azure:~/clouddrive/work/20200712$ rm .terraform/ -r atsushi_koizumi@Azure:~/clouddrive/work/20200712$ terraform init Initializing the backend... Initializing provider plugins... - Checking for available provider plugins... - Downloading plugin for provider "azurerm" (hashicorp/azurerm) 2.18.0... * provider.azurerm: version = "~> 2.18" Terraform has been successfully initialized! # そしてもう一度 terraform plan を実行 atsushi_koizumi@Azure:~/clouddrive/work/20200712$ terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # azurerm_resource_group.example will be created + resource "azurerm_resource_group" "example" { + id = (known after apply) + location = "westeurope" + name = "example-resources" } # azurerm_virtual_network.example will be created + resource "azurerm_virtual_network" "example" { + address_space = [ + "10.0.0.0/16", ] + guid = (known after apply) + id = (known after apply) + location = "westeurope" + name = "example-network" + resource_group_name = "example-resources" + subnet = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.

    terraform apply

    plan が成功したら、もちろん apply も成功するでしょう。

    atsushi_koizumi@Azure:~/clouddrive/work/20200712$ terraform apply ... Plan: 2 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

    やっと、ここまで出来ました。

    terraform destroy

    最後にお掃除をして終わりたいと思います。

    atsushi_koizumi@Azure:~/clouddrive/work/20200712$ terraform destroy An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: - destroy Plan: 0 to add, 0 to change, 2 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes ... Destroy complete! Resources: 2 destroyed.

    今回はここまでにしておきます。

  • Terraform
  • VNet
  • VSCode
  • CloudShell