Skip to content

Commit cf04335

Browse files
committed
Add lifecycle ignore userdata as otherwise reboots existing instances
1 parent 28b2c72 commit cf04335

File tree

2 files changed

+375
-2
lines changed

2 files changed

+375
-2
lines changed

main.tf

Lines changed: 369 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ data "aws_ssm_parameter" "this" {
1919
################################################################################
2020

2121
resource "aws_instance" "this" {
22-
count = local.create && !var.ignore_ami_changes && !var.create_spot_instance ? 1 : 0
22+
count = local.create && !var.ignore_ami_changes && !var.ignore_user_data_changes && !var.create_spot_instance ? 1 : 0
2323

2424
ami = local.ami
2525
instance_type = var.instance_type
@@ -197,7 +197,7 @@ resource "aws_instance" "this" {
197197
################################################################################
198198

199199
resource "aws_instance" "ignore_ami" {
200-
count = local.create && var.ignore_ami_changes && !var.create_spot_instance ? 1 : 0
200+
count = local.create && var.ignore_ami_changes && !var.ignore_user_data_changes && !var.create_spot_instance ? 1 : 0
201201

202202
ami = local.ami
203203
instance_type = var.instance_type
@@ -376,6 +376,373 @@ resource "aws_instance" "ignore_ami" {
376376
}
377377
}
378378

379+
################################################################################
380+
# Instance - Ignore UserData Changes
381+
################################################################################
382+
383+
resource "aws_instance" "ignore_user_data" {
384+
count = local.create && !var.ignore_ami_changes && var.ignore_user_data_changes && !var.create_spot_instance ? 1 : 0
385+
386+
ami = local.ami
387+
instance_type = var.instance_type
388+
cpu_core_count = var.cpu_core_count
389+
cpu_threads_per_core = var.cpu_threads_per_core
390+
hibernation = var.hibernation
391+
392+
user_data = var.user_data
393+
user_data_base64 = var.user_data_base64
394+
user_data_replace_on_change = var.user_data_replace_on_change
395+
396+
availability_zone = var.availability_zone
397+
subnet_id = var.subnet_id
398+
vpc_security_group_ids = var.vpc_security_group_ids
399+
400+
key_name = var.key_name
401+
monitoring = var.monitoring
402+
get_password_data = var.get_password_data
403+
iam_instance_profile = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].name : var.iam_instance_profile
404+
405+
associate_public_ip_address = var.associate_public_ip_address
406+
private_ip = var.private_ip
407+
secondary_private_ips = var.secondary_private_ips
408+
ipv6_address_count = var.ipv6_address_count
409+
ipv6_addresses = var.ipv6_addresses
410+
411+
ebs_optimized = var.ebs_optimized
412+
413+
dynamic "cpu_options" {
414+
for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : []
415+
416+
content {
417+
core_count = try(cpu_options.value.core_count, null)
418+
threads_per_core = try(cpu_options.value.threads_per_core, null)
419+
amd_sev_snp = try(cpu_options.value.amd_sev_snp, null)
420+
}
421+
}
422+
423+
dynamic "capacity_reservation_specification" {
424+
for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : []
425+
426+
content {
427+
capacity_reservation_preference = try(capacity_reservation_specification.value.capacity_reservation_preference, null)
428+
429+
dynamic "capacity_reservation_target" {
430+
for_each = try([capacity_reservation_specification.value.capacity_reservation_target], [])
431+
432+
content {
433+
capacity_reservation_id = try(capacity_reservation_target.value.capacity_reservation_id, null)
434+
capacity_reservation_resource_group_arn = try(capacity_reservation_target.value.capacity_reservation_resource_group_arn, null)
435+
}
436+
}
437+
}
438+
}
439+
440+
dynamic "root_block_device" {
441+
for_each = var.root_block_device
442+
443+
content {
444+
delete_on_termination = try(root_block_device.value.delete_on_termination, null)
445+
encrypted = try(root_block_device.value.encrypted, null)
446+
iops = try(root_block_device.value.iops, null)
447+
kms_key_id = lookup(root_block_device.value, "kms_key_id", null)
448+
volume_size = try(root_block_device.value.volume_size, null)
449+
volume_type = try(root_block_device.value.volume_type, null)
450+
throughput = try(root_block_device.value.throughput, null)
451+
tags = try(root_block_device.value.tags, null)
452+
}
453+
}
454+
455+
dynamic "ebs_block_device" {
456+
for_each = var.ebs_block_device
457+
458+
content {
459+
delete_on_termination = try(ebs_block_device.value.delete_on_termination, null)
460+
device_name = ebs_block_device.value.device_name
461+
encrypted = try(ebs_block_device.value.encrypted, null)
462+
iops = try(ebs_block_device.value.iops, null)
463+
kms_key_id = lookup(ebs_block_device.value, "kms_key_id", null)
464+
snapshot_id = lookup(ebs_block_device.value, "snapshot_id", null)
465+
volume_size = try(ebs_block_device.value.volume_size, null)
466+
volume_type = try(ebs_block_device.value.volume_type, null)
467+
throughput = try(ebs_block_device.value.throughput, null)
468+
tags = try(ebs_block_device.value.tags, null)
469+
}
470+
}
471+
472+
dynamic "ephemeral_block_device" {
473+
for_each = var.ephemeral_block_device
474+
475+
content {
476+
device_name = ephemeral_block_device.value.device_name
477+
no_device = try(ephemeral_block_device.value.no_device, null)
478+
virtual_name = try(ephemeral_block_device.value.virtual_name, null)
479+
}
480+
}
481+
482+
dynamic "metadata_options" {
483+
for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : []
484+
485+
content {
486+
http_endpoint = try(metadata_options.value.http_endpoint, "enabled")
487+
http_tokens = try(metadata_options.value.http_tokens, "optional")
488+
http_put_response_hop_limit = try(metadata_options.value.http_put_response_hop_limit, 1)
489+
instance_metadata_tags = try(metadata_options.value.instance_metadata_tags, null)
490+
}
491+
}
492+
493+
dynamic "network_interface" {
494+
for_each = var.network_interface
495+
496+
content {
497+
device_index = network_interface.value.device_index
498+
network_interface_id = lookup(network_interface.value, "network_interface_id", null)
499+
delete_on_termination = try(network_interface.value.delete_on_termination, false)
500+
}
501+
}
502+
503+
dynamic "private_dns_name_options" {
504+
for_each = length(var.private_dns_name_options) > 0 ? [var.private_dns_name_options] : []
505+
506+
content {
507+
hostname_type = try(private_dns_name_options.value.hostname_type, null)
508+
enable_resource_name_dns_a_record = try(private_dns_name_options.value.enable_resource_name_dns_a_record, null)
509+
enable_resource_name_dns_aaaa_record = try(private_dns_name_options.value.enable_resource_name_dns_aaaa_record, null)
510+
}
511+
}
512+
513+
dynamic "launch_template" {
514+
for_each = length(var.launch_template) > 0 ? [var.launch_template] : []
515+
516+
content {
517+
id = lookup(var.launch_template, "id", null)
518+
name = lookup(var.launch_template, "name", null)
519+
version = lookup(var.launch_template, "version", null)
520+
}
521+
}
522+
523+
dynamic "maintenance_options" {
524+
for_each = length(var.maintenance_options) > 0 ? [var.maintenance_options] : []
525+
526+
content {
527+
auto_recovery = try(maintenance_options.value.auto_recovery, null)
528+
}
529+
}
530+
531+
enclave_options {
532+
enabled = var.enclave_options_enabled
533+
}
534+
535+
source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check
536+
disable_api_termination = var.disable_api_termination
537+
disable_api_stop = var.disable_api_stop
538+
instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior
539+
placement_group = var.placement_group
540+
tenancy = var.tenancy
541+
host_id = var.host_id
542+
543+
credit_specification {
544+
cpu_credits = local.is_t_instance_type ? var.cpu_credits : null
545+
}
546+
547+
timeouts {
548+
create = try(var.timeouts.create, null)
549+
update = try(var.timeouts.update, null)
550+
delete = try(var.timeouts.delete, null)
551+
}
552+
553+
tags = merge({ "Name" = var.name }, var.instance_tags, var.tags)
554+
volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null
555+
556+
lifecycle {
557+
ignore_changes = [
558+
user_data
559+
]
560+
}
561+
}
562+
563+
564+
################################################################################
565+
# Instance - Ignore AMI Changes and user_data Changes
566+
################################################################################
567+
568+
resource "aws_instance" "ignore_ami_userdata" {
569+
count = local.create && var.ignore_ami_changes && var.ignore_user_data_changes && !var.create_spot_instance ? 1 : 0
570+
571+
ami = local.ami
572+
instance_type = var.instance_type
573+
cpu_core_count = var.cpu_core_count
574+
cpu_threads_per_core = var.cpu_threads_per_core
575+
hibernation = var.hibernation
576+
577+
user_data = var.user_data
578+
user_data_base64 = var.user_data_base64
579+
user_data_replace_on_change = var.user_data_replace_on_change
580+
581+
availability_zone = var.availability_zone
582+
subnet_id = var.subnet_id
583+
vpc_security_group_ids = var.vpc_security_group_ids
584+
585+
key_name = var.key_name
586+
monitoring = var.monitoring
587+
get_password_data = var.get_password_data
588+
iam_instance_profile = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].name : var.iam_instance_profile
589+
590+
associate_public_ip_address = var.associate_public_ip_address
591+
private_ip = var.private_ip
592+
secondary_private_ips = var.secondary_private_ips
593+
ipv6_address_count = var.ipv6_address_count
594+
ipv6_addresses = var.ipv6_addresses
595+
596+
ebs_optimized = var.ebs_optimized
597+
598+
dynamic "cpu_options" {
599+
for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : []
600+
601+
content {
602+
core_count = try(cpu_options.value.core_count, null)
603+
threads_per_core = try(cpu_options.value.threads_per_core, null)
604+
amd_sev_snp = try(cpu_options.value.amd_sev_snp, null)
605+
}
606+
}
607+
608+
dynamic "capacity_reservation_specification" {
609+
for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : []
610+
611+
content {
612+
capacity_reservation_preference = try(capacity_reservation_specification.value.capacity_reservation_preference, null)
613+
614+
dynamic "capacity_reservation_target" {
615+
for_each = try([capacity_reservation_specification.value.capacity_reservation_target], [])
616+
617+
content {
618+
capacity_reservation_id = try(capacity_reservation_target.value.capacity_reservation_id, null)
619+
capacity_reservation_resource_group_arn = try(capacity_reservation_target.value.capacity_reservation_resource_group_arn, null)
620+
}
621+
}
622+
}
623+
}
624+
625+
dynamic "root_block_device" {
626+
for_each = var.root_block_device
627+
628+
content {
629+
delete_on_termination = try(root_block_device.value.delete_on_termination, null)
630+
encrypted = try(root_block_device.value.encrypted, null)
631+
iops = try(root_block_device.value.iops, null)
632+
kms_key_id = lookup(root_block_device.value, "kms_key_id", null)
633+
volume_size = try(root_block_device.value.volume_size, null)
634+
volume_type = try(root_block_device.value.volume_type, null)
635+
throughput = try(root_block_device.value.throughput, null)
636+
tags = try(root_block_device.value.tags, null)
637+
}
638+
}
639+
640+
dynamic "ebs_block_device" {
641+
for_each = var.ebs_block_device
642+
643+
content {
644+
delete_on_termination = try(ebs_block_device.value.delete_on_termination, null)
645+
device_name = ebs_block_device.value.device_name
646+
encrypted = try(ebs_block_device.value.encrypted, null)
647+
iops = try(ebs_block_device.value.iops, null)
648+
kms_key_id = lookup(ebs_block_device.value, "kms_key_id", null)
649+
snapshot_id = lookup(ebs_block_device.value, "snapshot_id", null)
650+
volume_size = try(ebs_block_device.value.volume_size, null)
651+
volume_type = try(ebs_block_device.value.volume_type, null)
652+
throughput = try(ebs_block_device.value.throughput, null)
653+
tags = try(ebs_block_device.value.tags, null)
654+
}
655+
}
656+
657+
dynamic "ephemeral_block_device" {
658+
for_each = var.ephemeral_block_device
659+
660+
content {
661+
device_name = ephemeral_block_device.value.device_name
662+
no_device = try(ephemeral_block_device.value.no_device, null)
663+
virtual_name = try(ephemeral_block_device.value.virtual_name, null)
664+
}
665+
}
666+
667+
dynamic "metadata_options" {
668+
for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : []
669+
670+
content {
671+
http_endpoint = try(metadata_options.value.http_endpoint, "enabled")
672+
http_tokens = try(metadata_options.value.http_tokens, "optional")
673+
http_put_response_hop_limit = try(metadata_options.value.http_put_response_hop_limit, 1)
674+
instance_metadata_tags = try(metadata_options.value.instance_metadata_tags, null)
675+
}
676+
}
677+
678+
dynamic "network_interface" {
679+
for_each = var.network_interface
680+
681+
content {
682+
device_index = network_interface.value.device_index
683+
network_interface_id = lookup(network_interface.value, "network_interface_id", null)
684+
delete_on_termination = try(network_interface.value.delete_on_termination, false)
685+
}
686+
}
687+
688+
dynamic "private_dns_name_options" {
689+
for_each = length(var.private_dns_name_options) > 0 ? [var.private_dns_name_options] : []
690+
691+
content {
692+
hostname_type = try(private_dns_name_options.value.hostname_type, null)
693+
enable_resource_name_dns_a_record = try(private_dns_name_options.value.enable_resource_name_dns_a_record, null)
694+
enable_resource_name_dns_aaaa_record = try(private_dns_name_options.value.enable_resource_name_dns_aaaa_record, null)
695+
}
696+
}
697+
698+
dynamic "launch_template" {
699+
for_each = length(var.launch_template) > 0 ? [var.launch_template] : []
700+
701+
content {
702+
id = lookup(var.launch_template, "id", null)
703+
name = lookup(var.launch_template, "name", null)
704+
version = lookup(var.launch_template, "version", null)
705+
}
706+
}
707+
708+
dynamic "maintenance_options" {
709+
for_each = length(var.maintenance_options) > 0 ? [var.maintenance_options] : []
710+
711+
content {
712+
auto_recovery = try(maintenance_options.value.auto_recovery, null)
713+
}
714+
}
715+
716+
enclave_options {
717+
enabled = var.enclave_options_enabled
718+
}
719+
720+
source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check
721+
disable_api_termination = var.disable_api_termination
722+
disable_api_stop = var.disable_api_stop
723+
instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior
724+
placement_group = var.placement_group
725+
tenancy = var.tenancy
726+
host_id = var.host_id
727+
728+
credit_specification {
729+
cpu_credits = local.is_t_instance_type ? var.cpu_credits : null
730+
}
731+
732+
timeouts {
733+
create = try(var.timeouts.create, null)
734+
update = try(var.timeouts.update, null)
735+
delete = try(var.timeouts.delete, null)
736+
}
737+
738+
tags = merge({ "Name" = var.name }, var.instance_tags, var.tags)
739+
volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null
740+
741+
lifecycle {
742+
ignore_changes = [ami, user_data]
743+
}
744+
}
745+
379746
################################################################################
380747
# Spot Instance
381748
################################################################################

0 commit comments

Comments
 (0)