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