Skip to content
This repository has been archived by the owner on Aug 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #55 from empovit/update-esxi
Browse files Browse the repository at this point in the history
add ESXi upgrade option
  • Loading branch information
displague authored Jun 7, 2024
2 parents f386556 + 1831c16 commit e1265a4
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 29 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ s3_version = "S3v4"
```

### Google Cloud Storage (GCS)
We also have the optoin to use Google Cloud Storage (GCS). The setup will use a service account with Storage Reader permissions to download the needed files.
We also have the option to use Google Cloud Storage (GCS). The setup will use a service account with Storage Reader permissions to download the needed files.

The following settings will be needed in your `terraform.tfvars` to use GCS
```console
Expand Down Expand Up @@ -87,7 +87,7 @@ You will need to find the Python files in the vSAN SDK zip file (`binding/vsanmg

There are many variables which can be set to customize your install within `vars.tf`. The default variables to bring up a 3 node vSphere cluster and linux router using Equinix Metal's [c3.medium.x86](https://metal.equinix.com/product/servers/). Change each default variable at your own risk.

There are some variables you must set with a `terraform.tfvars` files. You need to set `auth_token` & `organization_id` to connect to Equinix Metal and the `project_name` which will be created in Equinix Metal. We will to setup you object store to download "Closed Source" packages such as vCenter. You'll provide the needed variables as descibed above as well as the vCenter ISO file name as `vcenter_iso_name`.
There are some variables you must set with a `terraform.tfvars` files. You need to set `auth_token` & `organization_id` to connect to Equinix Metal and the `project_name` which will be created in Equinix Metal. We will to setup you object store to download "Closed Source" packages such as vCenter. You'll provide the needed variables as described above as well as the vCenter ISO file name as `vcenter_iso_name`.

Here is a quick command plus sample values (assuming an S3 object store) to start file for you (make sure you adjust the variables to match your environment, pay special attention that the `vcenter_iso_name` matches whats in your bucket):

Expand All @@ -104,6 +104,19 @@ vcenter_iso_name = "VMware-VCSA-all-7.0.3-XXXXXXX.iso"
EOF
```

## Upgrading ESXi version

For some servers on Equinix Metal, only an older version of ESXi is available (6.5). You can upgrade such servers to a more recent version by setting `update_esxi = true`, and specifying an `esxi_update_filename` (refer to [VMware ESXi Patch Tracker](https://esxi-patches.v-front.de/) for latest update versions). The upgrade will be performed right after a server has been provisioned, and before vCenter Server installation starts.

```bash
cat <<EOF >>terraform.tfvars
update_esxi = true
esxi_update_filename = "ESXi-7.0U3d-19482537-standard"
EOF
```

A standalone Terraform script for ESXi upgrade is available [here](https://github.com/enkelprifti98/packet-esxi-6-7).

## Deploy the Equinix Metal vSphere cluster

All there is left to do now is to deploy the cluster:
Expand Down
94 changes: 67 additions & 27 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,56 @@ resource "equinix_metal_device" "esxi_hosts" {
}
}

resource "null_resource" "reboot_pre_upgrade" {
depends_on = [equinix_metal_device.esxi_hosts]
count = var.update_esxi ? 1 : 0

provisioner "local-exec" {
command = "sleep 250"
}
}

# Run the ESXi update script file in each server.
# If you make changes to the shell script, you need to update the sed command line number to get rid of te { at the end of the file which gets created by Terraform for some reason.
resource "null_resource" "upgrade_nodes" {

depends_on = [null_resource.reboot_pre_upgrade]
count = var.update_esxi ? length(equinix_metal_device.esxi_hosts) : 0

connection {
user = local.ssh_user
private_key = chomp(tls_private_key.ssh_key_pair.private_key_pem)
host = element(equinix_metal_device.esxi_hosts.*.access_public_ipv4, count.index)
}

provisioner "file" {
content = var.update_esxi ? templatefile("${path.module}/templates/update_esxi.sh.tpl", {
esxi_update_filename = "${var.esxi_update_filename}"

}) : ""
destination = "/tmp/update_esxi.sh"
}

provisioner "remote-exec" {
inline = [
"sed -i '27d' /tmp/update_esxi.sh",
"echo 'Running update script on remote host.'",
"chmod +x /tmp/update_esxi.sh",
"/tmp/update_esxi.sh"
]
}
}

resource "null_resource" "reboot_post_upgrade" {

depends_on = [null_resource.upgrade_nodes]
count = var.update_esxi ? 1 : 0

provisioner "local-exec" {
command = "sleep 250"
}
}

resource "equinix_metal_port" "esxi_hosts" {
count = length(equinix_metal_device.esxi_hosts)
bonded = false
Expand All @@ -152,7 +202,6 @@ resource "equinix_metal_port" "esxi_hosts" {
}
}


resource "null_resource" "run_pre_reqs" {
connection {
type = "ssh"
Expand Down Expand Up @@ -198,20 +247,6 @@ resource "null_resource" "run_pre_reqs" {
}
}

data "template_file" "download_vcenter" {
template = file("${path.module}/templates/download_vcenter.sh")
vars = {
object_store_bucket_name = var.object_store_bucket_name
object_store_tool = var.object_store_tool
s3_url = var.s3_url
s3_access_key = var.s3_access_key
s3_secret_key = var.s3_secret_key
s3_version = var.s3_version
vcenter_iso_name = var.vcenter_iso_name
ssh_private_key = chomp(tls_private_key.ssh_key_pair.private_key_pem)
}
}

resource "null_resource" "copy_gcs_key" {
count = var.object_store_tool == "gcs" ? 1 : 0
depends_on = [null_resource.run_pre_reqs]
Expand Down Expand Up @@ -240,7 +275,17 @@ resource "null_resource" "download_vcenter_iso" {
}

provisioner "file" {
content = data.template_file.download_vcenter.rendered
content = templatefile("${path.module}/templates/download_vcenter.sh", {
object_store_bucket_name = var.object_store_bucket_name
object_store_tool = var.object_store_tool
s3_url = var.s3_url
s3_access_key = var.s3_access_key
s3_secret_key = var.s3_secret_key
s3_version = var.s3_version
vcenter_iso_name = var.vcenter_iso_name
ssh_private_key = chomp(tls_private_key.ssh_key_pair.private_key_pem)
})

destination = "bootstrap/download_vcenter.sh"
}

Expand Down Expand Up @@ -269,16 +314,6 @@ resource "random_password" "vpn_pass" {
special = true
}


data "template_file" "vpn_installer" {
template = file("${path.module}/templates/l2tp_vpn.sh")
vars = {
ipsec_psk = random_password.ipsec_psk.result
vpn_user = var.vpn_user
vpn_pass = random_password.vpn_pass.result
}
}

resource "null_resource" "install_vpn_server" {
depends_on = [
null_resource.run_pre_reqs,
Expand All @@ -292,7 +327,11 @@ resource "null_resource" "install_vpn_server" {
}

provisioner "file" {
content = data.template_file.vpn_installer.rendered
content = templatefile("${path.module}/templates/l2tp_vpn.sh", {
ipsec_psk = random_password.ipsec_psk.result
vpn_user = var.vpn_user
vpn_pass = random_password.vpn_pass.result
})
destination = "bootstrap/vpn_installer.sh"
}

Expand Down Expand Up @@ -381,6 +420,7 @@ resource "null_resource" "esx_network_prereqs" {
resource "null_resource" "apply_esx_network_config" {
count = length(equinix_metal_device.esxi_hosts)
depends_on = [
null_resource.reboot_post_upgrade,
equinix_metal_port.esxi_hosts,
null_resource.esx_network_prereqs,
null_resource.copy_update_uplinks,
Expand Down
26 changes: 26 additions & 0 deletions templates/update_esxi.sh.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh
# There is no bash on ESXi, only sh (but not a real sh, just busybox).
# Determine the latest ESXi update here:
# https://esxi-patches.v-front.de/

# SSH and Shell are enabled by default on Equinix Metal ESXi servers

echo "Enabling swap"
# Swap must be enabled on the datastore. Otherwise, the upgrade may fail with a "no space left" error.
esxcli sched swap system set --datastore-enabled true
esxcli sched swap system set --datastore-name datastore1

# Update to your specified version of ESXi in the variables.tf file
vim-cmd /hostsvc/maintenance_mode_enter

esxcli network firewall ruleset set -e true -r httpClient

echo "Getting update file and updating"
# The variable esxi_update_filename is in the variables.tf file
esxcli software profile update -d https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml -p ${esxi_update_filename}

esxcli network firewall ruleset set -e false -r httpClient

vim-cmd /hostsvc/maintenance_mode_exit

reboot
16 changes: 16 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,19 @@ variable "vcva_deployment_option" {
type = string
default = "small"
}

variable "update_esxi" {
description = "if true update the ESXi version before proceeding to vCenter installation"
type = bool
default = false
}

variable "esxi_update_filename" {
description = <<-EOF
The specific update version that your servers will be updated to.
Note that the Equinix Metal portal and API will still show ESXi 6.5 as the OS but this script adds a tag with the update filename specified below.
You can check all ESXi update versions/filenames here: https://esxi-patches.v-front.de/
EOF
type = string
default = "ESXi-7.0U3d-19482537-standard"
}

0 comments on commit e1265a4

Please sign in to comment.