sshota0809のブログ

技術に関する備忘録など

vSphere環境でCloud-initを使って楽に仮想マシンの初期化を行う

TL;DR

会社の業務で vSpehre 環境の構築を行ったが、仮想マシンのセットアップを楽に行いたく Cloud-init を採用した話

  • cloud-init-vmware-guestinfo を利用することで仮想マシンmatadatauserdata を渡すことができる github.com

前提

vSphere 上の仮想マシンリソースはすべて terraform を利用して構成管理を行っている。 そのため、今回実現したい要件をまとめると以下の通りとなる。

  • vSphere上の仮想マシンmatadatauserdata を渡すことで Cloud-init でそれを使って仮想マシンの初期化処理を実施する
  • terraform 上で metadatauserdata の管理や仮想マシンへの配布を行いたい。

アプローチ

vSphere上の仮想マシンを Cloud-init を利用して初期化する

こちらに関しては、少し調べたところ VMware 社が公開している Cloud-init 用の Datasource があったため、こちらを利用することにしました。

github.com

詳しい仕様に関しては README を見ていただければと思いますが、仮想マシンリソースの extraconfig として各種データを定義することで 、そのデータをこの Datasource が読み込んで Cloud-init が走るという仕様になっています。

参考: https://github.com/vmware/cloud-init-vmware-guestinfo#configuration

terraform 上で metadata や userdata を定義および仮想マシンに配布する

上記の Datasource を利用し extraconfig に各種データを定義することで、Cloud-initを利用できることがわかりました。 なので、次は terraform を利用して extraconfig にデータを渡す方法を確認します。

これは、terraformvsphere_virtual_machine モジュールのドキュメントを確認したところ、extra_config オプションを定義することで可能でした。

www.terraform.io

実装

Datasource のインストール

今回は、下記をインストールしたマシンを 仮想マシンイメージ として vSphere 上に定義をし、それを利用して仮想マシンを作成する方針にしました。なので、好きな OS イメージを利用して 仮想マシンイメージ の元になるイメージを作成していきます。

好きな OS イメージで仮想マシンを立ち上げたら、Cloud-init をインストールします。今回、自分は CentOS 7.7 を利用することにしたので下記の通りです。

 yum -y install cloud-init

次に cloud-init-vmware-guestinfo の README に従って Datasource のインストールを行います。 今回は、シェルスクリプトを利用してインストールを行います。

参考: https://github.com/vmware/cloud-init-vmware-guestinfo#installing-on-other-linux-distributions

curl -sSL https://raw.githubusercontent.com/vmware/cloud-init-vmware-guestinfo/master/install.sh | sh -

シェルスクリプトの内容に関してですが、主に下記を行っています。

  • Datasource のインストール
  • インストールした Datasource を利用するための config ファイルの配置

dsname として VMwareGuestInfo という値が定義されており、それを config ファイル上で指定しています。

datasource_list: [ "VMwareGuestInfo" ]

https://github.com/vmware/cloud-init-vmware-guestinfo/blob/master/DataSourceVMwareGuestInfo.py#L102 https://github.com/vmware/cloud-init-vmware-guestinfo/blob/master/99-DataSourceVMwareGuestInfo.cfg#L13

ここまで実施したらインストールは完了なので、このイメージ状態のイメージを利用して 仮想マシンイメージ を作成してください。

terraform で仮想マシンリソースを定義

GitHub に参考となる雛形のようなリポジトリを作成したので、それを利用して説明をします。

github.com

ディレクトリ構成は下記の通りとなっています。

なお、GCP を普段利用しているため backend 等の設定は GCP のものになっていますが適宜変更をしてください。

今回、ポイントとなるのは 仮想マシンイメージとして先程作成したイメージ(この場合は template-centos7.7-cloud-init )を指定している点、extra_confg として metadatauserdata仮想マシンに渡している部分になります。

modules/common_centos77/main.tf

https://github.com/sshota0809/vsphere-vm-cloud-init/blob/master/modules/common_centos77/main.tf

data "vsphere_virtual_machine" "template" {
  name          = "template-centos7.7-cloud-init"
  datacenter_id = "${var.datacenter_id}"
}

...

data "template_file" "test_cloud_init_userdata" {
  template = "${file("${path.module}/cloud-init/userdata.yaml")}"
}

data "template_file" "test_cloud_init_metadata" {
  template = "${file("${path.module}/cloud-init/metadata.yaml")}"
  
  vars = {
    instance_name = "${var.hostname}"
    network_address = "${var.network_address}"
    network_gateway = "${var.network_gateway}"
  }
}

...

  extra_config = {
    "guestinfo.userdata"          = "${data.template_file.test_cloud_init_userdata.rendered}"
    "guestinfo.metadata"          = "${data.template_file.test_cloud_init_metadata.rendered}"
  }

上記のように定義したテンプレートファイルを仮想マシンの定義に設定しています。また、このテンプレートファイルは下記の通り別ファイルで定義しています。

modules/common_centos77/cloud-init/metadata.yaml

https://github.com/sshota0809/vsphere-vm-cloud-init/blob/master/modules/common_centos77/cloud-init/metadata.yaml

instance-id: ${instance_name}
local-hostname: ${instance_name}
network:
  version: 2
  ethernets:
    ens192:
      addresses:
        - ${network_address}
      gateway4: ${network_gateway}
      nameservers:
          addresses: [10.0.0.100, 10.0.0.101]

modules/common_centos77/cloud-init/userdata.yaml

https://github.com/sshota0809/vsphere-vm-cloud-init/blob/master/modules/common_centos77/cloud-init/userdata.yaml

#cloud-config

debug:
  verbose: true
  output: '/var/log/cloud-init-debug.log'

locale:       en_US.UTF-8
timezone:     Asia/Tokyo

今回はサンプルのため、対した設定はしていませんが Cloud-init の仕様に応じて色々設定を追加してみてください。

terraform の実行

あとは、init -> plan -> apply を実行すれば、仮想マシンリソースが vSphere上で立ち上げられ、Cloud-init が走り期待する設定がされます。

おわりに

仮想マシンの初期化はもちろん色々と選択肢がありますが、業務ではオンプレミス基盤だけでなくパブリックプラウドを利用していることもあり、どうせなら Cloud-init を利用する方針で統一したいという思いがあったため、今回はこのような方法を選択しました。