vSphere環境でCloud-initを使って楽に仮想マシンの初期化を行う
TL;DR
会社の業務で vSpehre 環境の構築を行ったが、仮想マシンのセットアップを楽に行いたく Cloud-init を採用した話
cloud-init-vmware-guestinfo
を利用することで仮想マシンにmatadata
やuserdata
を渡すことができる github.com
前提
vSphere 上の仮想マシンリソースはすべて terraform
を利用して構成管理を行っている。
そのため、今回実現したい要件をまとめると以下の通りとなる。
- vSphere上の仮想マシンに
matadata
やuserdata
を渡すことで Cloud-init でそれを使って仮想マシンの初期化処理を実施する terraform
上でmetadata
やuserdata
の管理や仮想マシンへの配布を行いたい。
アプローチ
vSphere上の仮想マシンを Cloud-init を利用して初期化する
こちらに関しては、少し調べたところ VMware 社が公開している Cloud-init 用の Datasource
があったため、こちらを利用することにしました。
詳しい仕様に関しては README を見ていただければと思いますが、仮想マシンリソースの extraconfig
として各種データを定義することで 、そのデータをこの Datasource
が読み込んで Cloud-init が走るという仕様になっています。
参考: https://github.com/vmware/cloud-init-vmware-guestinfo#configuration
terraform 上で metadata や userdata を定義および仮想マシンに配布する
上記の Datasource
を利用し extraconfig
に各種データを定義することで、Cloud-initを利用できることがわかりました。
なので、次は terraform
を利用して extraconfig
にデータを渡す方法を確認します。
これは、terraform
の vsphere_virtual_machine
モジュールのドキュメントを確認したところ、extra_config
オプションを定義することで可能でした。
実装
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 に参考となる雛形のようなリポジトリを作成したので、それを利用して説明をします。
ディレクトリ構成は下記の通りとなっています。
/modules/
- 仮想マシンやそれに渡す
matadata
やuserdata
を定義
- 仮想マシンやそれに渡す
/resouce/
なお、GCP を普段利用しているため backend 等の設定は GCP のものになっていますが適宜変更をしてください。
今回、ポイントとなるのは 仮想マシンイメージとして先程作成したイメージ(この場合は template-centos7.7-cloud-init
)を指定している点、extra_confg
として metadata
と userdata
を仮想マシンに渡している部分になります。
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
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
#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 を利用する方針で統一したいという思いがあったため、今回はこのような方法を選択しました。