From 96f8777a12e9b7edf613dd08bd9c05a21b7a9f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Tue, 14 Nov 2023 18:12:15 +0100 Subject: [PATCH] [TF-10414] Replace EC2 AWS Launch Configuration for AWS Launch Templates (#317) --- main.tf | 54 +++++++++++++++++----------------- modules/vm/main.tf | 64 +++++++++++++++++++++++++++-------------- modules/vm/variables.tf | 15 +++++++++- variables.tf | 15 ++++++++++ 4 files changed, 99 insertions(+), 49 deletions(-) diff --git a/main.tf b/main.tf index 18d1337a..94678c8f 100644 --- a/main.tf +++ b/main.tf @@ -24,7 +24,7 @@ data "aws_kms_key" "main" { } # ----------------------------------------------------------------------------- -# AWS Service Accounts +# AWS Service Accounts # ----------------------------------------------------------------------------- module "service_accounts" { source = "./modules/service_accounts" @@ -330,29 +330,31 @@ module "private_tcp_load_balancer" { module "vm" { source = "./modules/vm" - active_active = local.active_active - aws_iam_instance_profile = module.service_accounts.iam_instance_profile.name - ami_id = local.ami_id - aws_lb = var.load_balancing_scheme == "PRIVATE_TCP" ? null : module.load_balancer[0].aws_lb_security_group - aws_lb_target_group_tfe_tg_443_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_443_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_443_arn - aws_lb_target_group_tfe_tg_8800_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn - asg_tags = var.asg_tags - default_ami_id = local.default_ami_id - enable_disk = local.enable_disk - enable_ssh = var.enable_ssh - ebs_device_name = var.ebs_device_name - ebs_volume_size = var.ebs_volume_size - ebs_volume_type = var.ebs_volume_type - ebs_iops = var.ebs_iops - ebs_delete_on_termination = var.ebs_delete_on_termination - friendly_name_prefix = var.friendly_name_prefix - health_check_grace_period = var.health_check_grace_period - instance_type = var.instance_type - is_replicated_deployment = var.is_replicated_deployment - key_name = var.key_name - network_id = local.network_id - network_subnets_private = local.network_private_subnets - network_private_subnet_cidrs = local.network_private_subnet_cidrs - node_count = var.node_count - user_data_base64 = var.is_replicated_deployment ? module.tfe_init_replicated[0].tfe_userdata_base64_encoded : module.tfe_init_fdo[0].tfe_userdata_base64_encoded + active_active = local.active_active + aws_iam_instance_profile = module.service_accounts.iam_instance_profile.name + ami_id = local.ami_id + aws_lb = var.load_balancing_scheme == "PRIVATE_TCP" ? null : module.load_balancer[0].aws_lb_security_group + aws_lb_target_group_tfe_tg_443_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_443_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_443_arn + aws_lb_target_group_tfe_tg_8800_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn + asg_tags = var.asg_tags + ec2_launch_template_tag_specifications = var.ec2_launch_template_tag_specifications + default_ami_id = local.default_ami_id + enable_disk = local.enable_disk + enable_ssh = var.enable_ssh + ebs_device_name = var.ebs_device_name + ebs_volume_size = var.ebs_volume_size + ebs_volume_type = var.ebs_volume_type + ebs_iops = var.ebs_iops + ebs_delete_on_termination = var.ebs_delete_on_termination + ebs_snapshot_id = var.ebs_snapshot_id + friendly_name_prefix = var.friendly_name_prefix + health_check_grace_period = var.health_check_grace_period + instance_type = var.instance_type + is_replicated_deployment = var.is_replicated_deployment + key_name = var.key_name + network_id = local.network_id + network_subnets_private = local.network_private_subnets + network_private_subnet_cidrs = local.network_private_subnet_cidrs + node_count = var.node_count + user_data_base64 = var.is_replicated_deployment ? module.tfe_init_replicated[0].tfe_userdata_base64_encoded : module.tfe_init_fdo[0].tfe_userdata_base64_encoded } diff --git a/modules/vm/main.tf b/modules/vm/main.tf index 75076fc2..9bf2960e 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -72,39 +72,55 @@ resource "aws_security_group_rule" "tfe_dashboard" { cidr_blocks = var.aws_lb == null ? var.network_private_subnet_cidrs : null } -resource "aws_launch_configuration" "tfe" { - name_prefix = "${var.friendly_name_prefix}-tfe-ec2-asg-lt-" - image_id = var.ami_id - instance_type = var.instance_type - user_data_base64 = var.user_data_base64 +resource "aws_launch_template" "tfe" { + name_prefix = "${var.friendly_name_prefix}-tfe-ec2-asg-launch-template-" + image_id = var.ami_id + instance_type = var.instance_type + user_data = var.user_data_base64 + key_name = var.key_name + vpc_security_group_ids = [aws_security_group.tfe_instance.id] - iam_instance_profile = var.aws_iam_instance_profile - key_name = var.key_name - security_groups = [aws_security_group.tfe_instance.id] + dynamic "tag_specifications" { + for_each = var.ec2_launch_template_tag_specifications + + content { + resource_type = tag_specifications.value["resource_type"] + tags = tag_specifications.value["tags"] + } + } + + iam_instance_profile { + name = var.aws_iam_instance_profile + } metadata_options { - http_endpoint = "enabled" - # A hop limit of at least 2 is required for AWS Cost Estimation to function. + http_endpoint = "enabled" http_put_response_hop_limit = 2 http_tokens = "optional" } - root_block_device { - encrypted = true - volume_type = "gp2" - volume_size = 50 - delete_on_termination = true + block_device_mappings { + device_name = "/dev/sda1" + ebs { + encrypted = true + volume_type = "gp2" + volume_size = 50 + delete_on_termination = true + } } - dynamic "ebs_block_device" { + dynamic "block_device_mappings" { for_each = var.enable_disk ? [1] : [0] content { - device_name = var.ebs_device_name - volume_size = var.ebs_volume_size - volume_type = var.ebs_volume_type - iops = var.ebs_iops - delete_on_termination = var.ebs_delete_on_termination + device_name = var.ebs_device_name + ebs { + volume_size = var.ebs_volume_size + volume_type = var.ebs_volume_type + iops = var.ebs_iops + delete_on_termination = var.ebs_delete_on_termination + snapshot_id = var.ebs_snapshot_id + } } } @@ -127,7 +143,11 @@ resource "aws_autoscaling_group" "tfe_asg" { # since RHEL has longer startup time health_check_grace_period = local.health_check_grace_period health_check_type = "ELB" - launch_configuration = aws_launch_configuration.tfe.name + + launch_template { + id = aws_launch_template.tfe.id + version = "$Latest" + } dynamic "tag" { for_each = local.tags diff --git a/modules/vm/variables.tf b/modules/vm/variables.tf index d5017c5a..01850747 100644 --- a/modules/vm/variables.tf +++ b/modules/vm/variables.tf @@ -97,6 +97,14 @@ variable "key_name" { type = string } +variable "ec2_launch_template_tag_specifications" { + description = "(Optional) List of tag specifications to apply to the launch template." + type = list(object({ + resource_type = string + tags = map(string) + })) +} + # Mounted Disk Installation # ------------------------- variable "ebs_device_name" { @@ -124,7 +132,12 @@ variable "ebs_delete_on_termination" { description = "(Optional if Mounted Disk installation) Whether the volume should be destroyed on instance termination." } +variable "ebs_snapshot_id" { + type = string + description = "(Optional) The Snapshot ID to mount (instead of a new volume)" +} + variable "enable_disk" { type = bool description = "Will you be attaching an EBS block device for a Mounted Disk Installation?" -} \ No newline at end of file +} diff --git a/variables.tf b/variables.tf index cafb5f22..64ca45c8 100644 --- a/variables.tf +++ b/variables.tf @@ -14,6 +14,15 @@ variable "ami_id" { description = "AMI ID to use for TFE instances" } +variable "ec2_launch_template_tag_specifications" { + description = "(Optional) List of tag specifications to apply to the launch template." + type = list(object({ + resource_type = string + tags = map(string) + })) + default = [] +} + variable "asg_tags" { type = map(string) description = "(Optional) Map of tags only used for the autoscaling group. If you are using the AWS provider's default_tags,please note that it tags every taggable resource except for the autoscaling group, therefore this variable may be used to duplicate the key/value pairs in the default_tags if you wish." @@ -599,6 +608,12 @@ variable "ebs_volume_type" { } } +variable "ebs_snapshot_id" { + type = string + description = "(Optional) The Snapshot ID to mount (instead of a new volume)" + default = null +} + # External Vault ONLY # ------------------- variable "extern_vault_addr" {