Error: creating Auto Scaling Group : ValidationError: You must use a valid fully-formed launch template. Value () for parameter groupId is invalid. The value cannot be empty

As a DevOps engineer, we do encounter such cryptic error messages while launching infrastructures. In the below post, we will try to understand one such error while creating an Auto Scaling Group in AWS cloud, with a possible workaround.

Error:
Error: creating Auto Scaling Group : ValidationError: You must use a valid fully-formed launch template. Value () for parameter groupId is invalid. The value cannot be empty
│ status code: 400, request id: aac314dd-082f-4634-82ca-8bd6

Backgroud

We are trying to create an Auto Scaling group with a launch template.

# Auto Scale Group
resource "aws_autoscaling_group" "osc_asg_application" {
  name                = "osc-asg-application"
  max_size            = 1
  min_size            = 1
  desired_capacity    = 1
  vpc_zone_identifier = [aws_subnet.osc_application.id]
  launch_template {
    id      = aws_launch_template.osc_application_launch_template.id
    version = "$Latest"
  }
  tag {
    key                 = "name"
    value               = "osc-asg-application"
    propagate_at_launch = true
  }
}
# Launch Template
resource "aws_launch_template" "osc_application_launch_template" {
  name                   = "osc-application-launch-template"
  image_id               = data.aws_ami.cloudfront_ami.image_id
  key_name               = "demokey"
  instance_type          = "t2.micro"
  security_group_names = [aws_security_group.osc_security_group.id]
  block_device_mappings {
    device_name = "/dev/sdf"
    ebs {
      volume_size = 8
      volume_type = "gp3"

    }
  }

  dynamic "tag_specifications" {
    for_each = var.tag_resource
    content {
      resource_type = tag_specifications.value
      tags = {
        Name = "osc-application-resource"
      }
    }
  }

  tags = {
    Name = "osc-application-launch-template"
  }
}

When we planned and applied the above terraform code, it failed with the following error code.


Error: creating Auto Scaling Group : ValidationError: You must use a valid fully-formed launch template. Value () for parameter groupId is invalid. The value cannot be empty
│ status code: 400, request id: aac314dd-082f-4634-82ca-8bd6b9fe69a6

Upon investigating the issue futher, we found the security group argument passed in launch template was wrong. We had passed the argument security_group_names instead of vpc_security_group_ids.

We made the changes in the launch template and updated the security group argument.

The updated working launch template code is as below,

resource "aws_launch_template" "osc_application_launch_template" {
  name                 = "osc-application-launch-template"
  image_id             = data.aws_ami.cloudfront_ami.image_id
  key_name             = "demokey"
  instance_type        = "t2.micro"
  vpc_security_group_ids = [aws_security_group.osc_security_group.id]
  block_device_mappings {
    device_name = "/dev/sdf"
    ebs {
      volume_size = 8
      volume_type = "gp3"

    }
  }

  dynamic "tag_specifications" {
    for_each = var.tag_resource
    content {
      resource_type = tag_specifications.value
      tags = {
        Name = "osc-application-resource"
      }
    }
  }

  tags = {
    Name = "osc-application-launch-template"
  }
}

AWS EC2 – Unable to install/download packages from amazon repo to EC2 instance

We may have faced this issue on connecting to the Amazon repo to download/install packages, like Mysql, Apache, Nginx, etc.

We may get a connection time-out error when we run the sudo apt install mysql-server command. The error can occur for any package, in our example, we are installing a MySQL server.

Error

root@ip-10-9-9-58:/home/ubuntu# sudo apt install mysql-server

Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (52.91.65.63), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (52.207.133.243), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (54.87.19.168), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (54.165.17.230), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (3.87.126.146), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (3.209.10.109), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (18.232.150.247), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (34.201.250.36), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (34.237.137.22), connection timed out Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (52.73.36.184), connection timed out

The issue may occur in private or public instances. The most common solution is to first check the security groups assigned to your instance.

Steps

Login to your AWS console > EC2 > Security Groups,

Click on the Edit Outbound rules tab, then on Edit outbound rules.

Ensure we have HTTP TCP protocol for port 80 opened on outbound rules of the assigned security group.

If the rule for HTTP TCP Port 80 is missing, add the new rules in the similar format specified in the above image and save the changes.

Now, try to install the package, it should connect over the internet and install the package successfully.

Restricted Outbound Access

To solve the issue, above we have allowed all outbound traffic, in some cases due to security restrictions the organization may not allow you to open outbound traffic to all IP ranges.

The best practice says we should have minimum permissions.

To accomplish our security goals, we can restrict the outbound traffic to a certain Amazon repo mirrors IPs.

As we saw in the above error, Amazon tries to hit several of its mirrors to download and install the package. We need to copy any of these mirror IP addresses and use them to restrict outbound traffic in our security group.

root@ip-10-9-9-58:/home/ubuntu# sudo apt install mysql-server

Could not connect to us-east-1.ec2.archive.ubuntu.com:80 (52.91.65.63), connection timed out

In this example, we will open outbound only for IP 52.91.65.63.

Login to your AWS console > EC2 > Security Groups, select the assigned security group, and click on the Edit Outbound rules tab, then on Edit outbound rules.

Select the HTTP TCP port 80 rule and change 0.0.0.0/0 to 52.91.65.63/32. Save the changes, this will restrict the outbound rule for HTTP TCP port 80 to only one IP address, 52.91.65.63.

Note: We need to add a CIDR range even when we have one single IP address, Security Group does not allow us to add just a single IP address without a CIDR range. Even for a single IP address, we are required to add a CIDR block.

In our example for our single IP address, we have added a CIDR range /32.

You can change the CIDR block range based on your IP requirements.

Route53 – Overview

AWS Route53 service is used to manage the DNS records for your infrastructure.

  • SOA record stores information about
    • The name of the server that supplied the data of the zone.
    • The administrator of the zone
    • The current version of the data file.
    • The default number of seconds for the time-to-live file on the resource record
  • Alias Records
    • Alias records are used to map resource record sets in your hosted zone to ELB, CloudFront Distribution, or S3 buckets that are configured as websites.
    • Alias record works like CNAME record in that you map one DNS name (www.example.com) to another target DNS name (elbtest.elb.amazonaws.com).
    • Key Differences – A CNAME can’t be used for naked domain names (Zone apex record). You can’t have a CNAME pointing to the naked domain name i.e. http://example.com. It must be either an A record or an alias.
  • Route 53 is a global service and is not restricted to regions.
  • Routing policy in AWS
    • Simple Routing
    • Weighted Routing
    • Latency – Based routing
    • Failover Routing
    • Geolocation Routing
    • MultiValue Routing
  • Simple Routing policy
    • This is the default routing policy when we create a new record set.
    • It is good when we have only one record set.
    • It basically works around robin policy, for two instances each of them will appear one after the another.
  • Weighted routing policy
    • As we can see from the example, with weighted routing we can route the traffic based on the weight to certain instances.
  • Latency Based Routing
    • Latency-based routing allows you to route your traffic based on the lowest network latency for your end-users. (fastest response time).
    • To use latency-based routing, you create a latency resource record set for the amazon EC2 or (ELB) resource in each region that hosts your website. When AWS route 53 receives a query for your website. It selects the latency resource record set for the region that gives the user the lowest latency. Route 53 then responds with the value associated with that record set.
  • Failover Routing Policy
    • Failover routing policies are used when you have to create an Active/Passive setup.
    • Route 53 will monitor the health of your primary site using the health check page.
    • The Heath check page is the endpoint of your instances.
    • We need to create health checks and configure the endpoints to be monitored.
  • Geo-Location Routing Policy
    • Geo Location Routing lets you choose where your traffic will be sent based on the geographical location of the users.
  • Multivalue Answer Routing
    • You can have health check endpoints for each EC2 instance and if anyone fails you can remove it.