├── .gitignore ├── README.md ├── config.tf ├── main.tf ├── outputs.tf ├── templates ├── metadata.yaml └── userdata.yaml ├── terraform.tfvars.example ├── variables.tf └── vsphere_data.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 12 | # .tfvars files are managed as part of configuration and so should be included in 13 | # version control. 14 | # 15 | # example.tfvars 16 | terraform.tfvars 17 | 18 | # Ignore override files as they are usually used to override resources locally and so 19 | # are not checked in 20 | override.tf 21 | override.tf.json 22 | *_override.tf 23 | *_override.tf.json 24 | 25 | # Include override files you do wish to add to version control using negated pattern 26 | # 27 | # !example_override.tf 28 | 29 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 30 | # example: *tfplan* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloud-Init Sample 2 | 3 | This repo provides an example of deploying a Ubuntu machine with dynamically generated metadata and userdata files included in the templates directory. 4 | 5 | Cloud-init configuration is provided via the [VMware guestinfo datasource](https://github.com/vmware/cloud-init-vmware-guestinfo). A sample Packer build that has the relevant dependencies pre-installed can be found [here](https://github.com/grantorchard/packer-vsphere-cloudinit). 6 | 7 | To leverage the example of switching between DHCP and static IP addressing, you will need to set the dhcp variable value to true or false, and update the vars block for the metadata file_template resource in the config.tf file. -------------------------------------------------------------------------------- /config.tf: -------------------------------------------------------------------------------- 1 | data template_file "userdata" { 2 | template = file("${path.module}/templates/userdata.yaml") 3 | 4 | vars = { 5 | username = var.username 6 | ssh_public_key = file(var.ssh_public_key) 7 | packages = jsonencode(var.packages) 8 | } 9 | } 10 | 11 | 12 | data template_file "metadata" { 13 | template = file("${path.module}/templates/metadata.yaml") 14 | vars = { 15 | dhcp = var.dhcp 16 | hostname = var.hostname_prefix 17 | ip_address = var.ip_address 18 | netmask = var.netmask 19 | nameservers = jsonencode(var.nameservers) 20 | gateway = var.gateway 21 | } 22 | } -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | provider "vsphere" { 2 | user = var.vsphere_user 3 | password = var.vsphere_password 4 | vsphere_server = var.vsphere_server 5 | 6 | # If you have a self-signed cert 7 | allow_unverified_ssl = true 8 | } 9 | 10 | resource vsphere_virtual_machine "this" { 11 | name = var.hostname_prefix 12 | resource_pool_id = data.vsphere_compute_cluster.this.resource_pool_id 13 | datastore_id = data.vsphere_datastore.this.id 14 | 15 | num_cpus = 2 16 | memory = 1024 17 | guest_id = data.vsphere_virtual_machine.template.guest_id 18 | 19 | network_interface { 20 | network_id = data.vsphere_network.this.id 21 | adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0] 22 | } 23 | wait_for_guest_net_timeout = 0 24 | 25 | disk { 26 | label = "disk0" 27 | size = data.vsphere_virtual_machine.template.disks.0.size 28 | eagerly_scrub = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub 29 | thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned 30 | } 31 | 32 | clone { 33 | template_uuid = data.vsphere_virtual_machine.template.id 34 | } 35 | 36 | extra_config = { 37 | "guestinfo.metadata" = base64encode(data.template_file.metadata.rendered) 38 | "guestinfo.metadata.encoding" = "base64" 39 | "guestinfo.userdata" = base64encode(data.template_file.userdata.rendered) 40 | "guestinfo.userdata.encoding" = "base64" 41 | } 42 | } -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output metadata { 2 | value = "\n${data.template_file.metadata.rendered}" 3 | } 4 | 5 | output userdata { 6 | value = "\n${data.template_file.userdata.rendered}" 7 | } 8 | -------------------------------------------------------------------------------- /templates/metadata.yaml: -------------------------------------------------------------------------------- 1 | local-hostname: ${hostname} 2 | instance-id: ${hostname} 3 | network: 4 | version: 2 5 | ethernets: 6 | ens192: 7 | %{ if dhcp == "true" }dhcp4: true 8 | %{ else }addresses: 9 | - ${ip_address}/${netmask} 10 | gateway4: ${gateway} 11 | nameservers: 12 | addresses: ${nameservers} 13 | 14 | %{ endif } -------------------------------------------------------------------------------- /templates/userdata.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | users: 3 | - name: ${username} 4 | ssh-authorized-keys: 5 | - ${ssh_public_key} 6 | sudo: ['ALL=(ALL) NOPASSWD:ALL'] 7 | groups: sudo 8 | shell: /bin/bash 9 | 10 | packages: ${packages} -------------------------------------------------------------------------------- /terraform.tfvars.example: -------------------------------------------------------------------------------- 1 | datacenter_name = "Core" 2 | cluster_name = "Tenant" 3 | datastore_name = "hl-core-ds01" 4 | vm_network_name = "Common" 5 | vsphere_user = "administrator@vsphere.local" 6 | vsphere_password = "VMware123!" 7 | vsphere_server = "hlcorevc01.humblelab.com" 8 | template_name = "ubuntu-18.04-packer" 9 | username = "grant" 10 | ssh_public_key = "/Users/Grant/.ssh/id_rsa.pub" 11 | packages = ["jq","apache2"] 12 | dhcp = "true" 13 | ip_address = "10.0.0.237" 14 | netmask = "24" 15 | gateway = "10.0.0.1" 16 | nameservers = ["192.168.1.5","192.168.1.6"] -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------------------------------------------------- 2 | # VMWARE PROVIDER VARIABLES 3 | # These are used to connect to vCenter. 4 | # --------------------------------------------------------------------------------------------------------------------- 5 | 6 | variable "vsphere_server" { 7 | type = string 8 | } 9 | 10 | variable "vsphere_user" { 11 | type = string 12 | } 13 | 14 | variable "vsphere_password" { 15 | type = string 16 | } 17 | 18 | # --------------------------------------------------------------------------------------------------------------------- 19 | # VMWARE DATA SOURCE VARIABLES 20 | # These are used to discover unmanaged resources used during deployment. 21 | # --------------------------------------------------------------------------------------------------------------------- 22 | 23 | variable datacenter_name { 24 | type = string 25 | description = "The name of the vSphere Datacenter into which resources will be created." 26 | } 27 | 28 | variable cluster_name { 29 | type = string 30 | description = "The vSphere Cluster into which resources will be created." 31 | } 32 | 33 | variable datastore_name { 34 | type = string 35 | description = "The vSphere Datastore into which resources will be created." 36 | } 37 | 38 | variable datastore_cluster_name { 39 | type = string 40 | default = "" 41 | } 42 | 43 | variable vm_network_name { 44 | type = string 45 | } 46 | 47 | variable template_name { 48 | type = string 49 | } 50 | 51 | # --------------------------------------------------------------------------------------------------------------------- 52 | # VMWARE RESOURCE VARIABLES 53 | # Variables used during the creation of resources in vSphere. 54 | # --------------------------------------------------------------------------------------------------------------------- 55 | 56 | variable machine_count { 57 | type = number 58 | default = 3 59 | } 60 | 61 | variable hostname_prefix { 62 | type = string 63 | default = "ubuntu" 64 | description = "A prefix for the virtual machine name." 65 | } 66 | 67 | # --------------------------------------------------------------------------------------------------------------------- 68 | # CLOUD INIT VARIABLES 69 | # Variables used for generation of metadata and userdata. 70 | # --------------------------------------------------------------------------------------------------------------------- 71 | 72 | 73 | variable username { 74 | type = string 75 | } 76 | 77 | variable ssh_public_key { 78 | type = string 79 | description = "Location of SSH public key." 80 | } 81 | 82 | variable packages { 83 | type = list 84 | default = [] 85 | } 86 | 87 | variable dhcp { 88 | type = string 89 | default = "true" 90 | } 91 | 92 | variable ip_address { 93 | type = string 94 | default = "" 95 | } 96 | 97 | variable netmask { 98 | type = string 99 | default = "" 100 | } 101 | 102 | variable gateway { 103 | type = string 104 | default = "" 105 | } 106 | 107 | variable nameservers { 108 | type = list 109 | default = [] 110 | } -------------------------------------------------------------------------------- /vsphere_data.tf: -------------------------------------------------------------------------------- 1 | data vsphere_datacenter "this" { 2 | name = var.datacenter_name 3 | } 4 | 5 | data vsphere_compute_cluster "this" { 6 | name = var.cluster_name 7 | datacenter_id = data.vsphere_datacenter.this.id 8 | } 9 | 10 | data vsphere_datastore "this" { 11 | name = var.datastore_name 12 | datacenter_id = data.vsphere_datacenter.this.id 13 | } 14 | 15 | /* 16 | data vsphere_datastore_cluster "this" { 17 | name = var.datastore_name 18 | datacenter_id = data.vsphere_datacenter.this.id 19 | } 20 | */ 21 | 22 | data vsphere_network "this" { 23 | name = var.vm_network_name 24 | datacenter_id = data.vsphere_datacenter.this.id 25 | } 26 | 27 | data vsphere_virtual_machine "template" { 28 | name = var.template_name 29 | datacenter_id = data.vsphere_datacenter.this.id 30 | } --------------------------------------------------------------------------------