5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

terraform-provider-libvirtを使ってみた

Last updated at Posted at 2021-01-25

はじめに

Terraformを使ってローカル環境でVMをデプロイしてみたのでその記録を残します。利用したバージョンは下記になります。Ubuntu 20.04LTSでの記録になります。

$ terraform version
Terraform v0.14.5
+ provider registry.terraform.io/dmacvicar/libvirt v0.6.3

Terraform?

公式ページ https://www.terraform.io/

Infrastructure as Code (IaC) のツールという紹介がよくされていると思います。Codeつまりテキストファイルに書かれたロジックに基づいてインフラを構築するCLIツールです。インフラと言っても当然物理をどうこうできるわけがありませんので、基本的にはクラウド上でのインフラ構築と考えればいいと思います。ローカル環境でKVMやdockerを使った構成を構築することもできます。

Terraformのインストール

ダウンロードページから、下記のプラットフォーム向けのTerraformを入手できます。

  • macOS
  • FreeBSD
  • Linux
  • OpenBSD
  • Solaris
  • Windows

クラウド環境から実行できる環境Terraform Cloudもあるようです。

Ubuntuであればsudo apt-get install terraformでインストールすることもできます。他もおそらくパッケージシステムでインストールできると思います。

どんなふうに記述して何を構築するのか

https://learn.hashicorp.com/terraform
ここを読んでおいてください、だと投げやりすぎるのですが、読んでいただけるのならそのほうが以下のしょぼくれた説明よりしっかりしているので、安心できるかと思います。

というわけで雰囲気を味わいたい人向けに、どんなふうに書いたら何が構築できるのか、その一例を紹介します。

ディレクトリを用意する

Terraformの構築対象はディレクトリで管理されます。ここでは試しにtf-testというディレクトリを用意してみます。Codeをこのディレクトリに置くことになります。

mkdir tf-test
cd tf-test

*.tf ファイルを用意する

Terraformが読んで実行するコードはsuffixを.tfとします。.tfの中身つまり記述言語は、Hashicorp Configuration Language (HCL) というそうです。

下記はオフィシャルのチュートリアルムービーから拝借しました。AWSのEC2インスタンスを構築する例になります。ここではmain.tfとしておきます。suffixをみてファイルを見つけるので、mainである必要は特にありません。

main.tf
provider "aws" {
  access_key = "ACCESS_KEY"
  secret_key = "SECRET_KEY"
  region = "us-east-1"
}

resource "aws_instance" "example" {
  ami = "ami-2757f631"
  instance-type = "t2.micro"
}

見て解ると思いますが、これはこのままでは実際に動かすことはできませんので、眺めるだけにとどめておいてください。

Terraformを動かしてみる

まず最初に一回だけ、初期化が必要です。

terraform init

tfファイルの内容が正しいかをチェックできます。(してもしなくても、間違っていれば実行時にエラーが出ます)

terraform validate

なにをどんなふうに変更することになるのかの確認もできます。

terraform plan

実行すると、上記例であればAWS EC2インスタンスが作成されます。

terraform apply

インスタンスを削除することもできます。

terraform destroy

さまざまなprovider

例示したtfファイルにも書きましたが、Terraformではproviderを指定して、そのproviderのリソースとしてどういうものを用意するのかを記述していきます。例で提示した"aws"の他にも様々なproviderが用意されています。

  • "aws"
  • "azurerm"
  • "google"
  • "kubernetes"
  • ...

数が多くて紹介しきれませんので、https://registry.terraform.io/browse/providers こちらで検索してみてください。

providerは、下記に分類されます。

  • HashiCorpのTerraform registryから提供されていて自動的にダウンロードして利用できるもの
    • official, verified, communityの3種に分かれます
  • Terraform registryにないもの

Terraform registryで提供されているものは、provider "それ" と書けば利用できます。ローカルになければ自動でダウンロードされます。提供されていないものは手動でダウンロードするなどの作業が必要になります。

terraform-provider-libvirt

terraform-provider-libvirtは、名前から想像できますが、libvirtを使ってVM環境を構築するTerraform providerです。Terraform registryでは提供されていませんので、自動ダウンロードや自動インストールは失敗します。そのため、インストールと利用には少し手間がかかります。

terraform-provider-libvirtのインストール

さまざまなインストール方法がありますので、公式ページのREADME.mdを読んで、好きな方法でインストールしてください。

たとえばstable packageをUbuntuにインストールする場合は、README.mdからリンクを手繰ってこの手順に従います。

インストール後、もうひと手間必要です。
https://github.com/dmacvicar/terraform-provider-libvirt/blob/master/docs/migration-13.md
こちらのドキュメントのとおりに、ファイルを移動させてください。Terraform 0.13以降のバージョンでは、これをやっておかないとprovider "libvirt"が使えません。

provider "libvirt" でVMを構築する

用意しておくもの

ディスクイメージ

構築するVM用のディスクイメージが必要です。構築時に(virt-installによって)複製されます。なんでもいいのですが、ここではたまたま手元にあったdebian10-gns3.qcow2を使うことにします。(ここから拾えます)

$ ls -lh
total 2.6G
-rw-rw-r-- 1 masaru masaru 2.6G Nov 11 16:07 debian10-gns3.qcow2

libvirt, qemu

当然ですがlibvirtqemuをインストールしておく必要があります。操作しているアカウントをlibvirtグループに追加するのもお忘れなく。

/etc/libvirt/qemu.conf の編集

security_driver = "none" にしておかないと、VMの起動に失敗します。編集しておいてください。編集後は sudo systemd restart libvirt-bin を実行してください。グループ周りの反映もあるので一度リブートするのでもいいかと思います。

tfファイルの編集

ディレクトリを作って、.tfファイルを編集します。(viである必要はもちろんありません)

mkdir libvirt-test
cd libvirt-test
vi main.cf

いきなりproviderと書き始めたいところですが、.tfファイルの先頭におまじないが必要です。

main.tf
terraform {
  required_version = ">= 0.13"
  required_providers {
    libvirt = {
      version = ">= 0.6.2"
      source = "dmacvicar/libvirt"
    }
  }
}

この記述によって、先ほど場所を移動したterraform-provider-libvirtを見つけることができます。これがない場合、Terraform registryに探しに行ってしまい、hashicorp/libvirtがないんじゃが? と言われエラーになってしまいます。

では続けていよいよprovider以降をつらつら書きます。

main.tf
provider "libvirt" {
  uri = "qemu:///system"
}

resource "libvirt_volume" "os-image" {
  name = "testvm-disk.qcow2"
  source = "debian10-gns3.qcow2"
  format = "qcow2"
}

resource "libvirt_domain" "domain-testvm" {
  name = "debian"
  memory = 2048
  vcpu = 1

  disk { volume_id = libvirt_volume.os-image.id }

  network_interface {
    network_name = "default"
  }

  console {
    type = "pty"
    target_port = "0"
  }

  graphics {
    type = "spice"
    listen_type = "address"
    autoport = "true"
  }
}

ざっくり解説すると

  • pervider "libvirt"でlibvirt providerの利用を宣言 (以降でlibvirt_ごにょごにょというリソースが使えるようになる)
  • resource "libvirt_volume" "os-image" でボリューム(ストレージ)を定義。
  • resource "libvirt_domain" "domain-testvm"でドメイン(VMインスタンス)を定義。

最後に、このディレクトリにdebian10-gns3.qcow2を置けば準備完了です。

いよいよ実行

terraform init
terraform validate
terraform apply

terraform apply を実行すると、実行するか問い合わせがありますので yes と答えます。

実行ログ (たまたまですが裏で別の重いタスクを動かしてる関係で時間がかかっています)
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of dmacvicar/libvirt from the dependency lock file
- Installing dmacvicar/libvirt v0.6.3...
- Installed dmacvicar/libvirt v0.6.3 (unauthenticated)

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
$ terraform validate
Success! The configuration is valid.
$ terraform apply

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:

  # libvirt_domain.domain-testvm will be created
  + resource "libvirt_domain" "domain-testvm" {
      + arch        = (known after apply)
      + disk        = [
          + {
              + block_device = null
              + file         = null
              + scsi         = null
              + url          = null
              + volume_id    = (known after apply)
              + wwn          = null
            },
        ]
      + emulator    = (known after apply)
      + fw_cfg_name = "opt/com.coreos/config"
      + id          = (known after apply)
      + machine     = (known after apply)
      + memory      = 2048
      + name        = "debian"
      + qemu_agent  = false
      + running     = true
      + vcpu        = 1

      + console {
          + source_host    = "127.0.0.1"
          + source_service = "0"
          + target_port    = "0"
          + type           = "pty"
        }

      + graphics {
          + autoport       = true
          + listen_address = "127.0.0.1"
          + listen_type    = "address"
          + type           = "spice"
        }

      + network_interface {
          + addresses    = (known after apply)
          + hostname     = (known after apply)
          + mac          = (known after apply)
          + network_id   = (known after apply)
          + network_name = "default"
        }
    }

  # libvirt_volume.os-image will be created
  + resource "libvirt_volume" "os-image" {
      + format = "qcow2"
      + id     = (known after apply)
      + name   = "testvm-disk.qcow2"
      + pool   = "default"
      + size   = (known after apply)
      + source = "debian10-gns3.qcow2"
    }

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

libvirt_volume.os-image: Creating...
libvirt_volume.os-image: Still creating... [10s elapsed]
libvirt_volume.os-image: Still creating... [20s elapsed]
libvirt_volume.os-image: Still creating... [30s elapsed]
libvirt_volume.os-image: Still creating... [40s elapsed]
libvirt_volume.os-image: Still creating... [50s elapsed]
libvirt_volume.os-image: Still creating... [1m0s elapsed]
libvirt_volume.os-image: Still creating... [1m10s elapsed]
libvirt_volume.os-image: Still creating... [1m20s elapsed]
libvirt_volume.os-image: Still creating... [1m30s elapsed]
libvirt_volume.os-image: Still creating... [1m40s elapsed]
libvirt_volume.os-image: Still creating... [1m50s elapsed]
libvirt_volume.os-image: Still creating... [2m0s elapsed]
libvirt_volume.os-image: Still creating... [2m10s elapsed]
libvirt_volume.os-image: Creation complete after 2m18s [id=/var/lib/libvirt/images/testvm-disk.qcow2]
libvirt_domain.domain-testvm: Creating...
libvirt_domain.domain-testvm: Still creating... [10s elapsed]
libvirt_domain.domain-testvm: Creation complete after 15s [id=33e01c13-97a9-4ec0-ae7a-51853096ad94]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
masaru@tama:~/src/libvirt-test$ 

terraform applyを実行した後、実際にVMが起動しているか確認してみます。

$ virsh list
 Id   Name     State
------------------------
 37   debian   running

$ 

virt-viewerでコンソール画面と接続することができます。今回使ったイメージではbannerに表示がありますがroot/debianあるいはdebian/debianでログインできます。

削除

terraform destroy で構築した環境がまるっと削除されます。ディスクイメージも削除されますので、VMにログインしていろいろファイルを変更などしていてもすべてが無に帰します。ご注意ください。

エラーで困ったら

/var/lib/libvirt/qemu.confの編集を忘れていると、terraform applyの実行で最後の最後にPermission deniedと言われてコケます。/var/lib/libvirt/imagesにアクセスできないのでこれかな? と思う方もいらっしゃるかわかりませんが、そこはそのままでOKです。virsh pool-edit defaultとかやればオーナーグループパーミッションどれも変更できますが、それでは解決しません。上で書いたとおり、qemu.confを編集してください。

この状態でterraform destroyを実行しても半端にlibvirt domainが残っているので、次のterraform applyが失敗します。terraform destroyの後にdomainを削除することでこの問題を回避できます。

virsh undefine debian

さいごに

Terraformにはmoduleという概念があって便利なのですが、これについては別途解説したいと思います。terraform-provider-libvirtのネットワーク周りについても解説できればと思います。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?