Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ node_modules/
tmp/
.cache/

# Local .terraform directories
.terraform/

# .tfstate files
*.tfstate
*.tfstate.*
Expand Down Expand Up @@ -127,3 +124,14 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc

# Local state (shouldn't exist with cloud backend, but belt-and-suspenders)
*.tfstate
*.tfstate.*
.terraform/
.terraform.lock.hcl

# Never commit real variable values / secrets
terraform.tfvars
*.auto.tfvars
secrets.tf
50 changes: 50 additions & 0 deletions tfe/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ---------------------------------------------------------------------------
# v3-API resources (works on AOS 6.8.1 / your PC version; v4 / *_v2 resources
# require AOS 7.0 + pc.2024.3 which this cluster doesn't run).
# Provider talks to Prism Central. Credentials come from NUTANIX_* env vars
Comment thread
rgardner4012 marked this conversation as resolved.
# set as sensitive workspace variables.
# ---------------------------------------------------------------------------

# Discover the cluster by name. On v3 the data source returns .id (= cluster UUID).
Comment thread
rgardner4012 marked this conversation as resolved.
data "nutanix_clusters" "clusters" {}

locals {
# Build a name->uuid map of clusters registered to PC, then pick ours by name.
# On single-node CE there's one PE cluster; var.cluster_name must match what
# PE/PC shows (you named it "cluster1").
cluster_uuid = one([
for c in data.nutanix_clusters.clusters.entities : c.metadata.uuid
if c.name == var.cluster_name
])
}

# Look up the subnet by name -> returns .id (subnet UUID).
data "nutanix_subnet" "subnet" {
subnet_name = var.subnet_name
}

resource "nutanix_virtual_machine" "lab" {
name = var.vm_name
description = "TF lab smoke-test VM (Pattern B, v3 API)"
cluster_uuid = local.cluster_uuid
num_sockets = 1
num_vcpus_per_socket = 1
memory_size_mib = var.memory_mib # MiB in v3 — no float/whole-number bug

nic_list {
subnet_uuid = data.nutanix_subnet.subnet.id
}

# Empty boot disk (no image yet). Goal of this phase: prove HCP -> agent ->
# Prism Central creates a VM. Image + cloud-init come next iteration.
disk_list {
disk_size_mib = var.disk_mib
device_properties {
Comment thread
rgardner4012 marked this conversation as resolved.
device_type = "DISK"
disk_address = {
adapter_type = "SCSI"
device_index = 0
}
}
}
}
18 changes: 18 additions & 0 deletions tfe/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
output "vm_uuid" {
description = "The created VM's UUID."
value = nutanix_virtual_machine.lab.id
}

output "vm_name" {
value = nutanix_virtual_machine.lab.name
}

# v3 surfaces the learned IP under nic_list_status. Empty until the guest boots
# with an OS that gets an address — wired now for the Phase 4 AAP hand-off.
output "vm_ip_address" {
description = "Assigned IPv4 address, once the guest has booted with an OS."
value = try(
nutanix_virtual_machine.lab.nic_list_status[0].ip_endpoint_list[0].ip,
""
)
}
15 changes: 15 additions & 0 deletions tfe/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Provider credentials come from sensitive WORKSPACE VARIABLES in HCP, set as
# environment variables (env category):
# NUTANIX_ENDPOINT = 192.168.0.39 (Prism Central host/IP, no scheme, no port)
Comment thread
rgardner4012 marked this conversation as resolved.
# NUTANIX_PORT = 9440
# NUTANIX_USERNAME = admin
# NUTANIX_PASSWORD = <prism password> (mark Sensitive)
# NUTANIX_INSECURE = true (CE uses a self-signed cert)
#
# Because all five are read from NUTANIX_* env vars, the provider block can be
# nearly empty. Nothing secret lives in code or in git.

provider "nutanix" {
# All values sourced from NUTANIX_* environment variables in the workspace.
# Left explicit-but-empty here for documentation; remove if you prefer.
}
19 changes: 19 additions & 0 deletions tfe/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
terraform {
required_version = ">= 1.6"

required_providers {
nutanix = {
source = "nutanix/nutanix"
version = "~> 2.4" # v3-API-based resources still ship in current provider
}
}

# CLI-driven workspace: state + execution in HCP, runs dispatch to your
# in-network agent. `terraform login` once on this machine first.
cloud {
organization = "homelab_nutanix"
workspaces {
name = "hl-dev"
}
}
}
28 changes: 28 additions & 0 deletions tfe/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
variable "vm_name" {
type = string
default = "tf-lab-smoke-01"
}

variable "cluster_name" {
type = string
description = "PE cluster name as shown in Prism (you named it cluster1)."
default = "cluster1"
}

variable "subnet_name" {
type = string
description = "Name of the AHV subnet/network to attach the NIC to."
# No default — set in terraform.tfvars or a workspace variable.
}

variable "memory_mib" {
type = number
description = "VM memory in MiB."
default = 2048 # 2 GiB
}

variable "disk_mib" {
type = number
description = "Boot disk size in MiB."
default = 20480 # 20 GiB
}
Loading