ESXiを自動インストール＆構築したかった

#はじめに
直近で、結構な台数の物理サーバにESXiをインストールして構築する必要が出てきました。
手作業でやるのが面倒なのもそうですが、ヒューマンエラーで差分が出る可能性を減らしたいので、どうにかして自動してみました。
また、今後も運用がしやすくなるように、Windows環境のみで出来るようにします。

環境
物理サーバ：NEC Express5800/R120h-1M
ISO：ESXi 7.0u2 NEC Custom Installer
作業環境：Windows 10

#事前準備
###ISOファイルの抽出
まずは、myvmware からIOSファイルをダウンロードして、中のデータを抽出します。
Windows8以降は、OS標準でISOがマウント出来るので、ツールなどは不要です。
今回は、C:\scripts\custom_iso に展開しました。

Kickstartスクリプトの作成
次は、インストール時の設定を反映するためのスクリプトを作成します。
作成したスクリプトは、C:\scripts\custom_iso 内に、WORKフォルダを作成して配置します。
この時、フォルダ名は必ず大文字で作成してください。

スクリプトでは、以下の流れで処理を行います。
1.ESXiのインストール＆再起動
2.ESXiにIPアドレス割り振り
3.仮想SW、DNS、NTPなどの設定

1の処理内でESXiにIPアドレスは設定出来ますが、その場合は台数分のISOを作成する必要があります。
そのため、今回は一つのISOで複数のサーバに対して、それぞれユニークのIPアドレスを割り振り出来るようにしています。

###ks.cfg
まずは、メインの処理スクリプトです。

```cfg:ks.cfg
################################################
## vSphere ESXi 7.0 Scripted Install - Part 1 ##
################################################

# Accept the VMware End User License Agreement
vmaccepteula

# Set the root password for DCUI
rootpw PASSWORD

# Install on the first local disk available on machine
install --firstdisk --overwritevmfs

# Keyboard type
keyboard Japanese

# Set the network to DHCP on the first network adapter
network --bootproto=dhcp --device=vmnic0

# Reboot
reboot --noeject

################################################
## vSphere ESXi 7.0 Scripted Install - Part 2 ##
################################################

%firstboot --interpreter=busybox

# Mount install Disk
vmkload_mod iso9660
/sbin/vsish -e set /vmkModules/iso9660/mount mpx.vmhba32:C0:T0:L0

# Copy Network Config Shell
cp /vmfs/volumes/CDROM/WORK/NWSETUP.SH /tmp/nwsetup.sh
cp /vmfs/volumes/CDROM/WORK/SVR.CSV /tmp/svr.csv

# Disable IPv6
esxcli system module parameters set -m tcpip4 -p ipv6=0

# Done Network Config Shell
sh /tmp/nwsetup.sh

################################################
## vSphere ESXi 7.0 Scripted Install - Part 3 ##
################################################

# Add DNS Server
esxcli network ip dns server add --server DNSSERVER#1
esxcli network ip dns server add --server DNSSERVER#2

# Add NTP Server & Service Start
esxcli system ntp set --server=NTPSERVER#1 --server=NTPSERVER#2
/sbin/chkconfig ntpd on;
esxcli system ntp set --enabled=yes

# Enable and start SSH & ESX Shell Service
vim-cmd hostsvc/enable_ssh
vim-cmd hostsvc/start_ssh
vim-cmd hostsvc/enable_esx_shell
vim-cmd hostsvc/start_esx_shell

# Stop SSH & ESX Shell alert warnning
esxcli system settings advanced set --option=/UserVars/SuppressShellWarning --int-value=1

# Generate Virtual Switch & Port Group
esxcli network vswitch standard add --vswitch-name=vSwitch1

esxcli network vswitch standard uplink add --uplink-name=vmnic1 --vswitch-name=vSwitch1

esxcli network vswitch standard policy failover set --active-uplinks=vmnic1 --vswitch-name=vSwitch1

esxcli network vswitch standard portgroup add --portgroup-name=VLAN3510 --vswitch-name=vSwitch1

esxcli network vswitch standard portgroup set --portgroup-name=VLAN3510 --vlan-id 3510
```

Part 1では、インストールパラメータを指定します。
こちらは、VMware公式マニュアルにも記載がありますので、そちらを参考にしています。
[インストール スクリプトおよびアップグレード スクリプトのコマンド](https://docs.vmware.com/jp/VMware-vSphere/6.5/com.vmware.vsphere.install.doc/GUID-61A14EBB-5CF3-43EE-87EF-DB8EC6D83698.html#GUID-61A14EBB-5CF3-43EE-87EF-DB8EC6D83698　"インストール スクリプトおよびアップグレード スクリプトのコマンド")

###nwsetup.sh
Part 2では、ESXiへのIPアドレス割り振りを行います。

こちらは、以下のサイトを参考に作成しています。
[サーバ大量構築時のキモ ～VMware ESXiの自動インストール 初期設定自動化バージョン～](https://orebibou.com/ja/home/201407/20140701_001/　"サーバ大量構築時のキモ ～VMware ESXiの自動インストール 初期設定自動化バージョン～")

参考サイトでは、UUIDで物理サーバの紐づけを行ってますが、機器によってはUUIDの取得が面倒な時もあるため、シリアル番号での紐づけに変更してあります。(Nested ESXiへの自動インストールは想定してないので)

紐づけるリストは、svr.csv で記載します。
この二つのファイルは、改行コードをLFで保存してください。
CRLFで保存すると、スクリプトが動かないので、設定が反映されません。

```sh:nwsetup.sh
#!/bin/sh
# This Script is VMware ESXi Set Config Script
######################################################
# Set IP Address fpr vmknic
######################################################

cidr2mask ()
 {
 # Number of args to shift, 255..255, first non-255 byte, zeroes
 set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
 [ $1 -gt 1 ] && shift $1 || shift
 echo ${1-0}.${2-0}.${3-0}.${4-0}
}

######################################################
# Set IP Address for vmknic
######################################################

# Set Var
LIST=/tmp/svr.csv

# Get Serial Number
Serial=`smbiosDump | grep -A 3 'System Info (Type 1)' | grep Serial  | awk 'BEGIN { FS=": "; } { print $2; }' | sed "s/\"//g"`

# Get HostName,IP Address,Default Gateway
HOSTNAME=`cat $LIST | grep $Serial | awk 'BEGIN {FS=","} { print $1 }'`
GATEWAY=`cat $LIST | grep $Serial | awk 'BEGIN {FS=","} { print $3 }'`

# NIC0
NIC0_IPADDR=`cat $LIST | grep $Serial | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $1}'`
NIC0_PREFIX=`cat $LIST | grep $Serial | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $2}'`
NIC0_SUBNET=`cidr2mask $NIC0_PREFIX`

esxcli system hostname set --host="$HOSTNAME"
esxcfg-route -a default $GATEWAY

esxcfg-vmknic -i $NIC0_IPADDR -n $NIC0_SUBNET -p "Management Network"

/sbin/services.sh restart
```

```csv:svr.csv
hostname,serial,defaultgw,nic0
ESXi001,SERIAL001,192.168.100.1,192.168.100.11/24
ESXi002,SERIAL002,192.168.100.1,192.168.100.12/24
ESXi003,SERIAL003,192.168.100.1,192.168.100.13/24
ESXi004,SERIAL004,192.168.100.1,192.168.100.14/24
ESXi005,SERIAL005,192.168.100.1,192.168.100.15/24
```

Part 3以降は、esxcliコマンドなどを使って、固定パラメータを反映していきます。
以下のサイトを参考に、要件に従って反映しました。
[【vSphere ESXi7.0u2】ESXCLIコマンドでESXiの設定に使えそうなもの一覧] (https://t-dilemma.info/esxi-settings-esxcli-list/ "【vSphere ESXi7.0u2】ESXCLIコマンドでESXiの設定に使えそうなもの一覧")

Kickstartファイルのベースは、以下のコードを参考にさせて頂いてます。
[vmware-esxi-7-kickstart-install/ks.cfg] (https://github.com/sysadmintutorials/vmware-esxi-7-kickstart-install/blob/master/ks.cfg　"vmware-esxi-7-kickstart-install/ks.cfg")

作成したファイルは、全てWORKフォルダへ格納します。

#ブートパラメータの変更
起動後に、先ほど作成したKickstartファイルを実行するため、ブートパラメータの変更を行います。
今回はUEFIブートなので、以下のファイルを編集します。

```cfg:efi\boot\boot.cfg
kernelopt=cdromBoot runweasel
↓
kernelopt=ks=cdrom:/WORK/KS.CFG
```

#ISOファイル作成
次に、ISOファイルの作成を行います。
ここが、Windows環境で作成するにあたって一番のハマりポイントでした

###ISO作成ツールの入手
以下のURLから、mkisofs をダウンロードします。
https://sourceforge.net/projects/cdrtfe/files/cdrtfe%20portable/

ダウンロードしたzipファイルを展開し、以下のファイルを取り出します。
.\tools\cygwin\cygwin1.dll
.\tools\cdrtools\mkisofs.exe
取り出したファイルは、C:\scripts\mkisofs に格納しました。

###ISOファイルの作成
Linuxでも同様のツールがある(Linuxのが本家？)ので、実行コマンドオプションは調べるとたくさん出てきますが、残念ながらWindows版ではうまく行きませんでした。

そこで、VMwareのマニュアルなどを参照しながら、最終的に以下のパラメータでISOの作成が出来ました。
まずは、ISOファイルを展開したC:\scripts\custom_iso ディレクトリで、コマンドプロンプトを起動します。
コマンドプロンプトを起動して、cdコマンドで移動でもOKです。

次に、以下のコマンドを実行してISOファイルを作成します。

```
C:\scripts\mkisofs\mkisofs.exe -relaxed-filenames -J -R -b ISOLINUX.BIN -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -eltorito-platform efi -b EFIBOOT.IMG -no-emul-boot -o C:\scripts\custom_esxi.iso .
```

#ESXiインストール
作成したISOを、サーバの仮想DVD-ROMドライブへマウントしインストールします。
自動的にインストールが開始され、ks.cfgで指定したパラメータが投入されれば自動化は成功です！

#最後に
検証中に何度もISOを作成し続けて、結局構築台数分以上のISOを作成していた気が・・・
これで仕事に空き時間が出来るので、他のタスクを終わらせようと思います