7 changed files with 258 additions and 0 deletions
@ -0,0 +1,29 @@ |
|||
# Lab of vSphere Machines |
|||
|
|||
Fetch the latest vSphere 7.0 installation iso and customize it for automated install. |
|||
|
|||
```sh |
|||
sudo mount VMware-VMvisor-Installer-7.0U1c-17325551.x86_64.iso /mnt -o loop,ro |
|||
sudo mkdir /tmp/vsphere-custom |
|||
sudo cp -rv /mnt/* /tmp/vsphere-custom |
|||
sudo umount /mnt |
|||
sudo sed -i -r 's|^(kernelopt=.*)|\1 ks=https://raw.githubusercontent.com/nmasse-itix/terraform-lab/main/vsphere/itix-ks.cfg|' /tmp/vsphere-custom/boot.cfg |
|||
sudo sed -i -r 's|^(kernelopt=.*)|\1 ks=https://raw.githubusercontent.com/nmasse-itix/terraform-lab/main/vsphere/itix-ks.cfg|' /tmp/vsphere-custom/efi/boot/boot.cfg |
|||
sudo dnf install genisoimage |
|||
sudo genisoimage -relaxed-filenames -J -R -o /tmp/vsphere-custom.iso -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e efiboot.img -no-emul-boot /tmp/vsphere-custom |
|||
sudo cp /tmp/vsphere-custom.iso /var/lib/libvirt/images/ |
|||
``` |
|||
|
|||
Then, deploy the lab. |
|||
|
|||
```sh |
|||
terraform init |
|||
terraform apply |
|||
``` |
|||
|
|||
## References |
|||
|
|||
* https://www.grottedubarbu.fr/nested-virtualization-esxi-kvm/ |
|||
* https://itsjustbytes.com/2020/12/14/kvm-esxi-7-as-a-nested-cluster/ |
|||
* https://fabianlee.org/2018/09/19/kvm-deploying-a-nested-version-of-vmware-esxi-6-7-inside-kvm/ |
|||
* http://vnews.fr/construire-un-custom-iso-de-vmware-vsphere-esxi-6/ |
|||
@ -0,0 +1,21 @@ |
|||
terraform { |
|||
required_version = ">= 0.13" |
|||
required_providers { |
|||
libvirt = { |
|||
source = "dmacvicar/libvirt" |
|||
version = ">=0.6.3" |
|||
} |
|||
local = { |
|||
source = "hashicorp/local" |
|||
version = ">=2.0.0" |
|||
} |
|||
template = { |
|||
source = "hashicorp/template" |
|||
version = ">=2.2.0" |
|||
} |
|||
} |
|||
} |
|||
|
|||
output "machines" { |
|||
value = local.vsphere_machines |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
resource "libvirt_network" "lab_net" { |
|||
name = var.network_name |
|||
mode = "nat" |
|||
domain = var.network_domain |
|||
addresses = [var.network_ip_range] |
|||
autostart = true |
|||
dns { |
|||
enabled = true |
|||
} |
|||
dhcp { |
|||
enabled = true |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?xml version="1.0" ?> |
|||
<xsl:stylesheet version="1.0" |
|||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
|||
<xsl:output omit-xml-declaration="yes" indent="yes"/> |
|||
|
|||
<!-- XSLT Identity template --> |
|||
<xsl:template match="node()|@*"> |
|||
<xsl:copy> |
|||
<xsl:apply-templates select="node()|@*"/> |
|||
</xsl:copy> |
|||
</xsl:template> |
|||
|
|||
<!-- Change the NIC model to e1000e --> |
|||
<xsl:template match="/domain/devices/interface[@type='network']/model/@type"> |
|||
<xsl:attribute name="type"> |
|||
<xsl:value-of select="'e1000e'"/> |
|||
</xsl:attribute> |
|||
</xsl:template> |
|||
|
|||
<!-- Change all disks to SATA and renumber them (sda, sdb, etc.)--> |
|||
<xsl:template match="/domain/devices"> |
|||
<xsl:copy> |
|||
<xsl:apply-templates select="@*|node()[not(ancestor-or-self::disk)]"/> |
|||
<xsl:for-each select="disk"> |
|||
<disk> |
|||
<xsl:apply-templates select="@*|node()[not(ancestor-or-self::target | ancestor-or-self::wwn)]"/> |
|||
<target bus="sata" rotation_rate="1"> |
|||
<xsl:attribute name="rotation_rate"> |
|||
<!-- Disk is an SSD --> |
|||
<xsl:value-of select="'1'" /> |
|||
<!-- Disk is an HDD (7200 RPM) --> |
|||
<!-- <xsl:value-of select="'7200'" /> --> |
|||
</xsl:attribute> |
|||
<xsl:attribute name="dev"> |
|||
<xsl:value-of select="'sd'" /><xsl:number value="position()" format="a"/> |
|||
</xsl:attribute> |
|||
</target> |
|||
</disk> |
|||
</xsl:for-each> |
|||
</xsl:copy> |
|||
</xsl:template> |
|||
|
|||
<!-- Hide KVM for the guest --> |
|||
<xsl:template match="/*"> |
|||
<xsl:copy> |
|||
<xsl:apply-templates select="@*|node()"/> |
|||
<features> |
|||
<kvm> |
|||
<hidden state='on'/> |
|||
</kvm> |
|||
</features> |
|||
</xsl:copy> |
|||
</xsl:template> |
|||
|
|||
</xsl:stylesheet> |
|||
@ -0,0 +1,3 @@ |
|||
provider "libvirt" { |
|||
uri = "qemu:///system" |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
variable "vsphere_machine_count" { |
|||
type = number |
|||
default = 1 |
|||
} |
|||
|
|||
variable "pool_name" { |
|||
type = string |
|||
default = "default" |
|||
} |
|||
|
|||
variable "volume_format" { |
|||
type = string |
|||
default = "qcow2" |
|||
} |
|||
|
|||
variable "os_volume_size" { |
|||
type = number |
|||
default = 16 * 1024 * 1024 * 1024 |
|||
} |
|||
|
|||
variable "kvm_machine" { |
|||
type = string |
|||
default = "pc-q35-rhel8.2.0" |
|||
} |
|||
|
|||
variable "vmfs_volume_size" { |
|||
type = number |
|||
default = 200 * 1024 * 1024 * 1024 |
|||
} |
|||
|
|||
variable "vcpu_count" { |
|||
type = number |
|||
default = 4 |
|||
} |
|||
|
|||
variable "memory_size" { |
|||
type = number |
|||
default = 8192 |
|||
} |
|||
|
|||
|
|||
variable "vsphere_hostname_format" { |
|||
type = string |
|||
default = "esx-%02d" |
|||
} |
|||
|
|||
variable "vsphere_iso" { |
|||
type = string |
|||
default = "/var/lib/libvirt/images/vsphere-custom.iso" |
|||
} |
|||
|
|||
variable "network_name" { |
|||
type = string |
|||
default = "lab" |
|||
} |
|||
|
|||
variable "network_domain" { |
|||
type = string |
|||
default = "sample.lab" |
|||
} |
|||
|
|||
variable "bridge_network" { |
|||
type = string |
|||
default = "bridge" |
|||
} |
|||
|
|||
variable "network_ip_range" { |
|||
type = string |
|||
default = "10.10.0.0/24" |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
resource "libvirt_volume" "vsphere_os_disk" { |
|||
name = "${format(var.vsphere_hostname_format, count.index + 1)}-os.${var.volume_format}" |
|||
count = var.vsphere_machine_count |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
size = var.os_volume_size |
|||
} |
|||
|
|||
resource "libvirt_volume" "vsphere_vmfs_disk" { |
|||
name = "${format(var.vsphere_hostname_format, count.index + 1)}-vmfs.${var.volume_format}" |
|||
count = var.vsphere_machine_count |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
size = var.vmfs_volume_size |
|||
} |
|||
|
|||
resource "libvirt_domain" "vsphere_machine" { |
|||
count = var.vsphere_machine_count |
|||
name = format(var.vsphere_hostname_format, count.index + 1) |
|||
vcpu = var.vcpu_count |
|||
memory = var.memory_size |
|||
machine = var.kvm_machine |
|||
|
|||
boot_device { |
|||
dev = ["hd", "cdrom"] |
|||
} |
|||
|
|||
disk { |
|||
volume_id = element(libvirt_volume.vsphere_os_disk.*.id, count.index) |
|||
} |
|||
|
|||
disk { |
|||
volume_id = element(libvirt_volume.vsphere_vmfs_disk.*.id, count.index) |
|||
} |
|||
|
|||
cpu = { |
|||
mode = "host-passthrough" |
|||
} |
|||
|
|||
disk { |
|||
file = var.vsphere_iso |
|||
} |
|||
|
|||
graphics { |
|||
type = "vnc" |
|||
listen_type = "address" |
|||
} |
|||
|
|||
video { |
|||
type = "qxl" |
|||
} |
|||
|
|||
network_interface { |
|||
network_id = libvirt_network.lab_net.id |
|||
addresses = [cidrhost(var.network_ip_range, count.index + 11)] |
|||
hostname = format(var.vsphere_hostname_format, count.index + 1) |
|||
wait_for_lease = true |
|||
} |
|||
|
|||
xml { |
|||
xslt = file("patch.xslt") |
|||
} |
|||
} |
|||
|
|||
locals { |
|||
vsphere_machines = { for i in libvirt_domain.vsphere_machine : i.name => i.network_interface.0.addresses[0] } |
|||
} |
|||
Loading…
Reference in new issue