Skip to content

Latest commit

 

History

History
443 lines (324 loc) · 23.9 KB

README.md

File metadata and controls

443 lines (324 loc) · 23.9 KB

Terraform × cloud-initでVMのセットアップをいい感じにする

telmate-3.0.1-rc3


はじめに

どうも、ネットワークコンテンツ研究会に所属しております、cyokozaiと申します。 ここでは、ネットワークコンテンツ研究会のプロジェクトの一つであるNekko CloudにIaCを導入し、Nekko Cloudの環境構築の自動化を目的とします。 最近流行ってるじゃないですか、やれIaaSだのKaaSだのSaaSだの...。 私たちのNekko Cloudだってイカしたプロビジョニングツールを導入して、チームメンバーのみんなが自由に計算リソースを使える環境を用意したいんです! ってことで、Proxmox VEのVM作成をTerraformとcloud-initを使って簡単にできるようにする、そんな感じのリポジトリです🌟

TL;DR

  • Proxmox VEのVM構築をcloud-initとTerraformを利用して、簡略化かつIaC対応できるようにしたもの
  • Proxmox VEにcloud-initをセットアップする方法の紹介
  • Terraformの基本操作とtfstateを保護するための応用例

上記の通りLinux OSのインスタンスの初期設定をいい感じに自動化してくれる優れもの。 GUIとCLIどちらでも設定可能👍 今回はTerraformのProxmox Providerを使って外部からUbuntuインスタンスの作成を目標にします。

Terraformとは

HashiCorp社が提供するTerraformは今のInfrastructure as Code (IaC) 時代を支える最もスタンダードなプロビジョニングツールです。 IBMでは次のように紹介されています。

Terraform は、クラウドおよびオンプレミスのリソースを安全かつ効率的に構築、変更、バージョン管理できるコード ツールとしてのインフラストラクチャです。

Application Programming Interfaces (APIs)が使えるほとんどのプラットフォームでTerraformは使用可能なんだとか。 すげー🙌

Proxmox VEのVM作成をTerraformで自動化するメリット

ぶっちゃけ「IaCのデファクトスタンダードだから😏」と言いたいところではあるんですが、さすがにそれだけだとエライ人に怒られちゃうからね。 真面目にやります。

  • Infrastructure as Code (IaC)
    IaCとは、これまで手動で行っていた手順をコード化することです。 インフラの設定内容がコード化されることで、設定の使いまわしが容易で確実になります。 そのため、同じ環境の再利用性が高いのが特徴です。 さらに、一部分のみ変更した環境を作成する際にかかる時間を従来より大幅に削減し、手動操作によるミスを起きにくくすることが可能です。 また、gitによるバージョン管理が可能となり、さらに、githubを利用することでインフラへ設定を適用する前のコードレビューが可能になります。 IaCの魅力とは、開発と運用に必要不可欠なスピードと安全性を備え、バージョン管理が可能でありバリデーションを実行でき、再利用が容易であることです。 あなたが扱う複雑なインフラのすべてが、たった数十行のソースコードにまとめてあるなんて、ステキなことだとは思いませんか?
  • 冪等性の確保
    私たちはProxmox VEに対してステートレスなVM構築を目的としています。 特に注目したいのは、TerraformのState Lockingです。 これは、複数のユーザがサーバに対して変更や操作を実行しようとしたときに、変更によるファイルの競合を防ぐ機能です。 tfstateファイルにロックがかかると、他のユーザはそのtfstateファイルの変更はできないので、堅牢性に優れています。 ここで冪等性については深堀りしませんが、気になる人はコチラの記事をお読みになってください。
  • スケーラブルな変更
    私たちが求めているのは、プログラムの関数のように引数に入れる値を変更するだけで、VMの仕様を変更できる「手軽さ」です。 今回作成したtfファイルでは、所見の人がパラメータをいじくる場所を極力一か所に集中するように設計しています。 OSの変更、CPUのコア数、メモリの容量、ストレージの大きさ...それらすべては変数の値を変えるだけで実現できる。 ネットワークの設定やVMIDの紐づけ、SSHキーの保存、複数台のVMの同時デプロイ。 Terraformが有している協力なプロビジョニング機能は、初めて車を納車した人のように、利用者の苦労を一気に解決してくれます。

Terraformの選定理由

  • プロビジョニングツールとしての信頼性
    これまで、Terraformは多くのクラウドサービスで採用されてきた実績があります。 プロビジョニングツールの最大の利点は、インフラに関するほどんどあらゆる項目をソースコードで定義することができる点です。 堅牢なコードでインフラを体系化することができ、プロバイダに対して常にステートレスなプロビジョニングを実行できます。

Proxmox Providerの選定理由

今回はTelmate/proxmoxをProxmox Providerとして使用しています。 Terraformで選択可能なProxmoxのプロバイダはいくつか存在します。 今回はその中からTelmateとBPGの2つを比較しました。 Telmateの選定理由については以下の通りです。

  • 豊富な機能
    Telmate/proxmoxのバージョンは3.0.1-rc1です。 RC版を使用している理由は、CloudInitの柔軟なコンフィグ設定を実装しているためです。 今のところ動作に致命的な影響は出ていませんが、ロールバックも視野に入れつつ、CloudInitの恩恵を最大限得るために今回選択しています。
  • コミュニティが活発である
    開発コミュニティの活動が活発であることは大切な要素だと考えています。 サポートが終了していたり、バージョンの更新が滞っているようなOSSはとても使えません。 ソースコードの最終更新日やイシューのやり取りなどを確認することで、コミュニティの活動状況をある程度把握できるでしょう。 この点では、TelmateとBPGは双方活発なイシューが交わされており、今後のサービスの発展が期待されます。
  • バージョンのアップデートは破壊的更新ではないか
    今回の選定理由の決め手はこの要素にあります。 Telmateは、既に3回のメジャーアップデートを行っており、Terraformプロバイダとしての機能は高いレベルで成熟してきていると言えます。 しかし、BPGは未だメジャーアップデートは行われておらず、マイナーアップデートを頻繁に行っている状況です。 Terraformの使用場面を考えると安定稼働は必須なため、頻繁に破壊的なアップデートが発生するプロバイダは正直怖くて使えません。

こんな感じでしょうかね...。
あまりこういうのは書きなれていないので、拙い文章で申し訳ないです。 ちなみに今回は見送ったBPGですが、こちらも実装されている機能の側面では、Telmate以上のポテンシャルを秘めていると思います。 メジャーアップデートの到来を期待しつつ、こちらの動作検証も並行して進めていきたいですね。


cloud-initの使い方

作成したIMGファイルからテンプレートを作成して、クローンすることでVMのセットアップの手間を省くことができる。 cloud-initはそれを可能にし、クラウドでのIaCを行う上では欠かせないツールである。 Proxmoxでcloud-initを使用し、各種VMのデプロイを自動化する。
以下ではGUIとCLI両方の設定の仕方を紹介する。

GUIで設定を行う場合

  • Proxmox VEのGUIを開き、cloud-initを作成するノードのlocalを選択
  • ISO Imagesを選択し、使用するISOファイルUbuntu server Cloudimg 22.04LTSをアップロードする
  • 普段通りCreate VMを押してテンプレート用のVMを作成(ただし初回起動はまだしないように!bootのチェックも外しておく)
  • VM.Hardwareを選択し、AddからCloudInit Driveを選択する

CI-1

  • cloud-initの保存先を選択する

CI-2

  • VM.cloud-initを選択すると、編集可能になっている
  • User, Password, IP Config(Gateway)を設定する

CI-3

  • 設定が完了したら、右上のMoreからConvert to Templateを選択してテンプレートを作成
  • テンプレートが完成するとこんな感じの画面になる

CI-4

  • Datacenterを選択。Permissions.Userを選択する
  • Addをクリックして、Terraformを実行するためのユーザを新規作成する

GUI-1

  • 各種必要な項目を設定する(今回は適当にhogeを作成)

GUI-2

  • 次に、Permissions.API Tokensへ移動し、同様にAddをクリックしてトークンの新規発行を行う

GUI-3

  • 先程作成したユーザを選択し、任意のToken IDを入力する(今回はhogehoge)
  • Privilege Separationのチェック欄を外しておく

GUI-4

  • 発行したTokenとSecretはterraform.tfvarsPM_API_TOKEN_IDPM_API_TOKEN_SECRETへそれぞれ張り付けておく

GUI-5

  • Permissions.Rolesへ移動し、Createを選択
  • 新たにTerraformProviderというロールを作成する ※この項目はCLIで行った方が楽ですね...

GUI-tfprov

  • 最後にPermissionへ移動し、Addを選択

GUI-6

  • Path(/)、ユーザ(hoge)、ロール(TerraformProvider)を選択する

GUI-7

CLIで設定を行う場合

wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img -O ubuntu-22.04-server-cloudimg-amd64.img
  • テンプレート用のVMを作成
qm create <VM ID> --memory 4096 --balloon 1024 --net0 virtio,bridge=vmbr0
  • localのstorageにISOファイルをインポート
qm importdisk <VM ID> ubuntu-22.04-server-cloudimg-amd64.img local-lvm
  • VMをセットアップ(nameserverはネットワークごとに任意のIPを設定)
qm set <VM ID> --name <VM Name>
qm set <VM ID> --scsihw virtio-scsi-pci --virtio0 local-lvm:vm-<VM ID>-disk-0
qm set <VM ID> --virtio0 local-lvm:0,import-from=/root/ubuntu-22.04-server-cloudimg-amd64.img
qm set <VM ID> --boot order=virtio0
qm set <VM ID> --ide2 local-lvm:cloudinit
# qm set <VM ID> --nameserver 192.168.0.1
  • VMテンプレートにコンバートする
qm template <VM ID>

Terraformを使ってProxmoxのcloud-initから自動デプロイ

Proxmoxクラスタの設定

@ymbk990さんの記事を参考に、詳細な設定項目はtfvarsにまとめるように作成します。

  • Terraform用の新しいロールTerraformProviderを作成
pveum role add TerraformProvider -privs "Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Migrate VM.Monitor VM.PowerMgmt SDN.Use"
  • 新しいユーザhoge@pveを作成
pveum user add hoge@pve --password <password>
  • ロールTerraformProviderをユーザhoge@pveに追加
pveum aclmod / -user hoge@pve -role TerraformProvider
  • pvesh create /access/users/hoge@pve/token/hogehoge --privsep 0を実行してトークンを発行
  • 発行したTokenとSecretはterraform.tfvarsPM_API_TOKEN_IDPM_API_TOKEN_SECRETへそれぞれ張り付けておく
$ pvesh create /access/users/hoge@pve/token/hogehoge --privsep 0
┌──────────────┬──────────────────────────────────────┐
│ key          │ value                                │
╞══════════════╪══════════════════════════════════════╡
│ full-tokenid │ hoge@pve!hogehoge                    │
├──────────────┼──────────────────────────────────────┤
│ info         │ {"privsep":"0"}                      │
├──────────────┼──────────────────────────────────────┤
│ value        │ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx │
└──────────────┴──────────────────────────────────────┘

TerraformでVMをデプロイ

ここからは、このリポジトリをローカルにクローンしていることが前提です。
ま、ここまで読んでくれた人はさすがにもうやってくれてるよね?😁👍

  • cd .\terraformでtfファイルが保存されたディレクトリへ移動
  • terraform initを実行して初期化
  • terraform initは主に次のことを行う
  • providerの初期化
  • プラグインのダウンロード
  • backendの設定
  • moduleの初期化
    参考
$ terraform init

Initializing the backend...
Initializing modules...

Initializing provider plugins...
- Reusing previous version of telmate/proxmox from the dependency lock file
- Using previously-installed telmate/proxmox v3.0.1-rc1

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.

Important

Terraformでは、インフラストラクチャの状態を記録するtfstateファイルが存在します。 このファイルは、プロビジョニングにおける作成リソースやプラグインの依存関係など重要な情報を含みます。
そして、致命的なのは、以前建てたtfstateファイルを保護せずに次のVMをデプロイしてしまうと、tfstateファイルが上書きされてしまい、結果現在動作しているVMを破壊した後に新たにVMをデプロイしてしまいます。
この現象を回避するには、予めtfstateファイルの保存先をプロジェクトごとに分けておく必要があります。 TerraformのBackendオプションを使って初期化時に保存先を宣言すると、セキュアなプロビジョニングを実現できます。

terraform init -reconfigure -backend-config="path=tfstate/username/project-name.tfstate"

-reconfigureは既存のtfstateファイルの有無に関係なく、設定を再構成します。 -backend-configでtfstateファイルの保存先を設定します。

各種VMおよびリージョンの設定項目を記述する

backend.tflocalにあるVMリソースの項目を適宜設定する

  • Argument reference

    • onboot: デプロイ時にそのまま起動する デフォルトはtrue
    • storage_pool: 使用するストレージ先 cephfs local-lvmから選択
  • VM config Ubuntu 22.04

    • os_name: OSの名前
    • ci_name: cloud-initで事前に作成したVMテンプレートの名前
    • description: 概要
    • vmid: Proxmox VMID
    • clone_num: Proxmoxクラスター上にデプロイされるVMの数
    • cores: VMのコア数(デフォルトは1)
    • memory: VMのメモリ数(デフォルトは2048MB)
    • disk_size: VMのストレージ(デフォルトは2252MB)
tfvarsの設定項目について

terraform.tfvars.templateを参考に内容を記述すること。

  • PROXMOX PROVIDER CONFIGURATION

    • NC_REGION: Nekko Cloud PVE Regionの略語(幕張 => mk, 浦和 => ur, 津田沼 => tu)
    • PM_API_TOKEN_ID: # Permissions.API Tokensで作成したAPI Token
    • PM_API_TOKEN_SECRET: # Permissions.API Tokensで作成したAPI Secret
    • PM_HOST_IP: 各PVEリージョンのIPのホスト部(Number)
    • NC_MK_IP: 各PVEリージョンのIPのネットワーク部(XXX.XXX.XXX.)
    • NC_UR_IP: 各PVEリージョンのIPのネットワーク部(XXX.XXX.XXX.)
    • NC_TU_IP: 各PVEリージョンのIPのネットワーク部(XXX.XXX.XXX.)
  • VM CONFIGURATION

    • "vm_name": # VMの名前
    • "username": # VMにログインするユーザネーム
    • "password": # VMへのログイン時に必要なパスワード
    • "public_key": # SSH用の公開鍵
  • terraform planを実行してtfファイルに問題が無いか確認を行ってもらう
  • terraform applyを実行してデプロイ
    yesと入力して開始!
$ terraform apply
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: 1 added, 0 changed, 0 destroyed.
  • VMを削除する場合はterraform destroyを実行する
    yesと入力して開始!
$ terraform destroy

~~~

Plan: 0 to add, 0 to change, 1 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.

Important

terraform apply / destroyについて、先程のterraform init同様にtfstateファイルの指定、およびtfstate.buckupの保存先を指定します。 コマンドは以下のとおりです(destroyも同様)。

terraform apply --auto-approve -state=tfstate/username/project-name.tfstate -backup=tfstate/username/project-name.tfstate.backup

--auto-approveは変更確認の入力yesを省略します。 -stateは先程と同じtfstateファイルのパスを指定します。 -backupはtfstate.backupを保存するためのパスを指定します。


おわりに

ここまでお疲れ様でした!今日からあなたもNekko Cloudのリージョン管理者の仲間入りです🙌
今回のIaC実装を経て、チームメンバーの作業効率の向上に関する課題は多く残っていると考えています。 チームメンバーが求めているものは、自由に触って好きなように作ったり壊したりできるVMを、いつでも使える環境ではないでしょうか? IaC導入の一番のメリットは、インフラストラクチャの自動構築です。 これは、Nekko Cloudの各リージョン管理者からの視点では一定水準をクリアしたと認識しています。 では、リージョン管理者以外のチームメンバーは、VMを作成するのに一からTerraformを学ぶ必要があるのでしょうか? それは本来やりたいことからかけ離れた、あまりにも遠回りな選択肢なのです。
とまあ、説教垂れててもこういった労苦(Toil: トイル)は消えて無くなったりしないので、一つずつテクノロジーを使って解決していきましょう。 今ここでチョロっと話した、いわゆる「ゴールデンパス」に関するお話はコチラの記事で詳しく述べています。

ではでは、今後の開発にご期待ください!🫡
そんじゃまた👋

cyokozai

追伸

  • cloud-initのテンプレートもワンクリックで作成できるようにしたいので、CloudConfig.yaml周りを調査中であります🫡
  • 現在DiscordBotでVMのデプロイを行うツールを開発中です。
    他の開発メンバーも交えて、本格的にチームメンバーへのVMの払い出しを念頭に置いたシステム開発を行っています。

乞うご期待!!


参考文献

  1. cloud-initを使ったLinux OSの初期設定
  2. Proxmox VE cloud-init で Ubuntu 20.04 を起動する
  3. What is Terraform?
  4. Terraformとは | IBM
  5. サーバーレスが気になる開発者に捧ぐ「べき等性」ことはじめ
  6. Terraform面接質問集を作ってみた
  7. Terraform のコマンド、オプションを出来るだけ使ってみる
  8. Telmate/terraform-provider-proxmox
  9. bpg/terraform-provider-proxmox
  10. Proxmox Provider
  11. Terraform Registry
  12. Proxmox VEとTerraformでインターン生に仮想マシンを払い出す話
  13. Proxmox VEのcloudinitでuserdataを自由に調整する
  14. 道を照らす: プラットフォーム エンジニアリング、ゴールデンパス、セルフサービスのパワー