diff --git a/docs/data-sources/host.md b/docs/data-sources/host.md
new file mode 100644
index 0000000..15f89b0
--- /dev/null
+++ b/docs/data-sources/host.md
@@ -0,0 +1,141 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "vcf_host Data Source - terraform-provider-vcf"
+subcategory: ""
+description: |-
+
+---
+
+# vcf_host (Data Source)
+
+The `vcf_host` data source provides information about an ESXi host in a VMware Cloud Foundation environment.
+
+
+## Schema
+
+### Required
+
+- `fqdn` (String) The fully qualified domain name of the ESXi host.
+
+### Read-Only
+
+- `cluster` (List of Object) The cluster information of the ESXi host. (see [below for nested schema](#nestedatt--cluster))
+- `cpu` (List of Object) The CPU information of the ESXi host. (see [below for nested schema](#nestedatt--cpu))
+- `domain` (List of Object) The workload domain information of the ESXi host. (see [below for nested schema](#nestedatt--domain))
+- `hardware` (List of Object) The hardware information of the ESXi host. (see [below for nested schema](#nestedatt--hardware))
+- `id` (String) The ID of the ESXi host.
+- `ip_addresses` (List of Object) The IP addresses information of the ESXi host. (see [below for nested schema](#nestedatt--ip_addresses))
+- `memory` (List of Object) The memory information of the ESXi host. (see [below for nested schema](#nestedatt--memory))
+- `network_pool` (List of Object) The network pool associated with the ESXi host. (see [below for nested schema](#nestedatt--network_pool))
+- `physical_nics` (List of Object) The physical NICs information of the ESXi host. (see [below for nested schema](#nestedatt--physical_nics))
+- `status` (String) The status of the ESXi host.
+- `storage` (List of Object) The storage information of the ESXi host. (see [below for nested schema](#nestedatt--storage))
+- `storage_type` (String) The storage type of the ESXi host.
+- `version` (String) The version of the ESXi running on the host.
+
+
+
+### Nested Schema for `cluster`
+
+Read-Only:
+
+- `id` (String)
+
+
+
+### Nested Schema for `cpu`
+
+Read-Only:
+
+- `cores` (Number)
+- `cpu_cores` (List of Object) (see [below for nested schema](#nestedobjatt--cpu--cpu_cores))
+- `frequency_mhz` (Number)
+- `used_frequency_mhz` (Number)
+
+
+
+### Nested Schema for `cpu.cpu_cores`
+
+Read-Only:
+
+- `frequency_mhz` (Number)
+- `manufacturer` (String)
+- `model` (String)
+
+
+
+### Nested Schema for `domain`
+
+Read-Only:
+
+- `id` (String)
+- `name` (String)
+
+
+
+### Nested Schema for `hardware`
+
+Read-Only:
+
+- `hybrid` (Boolean)
+- `model` (String)
+- `vendor` (String)
+
+
+
+### Nested Schema for `ip_addresses`
+
+Read-Only:
+
+- `ip_address` (String)
+- `type` (String)
+
+
+
+### Nested Schema for `memory`
+
+Read-Only:
+
+- `total_capacity_mb` (Number)
+- `used_capacity_mb` (Number)
+
+
+
+### Nested Schema for `network_pool`
+
+Read-Only:
+
+- `id` (String)
+- `name` (String)
+
+
+
+### Nested Schema for `physical_nics`
+
+Read-Only:
+
+- `device_name` (String)
+- `mac_address` (String)
+- `speed` (Number)
+- `unit` (String)
+
+
+
+### Nested Schema for `storage`
+
+Read-Only:
+
+- `disks` (List of Object) (see [below for nested schema](#nestedobjatt--storage--disks))
+- `total_capacity_mb` (Number)
+- `used_capacity_mb` (Number)
+
+
+
+### Nested Schema for `storage.disks`
+
+Read-Only:
+
+- `capacity_mb` (Number)
+- `disk_type` (String)
+- `manufacturer` (String)
+- `model` (String)
diff --git a/examples/data-sources/host/variables.tf b/examples/data-sources/host/variables.tf
new file mode 100644
index 0000000..9e69411
--- /dev/null
+++ b/examples/data-sources/host/variables.tf
@@ -0,0 +1,22 @@
+variable "sddc_manager_host" {
+ type = string
+ description = "The fully qualified domain name of the SDDC Manager instance."
+}
+
+variable "sddc_manager_username" {
+ type = string
+ description = "The username to authenticate to the SDDC Manager instance."
+ sensitive = true
+}
+
+variable "sddc_manager_password" {
+ type = string
+ description = "The password to authenticate to the SDDC Manager instance."
+ sensitive = true
+}
+
+variable "host_fqdn" {
+ type = string
+ description = "The fully qualified domain name of the ESXi host."
+ default = "sfo-w01-esx01.sfo.rainpole.io"
+}
diff --git a/examples/data-sources/host/vcf_host.tf b/examples/data-sources/host/vcf_host.tf
new file mode 100644
index 0000000..b8f3132
--- /dev/null
+++ b/examples/data-sources/host/vcf_host.tf
@@ -0,0 +1,131 @@
+terraform {
+ required_providers {
+ vcf = {
+ source = "vmware/vcf"
+ }
+ }
+}
+
+provider "vcf" {
+ sddc_manager_username = var.sddc_manager_username
+ sddc_manager_password = var.sddc_manager_password
+ sddc_manager_host = var.sddc_manager_host
+}
+
+data "vcf_host" "example" {
+ fqdn = var.host_fqdn
+}
+
+output "host_id" {
+ value = data.vcf_host.example.id
+}
+
+output "host_fqdn" {
+ value = data.vcf_host.example.fqdn
+}
+
+output "host_hardware" {
+ value = [
+ for hw in data.vcf_host.example.hardware : {
+ hybrid = hw.hybrid
+ model = hw.model
+ vendor = hw.vendor
+ }
+ ]
+}
+
+output "host_version" {
+ value = data.vcf_host.example.version
+}
+
+output "host_status" {
+ value = data.vcf_host.example.status
+}
+
+output "host_domain" {
+ value = [
+ for domain in data.vcf_host.example.domain : {
+ id = domain.id
+ }
+ ]
+}
+
+output "host_cluster" {
+ value = [
+ for cluster in data.vcf_host.example.cluster : {
+ id = cluster.id
+ }
+ ]
+}
+
+output "host_network_pool" {
+ value = [
+ for pool in data.vcf_host.example.network_pool : {
+ id = pool.id
+ name = pool.name
+ }
+ ]
+}
+
+output "host_cpu" {
+ value = [
+ for cpu in coalesce(tolist(data.vcf_host.example.cpu), []) : {
+ cores = cpu.cores
+ frequency_mhz = cpu.frequency_mhz
+ used_frequency_mhz = cpu.used_frequency_mhz
+ cpu_cores = [
+ for core in coalesce(tolist(cpu.cpu_cores), []) : {
+ frequency_mhz = core.frequency_mhz
+ manufacturer = core.manufacturer
+ model = core.model
+ }
+ ]
+ }
+ ]
+}
+
+output "host_memory" {
+ value = [
+ for mem in data.vcf_host.example.memory : {
+ total_capacity_mb = mem.total_capacity_mb
+ used_capacity_mb = mem.used_capacity_mb
+ }
+ ]
+}
+
+output "host_storage" {
+ value = [
+ for storage in coalesce(tolist(data.vcf_host.example.storage), []) : {
+ total_capacity_mb = storage.total_capacity_mb
+ used_capacity_mb = storage.used_capacity_mb
+ disks = [
+ for disk in coalesce(tolist(storage.disks), []) : {
+ capacity_mb = disk.capacity_mb
+ disk_type = disk.disk_type
+ manufacturer = disk.manufacturer
+ model = disk.model
+ }
+ ]
+ }
+ ]
+}
+
+output "host_physical_nics" {
+ value = [
+ for nic in data.vcf_host.example.physical_nics : {
+ device_name = nic.device_name
+ mac_address = nic.mac_address
+ speed = nic.speed
+ unit = nic.unit
+ }
+ ]
+}
+
+output "host_ip_addresses" {
+ value = [
+ for ip in data.vcf_host.example.ip_addresses : {
+ ip_address = ip.ip_address
+ type = ip.type
+ }
+ ]
+}
diff --git a/internal/provider/data_host.go b/internal/provider/data_host.go
new file mode 100644
index 0000000..933dfc6
--- /dev/null
+++ b/internal/provider/data_host.go
@@ -0,0 +1,455 @@
+// © Broadcom. All Rights Reserved.
+// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+import (
+ "context"
+ "errors"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/vmware/vcf-sdk-go/client"
+ "github.com/vmware/vcf-sdk-go/client/hosts"
+ "github.com/vmware/vcf-sdk-go/models"
+
+ "github.com/vmware/terraform-provider-vcf/internal/api_client"
+ "github.com/vmware/terraform-provider-vcf/internal/constants"
+)
+
+func DataSourceHost() *schema.Resource {
+ return &schema.Resource{
+ ReadContext: dataSourceHostRead,
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The ID of the ESXi host.",
+ },
+ "fqdn": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The fully qualified domain name of the ESXi host.",
+ },
+ "hardware": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The hardware information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "model": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The hardware model of the ESXi host.",
+ },
+ "vendor": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The hardware vendor of the ESXi host.",
+ },
+ "hybrid": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: "Indicates if the ESXi host is hybrid.",
+ },
+ },
+ },
+ },
+ "version": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The version of the ESXi running on the host.",
+ },
+ "status": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The status of the ESXi host.",
+ },
+ "domain": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The workload domain information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The ID of the workload domain.",
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of the workload domain.",
+ },
+ },
+ },
+ },
+ "cluster": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The cluster information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The ID of the cluster.",
+ },
+ },
+ },
+ },
+ "network_pool": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The network pool associated with the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The name of the network pool.",
+ },
+ "id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The ID of the network pool.",
+ },
+ },
+ },
+ },
+ "cpu": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The CPU information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "cores": {
+ Type: schema.TypeInt,
+ Computed: true,
+ Description: "Number of CPU cores.",
+ },
+ "cpu_cores": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "Information about each of the CPU cores.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "frequency_mhz": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "The frequency of the CPU core in MHz.",
+ },
+ "manufacturer": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The manufacturer of the CPU.",
+ },
+ "model": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The model of the CPU.",
+ },
+ },
+ },
+ },
+ "frequency_mhz": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "Total CPU frequency in MHz.",
+ },
+ "used_frequency_mhz": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "Used CPU frequency in MHz.",
+ },
+ },
+ },
+ },
+ "memory": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The memory information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "total_capacity_mb": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "The total memory capacity in MB.",
+ },
+ "used_capacity_mb": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "The used memory capacity in MB.",
+ },
+ },
+ },
+ },
+ "storage_type": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The storage type of the ESXi host.",
+ },
+ "storage": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The storage information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "total_capacity_mb": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "The total storage capacity in MB.",
+ },
+ "used_capacity_mb": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "The used storage capacity in MB.",
+ },
+ "disks": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The disks information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "capacity_mb": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "The capacity of the disk in MB.",
+ },
+ "disk_type": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The type of the disk.",
+ },
+ "manufacturer": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The manufacturer of the disk.",
+ },
+ "model": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The model of the disk.",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "physical_nics": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The physical NICs information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "device_name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The device name of the NIC.",
+ },
+ "mac_address": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The MAC address of the NIC.",
+ },
+ "speed": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ Description: "The speed of the NIC.",
+ },
+ "unit": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The unit of the NIC speed.",
+ },
+ },
+ },
+ },
+ "ip_addresses": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "The IP addresses information of the ESXi host.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "ip_address": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The IP address.",
+ },
+ "type": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The type of the IP address.",
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func dataSourceHostRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ apiClient := meta.(*api_client.SddcManagerClient).ApiClient
+
+ fqdn := d.Get("fqdn").(string)
+ host, err := getHostByFqdn(ctx, apiClient, fqdn)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(host.ID)
+
+ // Fully qualified domain name information.
+ _ = d.Set("fqdn", host.Fqdn)
+
+ // Hardware information.
+ hardware := []map[string]interface{}{
+ {
+ "model": host.HardwareModel,
+ "vendor": host.HardwareVendor,
+ "hybrid": host.Hybrid,
+ },
+ }
+ _ = d.Set("hardware", hardware)
+
+ // ESXi version information.
+ _ = d.Set("version", host.EsxiVersion)
+
+ // Status information.
+ _ = d.Set("status", host.Status)
+
+ // Domain information.
+ domain := []map[string]interface{}{
+ {
+ "id": host.Domain.ID,
+ "name": host.Domain.Name,
+ },
+ }
+ _ = d.Set("domain", domain)
+
+ // Cluster information.
+ cluster := []map[string]interface{}{
+ {
+ "id": host.Cluster.ID,
+ },
+ }
+ _ = d.Set("cluster", cluster)
+
+ // Network pool information.
+ networkPool := []map[string]interface{}{
+ {
+ "id": host.Networkpool.ID,
+ "name": host.Networkpool.Name,
+ },
+ }
+ _ = d.Set("network_pool", networkPool)
+
+ // CPU information.
+ cpuCores := []map[string]interface{}{}
+ for _, core := range host.CPU.CPUCores {
+ cpuCore := map[string]interface{}{
+ "frequency_mhz": core.FrequencyMHz,
+ "manufacturer": core.Manufacturer,
+ "model": core.Model,
+ }
+ cpuCores = append(cpuCores, cpuCore)
+ }
+
+ cpu := map[string]interface{}{
+ "cores": host.CPU.Cores,
+ "cpu_cores": cpuCores,
+ "frequency_mhz": host.CPU.FrequencyMHz,
+ "used_frequency_mhz": host.CPU.UsedFrequencyMHz,
+ }
+
+ if err := d.Set("cpu", []interface{}{cpu}); err != nil {
+ return diag.FromErr(err)
+ }
+
+ // Memory information.
+ memory := []map[string]interface{}{
+ {
+ "total_capacity_mb": host.Memory.TotalCapacityMB,
+ "used_capacity_mb": host.Memory.UsedCapacityMB,
+ },
+ }
+ _ = d.Set("memory", memory)
+
+ // Compatible storage type information.
+ _ = d.Set("compatible_storage_type", host.CompatibleStorageType)
+
+ // Storage information.
+ disks := []map[string]interface{}{}
+ for _, disk := range host.Storage.Disks {
+ diskInfo := map[string]interface{}{
+ "capacity_mb": disk.CapacityMB,
+ "disk_type": disk.DiskType,
+ "manufacturer": disk.Manufacturer,
+ "model": disk.Model,
+ }
+ disks = append(disks, diskInfo)
+ }
+
+ storage := []map[string]interface{}{
+ {
+ "total_capacity_mb": host.Storage.TotalCapacityMB,
+ "used_capacity_mb": host.Storage.UsedCapacityMB,
+ "disks": disks,
+ },
+ }
+ _ = d.Set("storage", storage)
+
+ // Physical NICs information.
+ physicalNics := []map[string]interface{}{}
+ for _, nic := range host.PhysicalNics {
+ physicalNic := map[string]interface{}{
+ "device_name": nic.DeviceName,
+ "mac_address": nic.MacAddress,
+ "speed": nic.Speed,
+ "unit": nic.Unit,
+ }
+ physicalNics = append(physicalNics, physicalNic)
+ }
+ _ = d.Set("physical_nics", physicalNics)
+
+ // IP addresses information.
+ ipAddresses := []map[string]interface{}{}
+ for _, ip := range host.IPAddresses {
+ ipAddress := map[string]interface{}{
+ "ip_address": ip.IPAddress,
+ "type": ip.Type,
+ }
+ ipAddresses = append(ipAddresses, ipAddress)
+ }
+ _ = d.Set("ip_addresses", ipAddresses)
+
+ return nil
+}
+
+func getHostByFqdn(ctx context.Context, apiClient *client.VcfClient, fqdn string) (*models.Host, error) {
+ params := hosts.NewGetHostsParamsWithContext(ctx).
+ WithTimeout(constants.DefaultVcfApiCallTimeout)
+
+ hostPayload, err := apiClient.Hosts.GetHosts(params)
+ if err != nil {
+ return nil, err
+ }
+
+ if hostPayload.Payload == nil || len(hostPayload.Payload.Elements) == 0 {
+ return nil, errors.New("no hosts found")
+ }
+
+ for _, element := range hostPayload.Payload.Elements {
+ if element == nil {
+ continue
+ }
+
+ if element.Fqdn == fqdn {
+ return element, nil
+ }
+ }
+
+ return nil, errors.New("host not found")
+}
diff --git a/internal/provider/data_host_test.go b/internal/provider/data_host_test.go
new file mode 100644
index 0000000..97bf334
--- /dev/null
+++ b/internal/provider/data_host_test.go
@@ -0,0 +1,56 @@
+// © Broadcom. All Rights Reserved.
+// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+
+ "github.com/vmware/terraform-provider-vcf/internal/constants"
+)
+
+func TestAccDataSourceVcfHost(t *testing.T) {
+ hosts := []string{
+ constants.VcfTestHost1Fqdn,
+ constants.VcfTestHost2Fqdn,
+ constants.VcfTestHost3Fqdn,
+ constants.VcfTestHost4Fqdn,
+ }
+
+ var steps []resource.TestStep
+ for _, fqdn := range hosts {
+ steps = append(steps, resource.TestStep{
+ Config: testAccDataSourceVcfHostConfig(fqdn),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttrSet("data.vcf_host.test_host", "id"),
+ resource.TestCheckResourceAttr("data.vcf_host.test_host", "fqdn", fqdn),
+ ),
+ })
+ }
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: muxedFactories(),
+ Steps: steps,
+ })
+}
+
+func testAccDataSourceVcfHostConfig(hostFqdn string) string {
+ return fmt.Sprintf(`
+ resource "vcf_host" "test_host" {
+ fqdn = %q
+ username = "root"
+ password = "password"
+ network_pool_id = "test_network_pool_id"
+ storage_type = "VSAN"
+ }
+
+ data "vcf_host" "test_host" {
+ fqdn = vcf_host.test_host.fqdn
+ }
+ `, hostFqdn)
+}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 2633b4f..2967085 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -76,8 +76,9 @@ func Provider() *schema.Provider {
DataSourcesMap: map[string]*schema.Resource{
"vcf_cluster": DataSourceCluster(),
- "vcf_domain": DataSourceDomain(),
"vcf_credentials": DataSourceCredentials(),
+ "vcf_domain": DataSourceDomain(),
+ "vcf_host": DataSourceHost(),
"vcf_network_pool": DataSourceNetworkPool(),
"vcf_certificate": DataSourceCertificate(),
},