resource "aws_instance" "ec2-instance" { ami = var.ami-id instance_type = var.instance-type associate_public_ip_address = var.asso-public-ip // availability_zone = var.az iam_instance_profile = var.instance-profile key_name = var.create-ssh-key ? aws_key_pair.this[0].key_name : var.key-name private_ip = var.private-ip root_block_device { encrypted = var.ebs-encrypted volume_size = var.root-volume-size volume_type = var.root-volume-type kms_key_id = var.kms-key-id delete_on_termination = var.delete-on-termination } ebs_optimized = true subnet_id = var.subnet-id vpc_security_group_ids = var.security-groups # IMDSv2 requirement dynamic "metadata_options" { for_each = var.disable_secure_idmsv2 == false ? { set_idmsv2 : true } : {} content { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 2 } } # spot instance option dynamic "instance_market_options" { for_each = var.spot-max-price > 0 ? { use_spot : true } : {} content { market_type = "spot" dynamic "spot_options" { for_each = { use_spot : true } content { max_price = var.spot-max-price } } } } disable_api_termination = var.enable-termination-protection user_data = var.user-data monitoring = var.enable-detail-monitoring tags = merge(var.additional-tags, { "Name" : var.instance-name }) volume_tags = merge({ "Name" : "${var.instance-name}-root" }, data.aws_default_tags.this.tags) # do not redeploy instance when a new ami is released lifecycle { ignore_changes = [ami] } } resource "aws_ebs_volume" "data-volumes" { for_each = var.data-volumes availability_zone = aws_instance.ec2-instance.availability_zone size = each.value["size"] type = each.value["type"] iops = try(each.value["iops"], null) kms_key_id = aws_instance.ec2-instance.root_block_device[0].kms_key_id encrypted = aws_instance.ec2-instance.root_block_device[0].encrypted tags = merge( { Name : "${var.instance-name}-${each.key}" }, data.aws_default_tags.this.tags ) } locals { a_to_z = split(",", "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z") } resource "aws_volume_attachment" "data-volume-attachments" { count = length(aws_ebs_volume.data-volumes) volume_id = [for v in aws_ebs_volume.data-volumes : v.id][count.index] instance_id = aws_instance.ec2-instance.id device_name = "/dev/xvda${element(local.a_to_z, count.index)}" } resource "aws_eip" "ec2-eip" { count = var.asso-eip ? 1 : 0 instance = aws_instance.ec2-instance.id domain = "vpc" } resource "tls_private_key" "this" { count = var.create-ssh-key ? 1 : 0 algorithm = "ED25519" } resource "aws_key_pair" "this" { count = var.create-ssh-key ? 1 : 0 key_name = "${var.instance-name}-sshkey" public_key = tls_private_key.this[0].public_key_openssh } resource "random_id" "this" { byte_length = 2 } resource "aws_secretsmanager_secret" "this" { count = var.create-ssh-key ? 1 : 0 name = "${var.instance-name}-sshkey-${random_id.this.dec}" description = "Private key for ${aws_instance.ec2-instance.id}" } resource "aws_secretsmanager_secret_version" "this" { count = var.create-ssh-key ? 1 : 0 secret_id = aws_secretsmanager_secret.this[0].id secret_string = tls_private_key.this[0].private_key_openssh } data "aws_default_tags" "this" { lifecycle { postcondition { condition = length(self.tags) >= 1 error_message = "Validation failed: Provider default_tags not set." } } }