0

My EC2 instance resource code

resource "aws_instance" "my-sample-webapp-ec2" {
  availability_zone                    = var.availability_zone
  subnet_id                            = var.subnet_id
  key_name                             = var.ec2_instance_name
  instance_initiated_shutdown_behavior = "stop"
  disable_api_termination              = false
  #  vpc_security_group_ids               = var.vpc_security_group_ids

  launch_template {
    id      = var.launch_template_id
    version = "$Latest"
  }

  tags = {
    "Name" = var.ec2_instance_name
  }

  root_block_device {
    delete_on_termination = true
  }

}

My launch template already exists in AWS region - checked

My Module import for the above EC2 resource

module "aws_ec2_machines" {
  source              = "./modules/ec2_machines"
  count               = length(local.availability_zones)
  launch_template_id  = var.launch_template_id
  launch_template_ver = var.launch_template_ver
  ec2_instance_name   = "${var.ec2_instance_name}-${count.index + 1}"
  availability_zone   = local.availability_zones[count.index]
}

what I want to do is below

  1. Specify my launch template and launch EC2 instance(s)

  2. Subnet association should happen based on availability_zone

Currently, I have only 3 subnets (1 per availability zone), but they are not default. Also, the VPC under which the subnets are created is also not the default VPC.

The error I am getting

│ Error: Error launching source instance: InvalidParameterValue: Value (us-east-2b) for parameter availabilityZone is invalid. Subnet 'subnet-xxxxxx' is in the availability zone us-east-2a
│       status code: 400, request id: 75a126cb-59eb-40fe-9fa5-579ed908edbd
│
│   with module.aws_ec2_machines[1].aws_instance.my-sample-webapp-ec2,
│   on modules\ec2_machines\main.tf line 7, in resource "aws_instance" "my-sample-webapp-ec2":
│    7: resource "aws_instance" "my-sample-webapp-ec2" {
│
╵

What am I doing wrong?

ha9u63a7
  • 6,233
  • 16
  • 73
  • 108
  • 2
    You forgot probably the most important thing: what error do you get? – Ervin Szilagyi Jun 12 '22 at 16:21
  • @ErvinSzilagyi added this now. Btw - I believe this is potentially a bug in terraform. Apparently, launch template makes more sense if attached to auto scaling group. But I don't want that. I just want to be able to launch an EC2 instance using launch template and be able to assign subnet (which is not part of default VPC or a default subnet) - not sure why that's so difficult – ha9u63a7 Jun 12 '22 at 16:28
  • Regardless of the difficulty, if you want your EC2 instance to be placed in a non-default VPC, you have to specify a subnet. You can notice that the `aws_instance` does not accept a VPC id anywhere, but it can accept a `subnet_id`, from which it knows in which VPC should the instance be in. This is because each subnet can pe part of only one VPC. Now, if you omit the `subnet_id`, your instance will be placed automatically in the default VPC. This is not a bug, this is how the provider works. – Ervin Szilagyi Jun 12 '22 at 16:57
  • Knowing this `availability_zone` attribute makes only sense if you place your EC2 instance in the default VPC (you emit `subnet_id` essentially). In AWS each subnet can be part of on availability zone. – Ervin Szilagyi Jun 12 '22 at 16:58

1 Answers1

1

OK - I figured out to problem (pen and pencil writing)

  1. Launch Template ID does not need to have any subnet defined

  2. But any VPC should have subnets created and (good practice) assigned to a different AZ

    a. e.g. subnet-2a should be with AZ 1, subnet-2b should be with AZ 2 etc.

  3. Now, with the below resource/module invocation - it all worked well

    resource "aws_instance" "my-sample-webapp-ec2" {
      subnet_id                            = var.subnet_id
      instance_initiated_shutdown_behavior = "stop"
      disable_api_termination              = false
    
      launch_template {
        id      = var.launch_template_id
        version = "$Latest"
      }
    
      tags = {
        "Name" = var.ec2_instance_name
      }
    
    root_block_device {
    delete_on_termination = true
    }
    
    }
    

And the subsequent module call in main.tf

  module "aws_ec2_machines" {
  source              = "./modules/ec2_machines"
  count               = length(local.availability_zones)
  launch_template_id  = var.launch_template_id
  launch_template_ver = var.launch_template_ver
  ec2_instance_name   = "${var.ec2_instance_name}-${count.index + 1}"
  subnet_id           = local.subnets[count.index % local.available_subnet_count]
}
ha9u63a7
  • 6,233
  • 16
  • 73
  • 108