We have a Terraform project that includes both vSphere and Active Directory providers. It is designed to create Active Directory containers and objects (users, computers and security groups) before building new VMs, joining them to the domain and placing them in the correct (new) AD container.
The password for the account used to join the VM to the domain is cycled regularly by our PAM tool. So, we update the creds.auto.tf when we need to apply our project code with the updated password.
We have successfully used the project to deploy applications, cloning the project for each new application.
The issue was encountered when we had to make changes to one of the applications. Specifically, we added another user account to the project. Then we updated the creds.auto.tf and tried to apply the project.
The plan indicated the VM resource would be replaced. This was unexpected and will cause a lot of trouble moving forward… a minor change not directly related to the VM resource should not result in a destroy/rebuild.
I’m reaching out for assistance. Is there a way make these updates without replacing the VM?
I would be grateful for any help.
The plan output is attached.
plan_result.txt (7.1 KB)
Thanks
Hi @roy.madden,
If you want to prevent changes in configuration from being applied to existing resources, then you want to use the ignore_changes
feature. If you question on using that feature it would help to see the configuration and which attributes exactly you want to ignore.
Hi @jbardin ,
This is exactly what I needed - thanks for the assistance.
The syntax seems straightforward, but please double check my work - I added the lifecycle meta-argument at the end of the resource block:
resource "vsphere_virtual_machine" "vm" {
for_each = var.virtual_machines
name = each.key
resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
datastore_cluster_id = data.vsphere_datastore_cluster.datastore_cluster.id
num_cpus = each.value.vm_cpu
memory = each.value.vm_ram
guest_id = data.vsphere_virtual_machine.template.guest_id
scsi_type = data.vsphere_virtual_machine.template.scsi_type
firmware = var.vm_firmware
wait_for_guest_net_timeout = -1
network_interface {
network_id = data.vsphere_network.network.id
adapter_type = each.value.vm_adapter
}
dynamic "disk" {
for_each = { for idx, size in each.value.vm_disks : idx => size }
content {
label = "disk${disk.key}"
unit_number = disk.key
size = disk.value
thin_provisioned = false
eagerly_scrub = false
}
}
clone {
template_uuid = data.vsphere_virtual_machine.template.id
customize {
timeout = 30
windows_options {
computer_name = each.key
# workgroup = "test"
join_domain = var.domain_name
domain_admin_user = var.domain_admin_user
domain_admin_password = var.domain_admin_password
admin_password = var.local_adminpass
# product_key = var.productkey
# 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.vm_timezone
# product_key = var.productkey
# full_name = var.full_name
}
network_interface {
ipv4_address = each.value.vm_ip_address
ipv4_netmask = each.value.vm_ip_netmask
dns_server_list = each.value.vm_dns_list
dns_domain = var.domain_name
}
ipv4_gateway = each.value.vm_ip_gateway
}
}
lifecycle {
ignore_changes = [
domain_admin_user,
domain_admin_password
]
}
}
(I reformatted your post so I could make sure to get the blocks correct)
You must supply a full path to the attributes you want to specify, not just a pattern to match. Unfortunately with the legacy SDK there’s a bit of a nuance here, because each of the blocks is a list of one object, so you will need to give the index of each level.
I think the paths for this resource will look more like:
lifecycle {
ignore_changes = [
clone[0].customize[0].windows_options[0].domain_admin_user,
clone[0].customize[0].windows_options[0].domain_admin_password,
]
}
I’m not sure of the specifics of the resource, but maybe you could make a more general ignored path. If nothing below one of those blocks is useful for updates you can ignore the entire thing.
Thanks for pointing out the full path is required.
Also, thanks for reformatting the post.
How did you get the formatting done?
When I pasted the text, half was formatted properly and the rest was the default font/format.
When I attempted to correct it, all of the text went to the default.
Many online systems use the same markdown for raw text, which is to wrap it in opening and closing sets of 3 backticks (```). You can also click the “Preformatted text” button in the editor.