Repository: Terraform-VMWare-Modules/terraform-vsphere-vm Branch: master Commit: e47cf7eb9006 Files: 28 Total size: 61.6 KB Directory structure: gitextract_pni6tlpg/ ├── .github/ │ └── stale.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples/ │ ├── README.md │ ├── example-Windows-data_disk.tf │ ├── example-linux-Network.tf │ ├── example-linux-depend_on.tf │ └── example-vmname.tf ├── main.tf ├── output.tf ├── tests/ │ ├── sanity/ │ │ ├── .terraform.lock.hcl │ │ ├── README.md │ │ ├── apply.sh │ │ ├── cleanup.sh │ │ ├── connection.tf │ │ ├── main.tf │ │ └── plan.sh │ └── smoke/ │ ├── .terraform.lock.hcl │ ├── README.md │ ├── apply.sh │ ├── connection.tf │ ├── main.tf │ └── plan.sh ├── variables.tf └── versions.tf ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/stale.yml ================================================ # Number of days of inactivity before an issue becomes stale daysUntilStale: 30 # Number of days of inactivity before a stale issue is closed daysUntilClose: 7 # Issues with these labels will never be considered stale exemptLabels: - enhancement - pinned # Label to use when marking an issue as stale staleLabel: wontfix # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. # Comment to post when closing a stale issue. Set to `false` to disable closeComment: enable ================================================ FILE: .gitignore ================================================ # Local .terraform directories **/.terraform/* # .tfstate files *.tfstate *.tfstate.* # .tfvars files *.tfvars #Sensetive Info *private* #VIM Junk *.un~ ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at arman@rmaan.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to terraform-vsphere-vm We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: - Reporting a bug - Discussing the current state of the code - Submitting a fix - Proposing new features - Becoming a maintainer ## We Do have a Dedicated Slack Channel You can join the channel using the following [link](https://join.slack.com/t/terraformvmware/shared_invite/zt-elw5yhds-kPT_QMBWaHGLCPkPJKxYeA). ## We Develop with Github We use github to host code, to track issues and feature requests, as well as accept pull requests. ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 1. Fork the repo and create your branch from `master`. 2. If you've added code that should be tested, add tests. 1. This should be done via sanity test section. 2. Attach copy of the passed TF Plan. (Remove sensitive info if necessary) 3. If you've changed variables/functionality, update the documentation. 4. Ensure the test suite passes. 5. Make sure your code lints. 6. Issue that pull request! ## Any contributions you make will be under the MIT Software License In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. ## Report bugs using Github's [issues](https://github.com/Terraform-VMWare-Modules/terraform-vsphere-vm/issues) We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy! ## Write bug reports with detail, background, and sample code **Great Bug Reports** tend to have: - A quick summary and/or background - Steps to reproduce - Be specific! - Give sample code if you can. - What you expected would happen - What actually happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) People *love* thorough bug reports. I'm not even kidding. ## License By contributing, you agree that your contributions will be licensed under its MIT License. ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) Microsoft Corporation. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ================================================ FILE: README.md ================================================ # Terraform vSphere Module ![Terraform Version](https://img.shields.io/badge/Terraform-0.14-green.svg) [![TF Registry](https://img.shields.io/badge/terraform-registry-blue.svg)](https://registry.terraform.io/modules/Terraform-VMWare-Modules/vm/vsphere/) [![Changelog](https://img.shields.io/badge/changelog-release-green.svg)](https://github.com/Terraform-VMWare-Modules/terraform-vsphere-vm/releases) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) For Virtual Machine Provisioning with (Linux/Windows) customization. Based on Terraform v0.13 and up, this module includes most of the advanced features available in resource `vsphere_virtual_machine`. ## Deploys (Single/Multiple) Virtual Machines to your vSphere environment This Terraform module deploys single or multiple virtual machines of type (Linux/Windows) with the following features: - Ability to specify Linux or Windows VM customization. - Ability to add multiple network cards for the VM - Ability to assign tags and custom variables. - Ability to configure advanced features for a VM. - Ability to deploy either a datastore or a datastore cluster. - Add extra data disk (up to 15) to the VM. - Different datastores for data disks (datastore_id). - Different storage policies for data disks (storage_policy_id). - Different scsi_controllers per disk, including data disks. - Ability to define depend on using variable vm_depends_on & tag_depends_on > Note: For the module to work, it needs several required variables corresponding to existing resources in vSphere. Please refer to the variable section for the list of required variables. ## Getting started The following example contains the bare minimum options to be configured for (Linux/Windows) VM deployment. You can choose between Windows and Linux customization by simply using the `is_windows_image` boolean switch. You can also download the entire module and use your predefined variables to map your entire vSphere environment and use it within this module. First, create a `main.tf` file. Next, copy the code below and fill in the required variables. ```hcl # Configure the VMware vSphere Provider provider "vsphere" { user = "fill" password = "fill" vsphere_server = "fill" # if you have a self-signed cert allow_unverified_ssl = true } # Deploy 2 linux VMs module "example-server-linuxvm" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "X.X.X" vmtemp = "VM Template Name (Should Alrerady exist)" instances = 2 vmname = "example-server-linux" vmrp = "esxi/Resources - or name of a resource pool" network = { "Name of the Port Group in vSphere" = ["10.13.113.2", "10.13.113.3"] # To use DHCP create Empty list ["",""]; You can also use a CIDR annotation; } vmgateway = "10.13.113.1" dc = "Datacenter" datastore = "Data Store name(use datastore_cluster for datastore cluster)" } ``` Finally, run ```bash terraform run ``` ## Advanced Usage The module includes several option switches, which you can use to enable various VM provisioning features. - You can use `is_windows_image = true` to set the customization type to Windows (By default, it is Linux customization) - You can use `windomain = "somedomain.com"` to join a Windows server to an AD domain. - Requires following additional variables - `domainuser` - Domain account with necessary privileges to join a computer to the domain. - `domainpass` - Domain user password. - `is_windows_image` needs to be set to `true` to force the module to use Windows customization. > Note: When deploying a windows server in WorkGroup, we recommend keeping the Local Admin password set to its default and change it later via a script. Unfortunately, Terraform will re-deploy the entire server if you change the local admin password. Below is an example of windows deployment with some of the available feature sets. For a complete list of available features, please refer to [variable.tf](https://github.com/Terraform-VMWare-Modules/terraform-vsphere-vm/blob/master/variables.tf) ```hcl module "example-server-windowsvm-advanced" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "X.X.X" dc = "Datacenter" vmrp = "cluster/Resources" #Works with ESXi/Resources vmfolder = "Cattle" datastore_cluster = "Datastore Cluster" #You can use datastore variable instead vmtemp = "TemplateName" instances = 2 vmname = "AdvancedVM" vmnameformat = "%03d" #To use three decimal with leading zero vmnames will be AdvancedVM001,AdvancedVM002 domain = "somedomain.com" network = { "Name of the Port Group in vSphere" = ["10.13.113.2", "10.13.113.3"] # To use DHCP create Empty list ["",""]; You can also use a CIDR annotation; "Second Network Card" = ["", ""] } ipv4submask = ["24", "8"] network_type = ["vmxnet3", "vmxnet3"] tags = { "terraform-test-category" = "terraform-test-tag" } data_disk = { disk1 = { size_gb = 30, thin_provisioned = false, data_disk_scsi_controller = 0, }, disk2 = { size_gb = 70, thin_provisioned = true, data_disk_scsi_controller = 1, datastore_id = "datastore-90679" } } scsi_bus_sharing = "physicalSharing" // The modes are physicalSharing, virtualSharing, and noSharing scsi_type = "lsilogic" // Other acceptable value "pvscsi" scsi_controller = 0 // This will assign OS disk to controller 0 dns_server_list = ["192.168.0.2", "192.168.0.1"] enable_disk_uuid = true vmgateway = "192.168.0.1" auto_logon = true run_once = ["command01", "command02"] // You can also run Powershell commands orgname = "Terraform-Module" workgroup = "Module-Test" is_windows_image = true firmware = "efi" local_adminpass = "Password@Strong" } output "vmnames" { value = module.example-server-windowsvm-advanced.VM } output "vmnameswip" { value = module.example-server-windowsvm-advanced.ip } ``` ## Contributing This module is the work of many contributors. We appreciate your help! To contribute, please read the [contribution guidelines](https://github.com/Terraform-VMWare-Modules/terraform-vsphere-vm/blob/master/CONTRIBUTING.md) ## License [MIT](LICENSE) ================================================ FILE: examples/README.md ================================================ # Terraform vSphere examples This directory contains various examples for deplpyong Linux/Windows VMs to a vSphere vCenter. ## Getting started __Create a connection.tf file and copy the following code.__ ```hcl # Configure the VMware vSphere Provider provider "vsphere" { user = "fill" password = "fill" vsphere_server = "fill" # if you have a self-signed cert allow_unverified_ssl = true } ``` __Copy any of the exmpale tf files and fill the required data then run terraform init/plan/apply.__ ================================================ FILE: examples/example-Windows-data_disk.tf ================================================ data "vsphere_storage_policy" "policy" { name = "policy1" } module "example-server-windowsvm-advanced" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "X.X.X" dc = "Datacenter" vmrp = "cluster/Resources" #Works with ESXi/Resources vmfolder = "Cattle" datastore_cluster = "Datastore Cluster" #You can use datastore variable instead vmtemp = "TemplateName" instances = 2 vmname = "AdvancedVM" domain = "somedomain.com" network = { "Name of the Port Group in vSphere" = ["10.13.113.2", "10.13.113.3"] # To use DHCP create Empty list ["",""] } template_storage_policy_id = [data.vsphere_storage_policy.this.id] #Policy ID for the template disks data_disk = { disk1 = { size_gb = 30, thin_provisioned = false, data_disk_scsi_controller = 0, storage_policy_id = "ff45cc66-b624-4621-967f-1aef6437f568" #Different policy ID for data disks }, disk2 = { size_gb = 70, thin_provisioned = true, data_disk_scsi_controller = 1, datastore_id = "datastore-90679" } } scsi_bus_sharing = "physicalSharing" // The modes are physicalSharing, virtualSharing, and noSharing scsi_type = "lsilogic" // Other acceptable value "pvscsi" scsi_controller = 0 // This will assign OS disk to controller 0 dns_server_list = ["192.168.0.2", "192.168.0.1"] vmgateway = "192.168.0.1" enable_disk_uuid = true orgname = "Terraform-Module" workgroup = "Module-Test" is_windows_image = true firmware = "efi" local_adminpass = "Password@Strong" } ================================================ FILE: examples/example-linux-Network.tf ================================================ // Example of Linux VM with more Advanced Features module "example-server-linuxvm-advanced" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "Latest X.X.X" dc = "Datacenter" vmrp = "cluster/Resources" vmfolder = "Cattle" datastore_cluster = "Datastore Cluster" vmtemp = "TemplateName" instances = 2 vmname = "AdvancedVM" domain = "somedomain.com" ipv4submask = ["24", "8"] network = { "Network01" = ["10.13.113.2", "10.13.113.3"] # To use DHCP create Empty list ["",""] "Network02" = ["", ""] #Second Network will use the DHCP } disk_datastore = "vsanDatastore" dns_server_list = ["192.168.0.2", "192.168.0.1"] vmgateway = "192.168.0.1" network_type = ["vmxnet3", "vmxnet3"] } // Example of Linux VM with Network CIDR module "example-server-linuxvm-advanced" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "Latest X.X.X" dc = "Datacenter" vmrp = "cluster/Resources" vmfolder = "Cattle" datastore_cluster = "Datastore Cluster" vmtemp = "TemplateName" instances = 2 vmname = "AdvancedVM" domain = "somedomain.com" network = { "Network01" = ["10.13.113.2/28", "10.13.113.3/28"] # To use DHCP create Empty list ["",""] "Network02" = ["", ""] #Second Network will use the DHCP "Network03" = ["10.13.0.2/26", "10.13.0.3/26"] } disk_datastore = "vsanDatastore" dns_server_list = ["192.168.0.2", "192.168.0.1"] vmgateway = "192.168.0.1" network_type = ["vmxnet3", "vmxnet3"] } ================================================ FILE: examples/example-linux-depend_on.tf ================================================ // Simple Linux VM deployment module "example-server-linuxvm" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "Latest X.X.X" vmtemp = "TemplateName" instances = 1 vmname = "example-server-windows" vmrp = "esxi/Resources" network = { "Network01" = ["10.13.113.2", "10.13.113.3"] # To use DHCP create Empty list ["",""] "Network02" = ["", ""] #Second Network will use the DHCP } dc = "Datacenter" datastore = "Data Store name(use datastore_cluster for datastore cluster)" } // Example of Linux VM with more Advanced Features module "example-server-linuxvm-advanced" { source = "Terraform-VMWare-Modules/vm/vsphere" vm_depends_on = [module.example-server-linuxvm] # This force the second module to wait for first VM to be created first version = "Latest X.X.X" dc = "Datacenter" vmrp = "cluster/Resources" vmfolder = "Cattle" datastore_cluster = "Datastore Cluster" vmtemp = "TemplateName" instances = 2 cpu_number = 2 ram_size = 2096 cpu_hot_add_enabled = true cpu_hot_remove_enabled = true memory_hot_add_enabled = true vmname = "AdvancedVM" domain = "somedomain.com" ipv4submask = ["24", "8"] network = { "Network01" = ["10.13.113.2", "10.13.113.3"] # To use DHCP create Empty list ["",""] "Network02" = ["", ""] #Second Network will use the DHCP } dns_server_list = ["192.168.0.2", "192.168.0.1"] vmgateway = "192.168.0.1" network_type = ["vmxnet3", "vmxnet3"] tags = { "terraform-test-category" = "terraform-test-tag" "terraform-test-category-02" = "terraform-test-tag-02" } } ================================================ FILE: examples/example-vmname.tf ================================================ // Single VM deployment with literal name module "example-server-single" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "Latest X.X.X" vmtemp = "TemplateName" staticvmname = "liternalvmname" vmrp = "esxi/Resources" network = { "Name of the Port Group in vSphere" = ["10.13.113.2"] } dc = "Datacenter" datastore = "Data Store name(use datastore_cluster for datastore cluster)" } # Vmname Output -> liternalvmname //Sclae out Static VMs variable "name" { default = ["staticvmname", "staticvmname01"] } module "example-server-single" { source = "Terraform-VMWare-Modules/vm/vsphere" for_each = toset(var.name) version = "Latest X.X.X" vmtemp = "TemplateName" staticvmname = "liternalvmname" vmrp = "esxi/Resources" network = { "Name of the Port Group in vSphere" = ["10.13.113.2"] } dc = "Datacenter" datastore = "Data Store name(use datastore_cluster for datastore cluster)" } // Example of multiple VM deployment with complex naming standard # Define Environment Variable to switch between Environments variable "env" { default = "dev" } module "example-server-multi" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "Latest X.X.X" vmtemp = "TemplateName" instances = 2 vmname = "advancevm" vmnameformat = "%03d${var.env}" vmrp = "esxi/Resources" network = { "Name of the Port Group in vSphere" = ["10.13.113.2", ""] } dc = "Datacenter" datastore = "Data Store name(use datastore_cluster for datastore cluster)" } # Vmname Output -> advancevm001dev, advancevm002dev # //Example of appending domain name to vm name module "example-server-fqdnvmname" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "Latest X.X.X" vmtemp = "TemplateName" instances = 2 vmname = "advancevm" vmnameformat = "%03d" domain = "somedomain.com" fqdnvmname = true vmrp = "esxi/Resources" network = { "Name of the Port Group in vSphere" = ["10.13.113.2", ""] } dc = "Datacenter" datastore = "Data Store name(use datastore_cluster for datastore cluster)" } # Vmname Output -> advancevm001.somedomain.com, advancevm002.somedomain.com # //Example of using a starting number other than "1" for the vmname with multiple instances module "example-server-vmstartcount" { source = "Terraform-VMWare-Modules/vm/vsphere" version = "Latest X.X.X" vmtemp = "TemplateName" instances = 2 vmstartcount = 5 vmname = "advancevm" vmnameformat = "%03d" vmrp = "esxi/Resources" network = { "Name of the Port Group in vSphere" = ["10.13.113.2", ""] } dc = "Datacenter" datastore = "Data Store name(use datastore_cluster for datastore cluster)" } # Vmname Output -> advancevm005, advancevm006 ================================================ FILE: main.tf ================================================ data "vsphere_datacenter" "dc" { name = var.dc } data "vsphere_datastore_cluster" "datastore_cluster" { count = var.datastore_cluster != "" ? 1 : 0 name = var.datastore_cluster datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_datastore" "datastore" { count = var.datastore != "" && var.datastore_cluster == "" ? 1 : 0 name = var.datastore datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_datastore" "disk_datastore" { count = var.disk_datastore != "" ? 1 : 0 name = var.disk_datastore datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_resource_pool" "pool" { count = var.vmrp != "" ? 1 : 0 name = var.vmrp datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_network" "network" { count = length(var.network) name = var.network_delimiter != null ? split(var.network_delimiter,keys(var.network)[count.index])[1] : keys(var.network)[count.index] datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_virtual_machine" "template" { count = var.content_library == null ? 1 : 0 name = var.vmtemp datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_content_library" "library" { count = var.content_library != null ? 1 : 0 name = var.content_library depends_on = [var.tag_depends_on] } data "vsphere_content_library_item" "library_item_template" { count = var.content_library != null ? 1 : 0 library_id = data.vsphere_content_library.library[0].id type = "ovf" name = var.vmtemp depends_on = [var.tag_depends_on] } data "vsphere_tag_category" "category" { count = var.tags != null ? length(var.tags) : 0 name = keys(var.tags)[count.index] depends_on = [var.tag_depends_on] } data "vsphere_tag" "tag" { count = var.tags != null ? length(var.tags) : 0 name = var.tags[keys(var.tags)[count.index]] category_id = data.vsphere_tag_category.category[count.index].id depends_on = [var.tag_depends_on] } data "vsphere_folder" "folder" { count = var.vmfolder != null ? 1 : 0 path = "/${data.vsphere_datacenter.dc.name}/vm/${var.vmfolder}" depends_on = [var.vm_depends_on] } locals { interface_count = length(var.ipv4submask) #Used for Subnet handeling template_disk_count = var.content_library == null ? length(data.vsphere_virtual_machine.template[0].disks) : 0 } // Cloning a Linux or Windows VM from a given template. resource "vsphere_virtual_machine" "vm" { count = var.instances depends_on = [var.vm_depends_on] name = "${var.staticvmname != null ? var.staticvmname : format("${var.vmname}${var.vmnameformat}", count.index + var.vmstartcount)}${var.fqdnvmname == true ? ".${var.domain}" : ""}" resource_pool_id = var.vmrp != "" ? data.vsphere_resource_pool.pool[0].id : var.vmrpid folder = var.vmfolder tags = var.tag_ids != null ? var.tag_ids : data.vsphere_tag.tag[*].id custom_attributes = var.custom_attributes annotation = var.annotation extra_config = var.extra_config firmware = var.content_library == null && var.firmware == null ? data.vsphere_virtual_machine.template[0].firmware : var.firmware efi_secure_boot_enabled = var.content_library == null && var.efi_secure_boot == null ? data.vsphere_virtual_machine.template[0].efi_secure_boot_enabled : var.efi_secure_boot enable_disk_uuid = var.content_library == null && var.enable_disk_uuid == null ? data.vsphere_virtual_machine.template[0].enable_disk_uuid : var.enable_disk_uuid storage_policy_id = var.storage_policy_id datastore_cluster_id = var.datastore_cluster != "" ? data.vsphere_datastore_cluster.datastore_cluster[0].id : null datastore_id = var.datastore != "" ? data.vsphere_datastore.datastore[0].id : null num_cpus = var.cpu_number num_cores_per_socket = var.num_cores_per_socket cpu_hot_add_enabled = var.cpu_hot_add_enabled cpu_hot_remove_enabled = var.cpu_hot_remove_enabled cpu_reservation = var.cpu_reservation cpu_share_level = var.cpu_share_level cpu_share_count = var.cpu_share_level == "custom" ? var.cpu_share_count : null memory_reservation = var.memory_reservation memory = var.ram_size memory_hot_add_enabled = var.memory_hot_add_enabled memory_share_level = var.memory_share_level memory_share_count = var.memory_share_level == "custom" ? var.memory_share_count : null guest_id = var.content_library == null ? data.vsphere_virtual_machine.template[0].guest_id : null scsi_bus_sharing = var.scsi_bus_sharing scsi_type = var.scsi_type != "" ? var.scsi_type : (var.content_library == null ? data.vsphere_virtual_machine.template[0].scsi_type : null) scsi_controller_count = max( max(0, flatten([ for item in values(var.data_disk) : [ for elem, val in item : elem == "data_disk_scsi_controller" ? val : 0 ]])...) + 1, ceil((max(0, flatten([ for item in values(var.data_disk) : [ for elem, val in item : elem == "unit_number" ? val : 0 ]])...) + 1) / 15), var.scsi_controller) wait_for_guest_net_routable = var.wait_for_guest_net_routable wait_for_guest_ip_timeout = var.wait_for_guest_ip_timeout wait_for_guest_net_timeout = var.wait_for_guest_net_timeout ignored_guest_ips = var.ignored_guest_ips dynamic "network_interface" { for_each = keys(var.network) #data.vsphere_network.network[*].id #other option content { network_id = data.vsphere_network.network[network_interface.key].id adapter_type = var.network_type != null ? var.network_type[network_interface.key] : (var.content_library == null ? data.vsphere_virtual_machine.template[0].network_interface_types[0] : null) } } // Disks defined in the original template dynamic "disk" { for_each = var.content_library == null ? data.vsphere_virtual_machine.template[0].disks : [] iterator = template_disks content { label = length(var.disk_label) > 0 ? var.disk_label[template_disks.key] : "disk${template_disks.key}" size = var.disk_size_gb != null ? var.disk_size_gb[template_disks.key] : data.vsphere_virtual_machine.template[0].disks[template_disks.key].size unit_number = var.scsi_controller != null ? var.scsi_controller * 15 + template_disks.key : template_disks.key thin_provisioned = data.vsphere_virtual_machine.template[0].disks[template_disks.key].thin_provisioned eagerly_scrub = data.vsphere_virtual_machine.template[0].disks[template_disks.key].eagerly_scrub datastore_id = var.disk_datastore != "" ? data.vsphere_datastore.disk_datastore[0].id : null storage_policy_id = length(var.template_storage_policy_id) > 0 ? var.template_storage_policy_id[template_disks.key] : null io_reservation = length(var.io_reservation) > 0 ? var.io_reservation[template_disks.key] : null io_share_level = length(var.io_share_level) > 0 ? var.io_share_level[template_disks.key] : "normal" io_share_count = length(var.io_share_level) > 0 && var.io_share_level[template_disks.key] == "custom" ? var.io_share_count[template_disks.key] : null } } // Disk for template from Content Library dynamic "disk" { for_each = var.content_library == null ? [] : [1] iterator = template_disks content { label = length(var.disk_label) > 0 ? var.disk_label[template_disks.key] : "disk${template_disks.key}" size = var.disk_size_gb[template_disks.key] unit_number = var.scsi_controller != null ? var.scsi_controller * 15 + template_disks.key : template_disks.key // thin_provisioned = data.vsphere_virtual_machine.template[0].disks[template_disks.key].thin_provisioned // eagerly_scrub = data.vsphere_virtual_machine.template[0].disks[template_disks.key].eagerly_scrub datastore_id = var.disk_datastore != "" ? data.vsphere_datastore.disk_datastore[0].id : null storage_policy_id = length(var.template_storage_policy_id) > 0 ? var.template_storage_policy_id[template_disks.key] : null io_reservation = length(var.io_reservation) > 0 ? var.io_reservation[template_disks.key] : null io_share_level = length(var.io_share_level) > 0 ? var.io_share_level[template_disks.key] : "normal" io_share_count = length(var.io_share_level) > 0 && var.io_share_level[template_disks.key] == "custom" ? var.io_share_count[template_disks.key] : null disk_mode = length(var.disk_mode) > 0 ? var.disk_mode[template_disks.key] : null } } // Additional disks defined by Terraform config dynamic "disk" { for_each = var.data_disk iterator = terraform_disks content { label = terraform_disks.key size = lookup(terraform_disks.value, "size_gb", null) unit_number = ( lookup( terraform_disks.value, "unit_number", -1 ) < 0 ? ( lookup( terraform_disks.value, "data_disk_scsi_controller", 0 ) > 0 ? ( (terraform_disks.value.data_disk_scsi_controller * 15) + index(keys(var.data_disk), terraform_disks.key) + (var.scsi_controller == tonumber(terraform_disks.value["data_disk_scsi_controller"]) ? local.template_disk_count : 0) ) : ( index(keys(var.data_disk), terraform_disks.key) + local.template_disk_count ) ) : ( tonumber(terraform_disks.value["unit_number"]) ) ) thin_provisioned = lookup(terraform_disks.value, "thin_provisioned", "true") eagerly_scrub = lookup(terraform_disks.value, "eagerly_scrub", "false") datastore_id = lookup(terraform_disks.value, "datastore_id", null) storage_policy_id = lookup(terraform_disks.value, "storage_policy_id", null) io_reservation = lookup(terraform_disks.value, "io_reservation", null) io_share_level = lookup(terraform_disks.value, "io_share_level", "normal") io_share_count = lookup(terraform_disks.value, "io_share_level", null) == "custom" ? lookup(terraform_disks.value, "io_share_count") : null disk_mode = lookup(terraform_disks.value, "disk_mode", null) disk_sharing = lookup(terraform_disks.value, "disk_sharing", null) attach = lookup(terraform_disks.value, "attach", null) path = lookup(terraform_disks.value, "path", null) } } clone { template_uuid = var.content_library == null ? data.vsphere_virtual_machine.template[0].id : data.vsphere_content_library_item.library_item_template[0].id linked_clone = var.linked_clone timeout = var.timeout customize { dynamic "linux_options" { for_each = var.is_windows_image ? [] : [1] content { host_name = var.staticvmname != null ? var.staticvmname : format("${var.vmname}${var.vmnameformat}", count.index + var.vmstartcount) domain = var.domain hw_clock_utc = var.hw_clock_utc } } dynamic "windows_options" { for_each = var.is_windows_image ? [1] : [] content { computer_name = var.staticvmname != null ? var.staticvmname : format("${var.vmname}${var.vmnameformat}", count.index + var.vmstartcount) admin_password = var.local_adminpass workgroup = var.workgroup join_domain = var.windomain domain_admin_user = var.domain_admin_user domain_admin_password = var.domain_admin_password organization_name = var.orgname run_once_command_list = var.run_once auto_logon = var.auto_logon auto_logon_count = var.auto_logon_count time_zone = var.time_zone product_key = var.productkey full_name = var.full_name } } dynamic "network_interface" { for_each = keys(var.network) content { ipv4_address = split("/", var.network[keys(var.network)[network_interface.key]][count.index])[0] ipv4_netmask = var.network[keys(var.network)[network_interface.key]][count.index] == "" ? null : ( length(split("/", var.network[keys(var.network)[network_interface.key]][count.index])) == 2 ? ( split("/", var.network[keys(var.network)[network_interface.key]][count.index])[1] ) : ( length(var.ipv4submask) == 1 ? var.ipv4submask[0] : var.ipv4submask[network_interface.key] ) ) } } dns_server_list = var.dns_server_list dns_suffix_list = var.dns_suffix_list ipv4_gateway = var.vmgateway } } // Advanced options hv_mode = var.hv_mode ept_rvi_mode = var.ept_rvi_mode nested_hv_enabled = var.nested_hv_enabled enable_logging = var.enable_logging cpu_performance_counters_enabled = var.cpu_performance_counters_enabled swap_placement_policy = var.swap_placement_policy latency_sensitivity = var.latency_sensitivity shutdown_wait_timeout = var.shutdown_wait_timeout force_power_off = var.force_power_off } ================================================ FILE: output.tf ================================================ output "DC_ID" { description = "id of vSphere Datacenter" value = data.vsphere_datacenter.dc.id } output "ResPool_ID" { description = "Resource Pool id" value = var.vmrp != "" ? data.vsphere_resource_pool.pool[0].id : var.vmrpid } output "VM" { description = "VM Names" value = vsphere_virtual_machine.vm.*.name } output "ip" { description = "default ip address of the deployed VM" value = vsphere_virtual_machine.vm.*.default_ip_address } output "guest-ip" { description = "all the registered ip address of the VM" value = vsphere_virtual_machine.vm.*.guest_ip_addresses } output "uuid" { description = "UUID of the VM in vSphere" value = vsphere_virtual_machine.vm.*.uuid } output "disk" { description = "Disks of the deployed VM" value = vsphere_virtual_machine.vm.*.disk } ================================================ FILE: tests/sanity/.terraform.lock.hcl ================================================ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/vsphere" { version = "2.0.0" hashes = [ "h1:kF5EuJgqGrd6fElgIGSk7NpipRAo7bUcBygIFOQmLz0=", "zh:0c173a821b4e73b54474911b340220081c1ace68e02f58c076700ae0c6ec97cf", "zh:0cf8b72fc5747591a23ffa72a667a14bbf1b1138f430b863b2b3724f45c10462", "zh:262d2cc5510e18271022a650d537d09ab3037fe40812407b3dc31730d4c8159e", "zh:2f1184a1a29b5b0b31baafb63314139842305894d2d235200562af474d69763f", "zh:482f3e59a71d4ca8dcd3524459f09f0c14c5ef61990bd273e4dd4cfb930cb7ee", "zh:4a7c1b37fcd7342d333b8970263fe89d813d0502b687cd1e2733cbb3e4ad4c97", "zh:687b37b885b22bd7114b271fa999d483f993e120d0b8322cad7f907159b64c3a", "zh:6dd70d4f7542f11449cb8fbfbd186d9da233243bee5f8005c804dc6afb418e84", "zh:ab241bb083e077d40096e8ffe701dfbdf510cf6adb329af9c8c5231a48416b8f", "zh:b53de1995cc493683c75f416b072069919e2ef3d297384412d9d8f8c7ac8de90", "zh:e9b78cf4c133a7c9a05cec410cf468475c1c397c0a8b3ab5685c61e24ad02f68", ] } ================================================ FILE: tests/sanity/README.md ================================================ # Sanity Test for new Functionality **Copy of a TF Plan shoud be submmited with each PR, new functionality/variable should be explicitly added here under static values section in the main.tf file.** ### tfvars Example: ```hcl viserver = "fill" viuser = "fill" vipassword = "fill" vm = { linuxvm = { vmtemp = "Template name", is_windows_image = false vmrp = "fill" dc = "fill", datastore = "fill" vmfolder = "fill" vmgateway = "10.13.13.1" dns_servers = ["1.1.1.1"] network = { "VM Port Group" = ["10.13.13.2", ""], # To use DHCP create Empty list for each instance "VM Port Group" = ["", ""] } }, windowsvm = { vmtemp = "fill" is_windows_image = true vmrp = "fill" dc = "fill" vmfolder = "fill" datastore = "fill" dns_servers = null vmgateway = "10.13.13.1" network = { "VM Port Group" = ["10.13.13.2", ""], # To use DHCP create Empty list for each instance "VM Port Group" = ["", ""] } } } ``` ================================================ FILE: tests/sanity/apply.sh ================================================ terraform init terraform fmt terraform validate terraform apply -var-file="private.tfvars" ================================================ FILE: tests/sanity/cleanup.sh ================================================ terraform destroy -var-file=private.tfvars rm terraform.tfstate terraform.tfstate.backup .terraform.lock.hcl rm -rf .terraform ================================================ FILE: tests/sanity/connection.tf ================================================ variable "viuser" {} variable "vipassword" {} variable "viserver" {} # Configure the VMware vSphere Provider provider "vsphere" { user = var.viuser password = var.vipassword vsphere_server = var.viserver # if you have a self-signed cert allow_unverified_ssl = true } ================================================ FILE: tests/sanity/main.tf ================================================ # This workspace id to test the newly added functionality of the changes. # # Testing Tags resource "vsphere_tag_category" "category" { name = "terraform-test-category" cardinality = "SINGLE" description = "Managed by Terraform" associable_types = [ "VirtualMachine", "Datastore", ] } resource "vsphere_tag" "tag" { name = "terraform-test-tag" category_id = vsphere_tag_category.category.id description = "Managed by Terraform" } #to test naming convention variable "env" { default = "dev" } #Do not add any new variables here unless it is sensitive variable "vm" { type = map(object({ vmname = string vmtemp = string dc = string vmrp = string vmfolder = string datastore = string is_windows_image = bool network = map(list(string)) vmgateway = string dns_servers = list(string) })) } #add the new added function/variables here module "example-server-basic" { source = "../../" for_each = var.vm vmrp = each.value.vmrp vmfolder = each.value.vmfolder vmtemp = each.value.vmtemp is_windows_image = each.value.is_windows_image network = each.value.network vmgateway = each.value.vmgateway dc = each.value.dc datastore = each.value.datastore #starting of static values instances = 2 vmstartcount = 5 vmnameformat = "%03d${var.env}" domain = "somedomain.com" fqdnvmname = true vmname = "terraform-sanitytest" annotation = "Terraform Sanity Test" tag_depends_on = [vsphere_tag.tag.id] tags = { "terraform-test-category" = "terraform-test-tag", } data_disk = { disk1 = { size_gb = 30, thin_provisioned = false, data_disk_scsi_controller = 0, storage_policy_id = "ff45cc66-b624-4621-967f-1aef6437f568" }, disk2 = { size_gb = 70, thin_provisioned = true, data_disk_scsi_controller = 1, io_reservation = 15 io_share_level = "custom" io_share_count = 2000 } } io_reservation = [15] io_share_level = ["custom"] io_share_count = [2000] memory_share_level = "custom" memory_share_count = 2000 cpu_share_level = "custom" cpu_share_count = 2000 #ipv4submask = ["28", "26"] } output "DC_ID" { value = tomap({ for k, i in module.example-server-basic : k => i.DC_ID }) } output "VM" { value = tomap({ for k, i in module.example-server-basic : k => i.VM }) } ================================================ FILE: tests/sanity/plan.sh ================================================ terraform init terraform fmt terraform validate terraform plan -var-file="private.tfvars" ================================================ FILE: tests/smoke/.terraform.lock.hcl ================================================ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/vsphere" { version = "1.24.2" hashes = [ "h1:BEf8p0h+NYK0hu4dG8NloZtNaSw5nbMKsqwIZWdsIPk=", "zh:01d8e13dac110466f946da1f14294f64b747f1fa6f2d107f7bc0f8db40624497", "zh:06670e7baa2c2083afbe01b617aa72bcd2950830ecb66f01e743e361105e7b47", "zh:17220222bdeeeb7575a51ebd556377e9f2157258eec945710e95ec1a597f8ec7", "zh:2dfd808800c21a483e7401254d6dd817ec3f7d323525cd7a6d3919c81e30e686", "zh:671befb1f724ffbc68c117d06619989eb4b62246896ad168384540d1acc7a0b6", "zh:7d29d02d1c2f82a1c71e38aaa9daa23d4cccfc5d00c0c9ea1e2c36d98343e855", "zh:98a8acafe6e38f7ad214b53826b2a9dc1f036cfb3833ba67c517eae2e4ea56c0", "zh:a74fc725844da35ab73105e62b97efe717fb5c5f21554ee656d434e9803f20ad", "zh:a7ab1a04902254e63dc2dc489e69343c2a53999e987114c932259884594da1ec", "zh:df0beaef2d925771724cbf19747787f618c595c0712dc210b5581041691310e6", ] } ================================================ FILE: tests/smoke/README.md ================================================ # Smoke Test You need to run the plan using private.tfvars ### Example: ```hcl viserver = "fill" viuser = "fill" vipassword = "fill" vm = { linuxvm = { vmname = "example-server-linux", vmtemp = "fill" content_library = null annotation = "Terraform Smoke Test" instances = 0 is_windows_image = false vmrp = "fill" dc = "fill" datastore = "fill" vmfolder = "fill" vmgateway = "10.13.13.1" dns_servers = ["1.1.1.1"] network = { "VM Networks" = ["10.13.13.2"], } disk_size_gb = [ 20 ] } } ``` ================================================ FILE: tests/smoke/apply.sh ================================================ terraform init terraform fmt terraform validate terraform apply -var-file="private.tfvars" ================================================ FILE: tests/smoke/connection.tf ================================================ variable "viuser" {} variable "vipassword" {} variable "viserver" {} # Configure the VMware vSphere Provider provider "vsphere" { user = var.viuser password = var.vipassword vsphere_server = var.viserver # if you have a self-signed cert allow_unverified_ssl = true } ================================================ FILE: tests/smoke/main.tf ================================================ ####################################### # This workspace is for smoke test # do not modify this file # ##################################### variable "vm" { type = map(object({ vmname = string vmtemp = string annotation = string dc = string vmrp = string vmfolder = string datastore = string is_windows_image = bool instances = number network = map(list(string)) vmgateway = string dns_servers = list(string) })) } module "example-server-basic" { source = "../../" for_each = var.vm vmtemp = each.value.vmtemp annotation = each.value.annotation is_windows_image = each.value.is_windows_image instances = each.value.instances vmname = each.value.vmname vmrp = each.value.vmrp vmfolder = each.value.vmfolder network = each.value.network vmgateway = each.value.vmgateway dc = each.value.dc datastore = each.value.datastore #Either } ================================================ FILE: tests/smoke/plan.sh ================================================ terraform init terraform fmt terraform validate terraform plan -var-file="private.tfvars" ================================================ FILE: variables.tf ================================================ #Network Section variable "network" { description = "Define PortGroup and IPs/CIDR for each VM. If no CIDR provided, the subnet mask is taken from var.ipv4submask." type = map(list(string)) default = {} } variable "network_delimiter" { description = "If network name needs a delimiter for sequencing, define an UNUSED character here, otherwise leave as null" type = string default = null } variable "network_type" { description = "Define network type for each network interface." type = list(any) default = null } variable "ipv4submask" { description = "ipv4 Subnet mask. Warning: The order must follow the alphabetic order from var.network." type = list(any) default = ["24"] } #Data Disk section variable "datastore_cluster" { description = "Datastore cluster to deploy the VM." default = "" } variable "datastore" { description = "Datastore to deploy the VM." default = "" } variable "data_disk" { description = "Storage data disk parameter, example" type = map(map(string)) default = {} } variable "disk_label" { description = "Storage data disk labels." type = list(any) default = [] } variable "disk_size_gb" { description = "List of disk sizes to override template disk size." type = list(any) default = null } variable "disk_datastore" { description = "Define where the OS disk should be stored." type = string default = "" } variable "io_reservation" { description = "The I/O reservation (guarantee) that this disk has, in IOPS. The default is no reservation." type = list(number) default = [] } variable "io_share_level" { description = "The share allocation level for this disk. Can be one of low, normal, high, or custom. Default: normal." type = list(string) default = ["normal"] } variable "io_share_count" { description = "The share count for this disk when the share level is custom." type = list(number) default = [] } variable "disk_mode" { description = "The disk mode for the disk." type = list(string) default = [] } variable "template_storage_policy_id" { description = "List of UUIDs of the storage policy to assign to the template disk." type = list(any) default = [] } variable "scsi_bus_sharing" { description = "scsi_bus_sharing mode, acceptable values physicalSharing,virtualSharing,noSharing." type = string default = null } variable "scsi_type" { description = "scsi_controller type, acceptable values lsilogic,pvscsi." type = string default = "" } variable "scsi_controller" { description = "scsi_controller number for the main OS disk." type = number default = 0 # validation { # condition = var.scsi_controller < 4 && var.scsi_controller > -1 # error_message = "The scsi_controller must be between 0 and 3" # } } variable "enable_disk_uuid" { description = "Expose the UUIDs of attached virtual disks to the virtual machine, allowing access to them in the guest. Default: Inherited from cloned template" type = bool default = null } variable "storage_policy_id" { description = "(Optional) The UUID of the storage policy to assign to VM home directory." default = null } ########################################### variable "vmname" { description = "The name of the virtual machine used to deploy the vms. This name can scale out based on number of instances and vmnameformat - example can be found under exampel folder" default = "terraformvm" } variable "vmnameformat" { description = "vmname format. default is set to 2 decimal with leading 0. example: %03d for 3 decimal with leading zero or %02dprod for additional suffix" default = "%02d" } variable "vmstartcount" { description = "vmname start count value. default is set to 1. example: a value of 4 (with default format and 2 instances) will make first instance suffix 04 and second instance suffix 05" default = 1 } variable "staticvmname" { description = "Static name of the virtual machin. When this option is used VM can not scale out using instance variable. You can use for_each outside the module to deploy multiple static vms with different names" default = null } variable "fqdnvmname" { description = "If true, the vm will be created using domain variable appended" type = bool default = false } variable "vmtemp" { description = "Name of the template available in the vSphere." } variable "content_library" { description = "Name of the content library where the OVF template is stored." default = null } variable "instances" { description = "number of instances you want deploy from the template." default = 1 } variable "cpu_number" { description = "number of CPU (core per CPU) for the VM." default = 2 } variable "cpu_reservation" { description = "The amount of CPU (in MHz) that this virtual machine is guaranteed." default = null } variable "cpu_share_level" { description = "The allocation level for CPU resources. Can be one of high, low, normal, or custom. Default: custom." type = string default = "normal" } variable "cpu_share_count" { description = "The number of CPU shares allocated to the virtual machine when the cpu_share_level is custom." type = number default = 4000 } variable "ram_size" { description = "VM RAM size in megabytes." default = 4096 } variable "dc" { description = "Name of the datacenter you want to deploy the VM to." } variable "vmrpid" { description = "ID of cluster resource pool that VM will be deployed to. you use following to choose default pool in the cluster (esxi1) or (Cluster)/Resources." default = "" } variable "vmrp" { description = "Cluster resource pool that VM will be deployed to. you use following to choose default pool in the cluster (esxi1) or (Cluster)/Resources." default = "" } variable "vmfolder" { description = "The path to the folder to put this virtual machine in, relative to the datacenter that the resource pool is in. Path - The absolute path of the folder. For example, given a default datacenter of default-dc, a folder of type vm, and a folder name of terraform-test-folder, the resulting path would be /default-dc/vm/terraform-test-folder." default = null } variable "vmgateway" { description = "VM gateway to set during provisioning." default = null } variable "dns_server_list" { type = list(string) default = null } #Global Customization Variables variable "tags" { description = "The names of any tags to attach to this resource. They must already exist." type = map(any) default = null } variable "tag_ids" { description = "The ids of any tags to attach to this resource. They must already exist." type = list(any) default = null } variable "custom_attributes" { description = "Map of custom attribute ids to attribute value strings to set for virtual machine." type = map(any) default = null } variable "extra_config" { description = "Extra configuration data for this virtual machine. Can be used to supply advanced parameters not normally in configuration, such as instance metadata.'disk.enableUUID', 'True'." type = map(any) default = null } variable "annotation" { description = "A user-provided description of the virtual machine. The default is no annotation." default = null } variable "linked_clone" { description = "Clone this virtual machine from a snapshot. Templates must have a single snapshot only in order to be eligible." default = false } variable "timeout" { description = "The timeout, in minutes, to wait for the virtual machine clone to complete." type = number default = 30 } variable "dns_suffix_list" { description = "A list of DNS search domains to add to the DNS configuration on the virtual machine." type = list(string) default = null } variable "firmware" { description = "The firmware interface to use on the virtual machine. Can be one of bios or EFI. Default: Inherited from cloned template" default = null } variable "efi_secure_boot" { description = "Enables EFI secure boot. Can be only be true when firmware is EFI. Default: Inherited from cloned template" default = null } variable "num_cores_per_socket" { description = "The number of cores to distribute among the CPUs in this virtual machine. If specified, the value supplied to num_cpus must be evenly divisible by this value." type = number default = 1 } variable "cpu_hot_add_enabled" { description = "Allow CPUs to be added to this virtual machine while it is running." type = bool default = null } variable "cpu_hot_remove_enabled" { description = "Allow CPUs to be removed to this virtual machine while it is running." type = bool default = null } variable "memory_hot_add_enabled" { description = "Allow memory to be added to this virtual machine while it is running." type = bool default = null } variable "memory_reservation" { description = "The amount of memory (in MB) that this virtual machine is guaranteed." default = null } variable "memory_share_level" { description = "The allocation level for memory resources. Can be one of high, low, normal, or custom" type = string default = "normal" } variable "memory_share_count" { description = "(Optional) The number of memory shares allocated to the virtual machine when the memory_share_level is custom" type = number default = 81920 } #Linux Customization Variables variable "hw_clock_utc" { description = "Tells the operating system that the hardware clock is set to UTC." type = bool default = true } variable "domain" { description = "default VM domain for linux guest customization and fqdn name (if fqdnvmname is true)." default = "Development.com" } #Windows Customization Variables variable "is_windows_image" { description = "Boolean flag to notify when the custom image is windows based." type = bool default = false } variable "local_adminpass" { description = "The administrator password for this virtual machine.(Required) when using join_windomain option." default = null } variable "workgroup" { description = "The workgroup name for this virtual machine. One of this or join_domain must be included." default = null } variable "windomain" { description = "The domain to join for this virtual machine. One of this or workgroup must be included." default = null } variable "domain_admin_user" { description = "Domain admin user to join the server to AD.(Required) when using join_windomain option." default = null } variable "domain_admin_password" { description = "Doamin User pssword to join the server to AD.(Required) when using join_windomain option." default = null } variable "orgname" { description = "Organization name for when joining windows server to AD." default = null } variable "auto_logon" { description = " Specifies whether or not the VM automatically logs on as Administrator. Default: false." type = bool default = null } variable "auto_logon_count" { description = "Specifies how many times the VM should auto-logon the Administrator account when auto_logon is true. This should be set accordingly to ensure that all of your commands that run in run_once_command_list can log in to run." default = null } variable "time_zone" { description = "The new time zone for the virtual machine. This is a numeric, sysprep-dictated, timezone code." default = null } variable "run_once" { description = "List of Comamnd to run during first logon (Automatic login set to 1)." type = list(string) default = null } variable "productkey" { description = "Product key to be used during windows customization." default = null } variable "full_name" { description = "The full name of the user of this virtual machine. This populates the user field in the general Windows system information. Default - Administrator." default = null } variable "wait_for_guest_net_routable" { description = "Controls whether or not the guest network waiter waits for a routable address. When false, the waiter does not wait for a default gateway, nor are IP addresses checked against any discovered default gateways as part of its success criteria. This property is ignored if the wait_for_guest_ip_timeout waiter is used." type = bool default = true } variable "wait_for_guest_ip_timeout" { description = "The amount of time, in minutes, to wait for an available guest IP address on this virtual machine. This should only be used if your version of VMware Tools does not allow the wait_for_guest_net_timeout waiter to be used. A value less than 1 disables the waiter." type = number default = 0 } variable "wait_for_guest_net_timeout" { description = "The amount of time, in minutes, to wait for an available IP address on this virtual machine's NICs. Older versions of VMware Tools do not populate this property. In those cases, this waiter can be disabled and the wait_for_guest_ip_timeout waiter can be used instead. A value less than 1 disables the waiter." type = number default = 5 } variable "ignored_guest_ips" { description = "List of IP addresses and CIDR networks to ignore while waiting for an available IP address using either of the waiters. Any IP addresses in this list will be ignored if they show up so that the waiter will continue to wait for a real IP address." type = list(string) default = [] } variable "vm_depends_on" { description = "Add any external depend on module here like vm_depends_on = [module.fw_core01.firewall]." type = any default = null } variable "tag_depends_on" { description = "Add any external depend on module here like tag_depends_on = [vsphere_tag.foo.id]." type = any default = null } variable "hv_mode" { description = "The (non-nested) hardware virtualization setting for this virtual machine. Can be one of hvAuto, hvOn, or hvOff." type = string default = null } variable "ept_rvi_mode" { description = "The EPT/RVI (hardware memory virtualization) setting for this virtual machine." type = string default = null } variable "nested_hv_enabled" { description = "Enable nested hardware virtualization on this virtual machine, facilitating nested virtualization in the guest." type = bool default = null } variable "enable_logging" { description = "Enable logging of virtual machine events to a log file stored in the virtual machine directory." type = bool default = null } variable "cpu_performance_counters_enabled" { description = "Enable CPU performance counters on this virtual machine." type = bool default = null } variable "swap_placement_policy" { description = "The swap file placement policy for this virtual machine. Can be one of inherit, hostLocal, or vmDirectory." type = string default = null } variable "latency_sensitivity" { description = "Controls the scheduling delay of the virtual machine. Use a higher sensitivity for applications that require lower latency, such as VOIP, media player applications, or applications that require frequent access to mouse or keyboard devices.Can be one of low, normal, medium, or high." type = string default = null } variable "shutdown_wait_timeout" { description = "The amount of time, in minutes, to wait for a graceful guest shutdown when making necessary updates to the virtual machine. If force_power_off is set to true, the VM will be force powered-off after this timeout, otherwise an error is returned." type = string default = null } variable "migrate_wait_timeout" { description = "The amount of time, in minutes, to wait for a graceful guest shutdown when making necessary updates to the virtual machine. If force_power_off is set to true, the VM will be force powered-off after this timeout, otherwise an error is returned." type = string default = null } variable "force_power_off" { description = "If a guest shutdown failed or timed out while updating or destroying (see shutdown_wait_timeout), force the power-off of the virtual machine." type = bool default = null } ================================================ FILE: versions.tf ================================================ terraform { required_version = ">= 0.13.4" required_providers { vsphere = { source = "hashicorp/vsphere" } } }