Auto Scaling Group With No Associated ELB
- Query id: 8e94dced-9bcc-4203-8eb7-7e41202b2505
- Query name: Auto Scaling Group With No Associated ELB
- Platform: Terraform
- Severity: Medium
- Category: Availability
- CWE: 400
- URL: Github
Description¶
AWS Auto Scaling Groups must have associated ELBs to ensure high availability and improve application performance. This means the attribute 'load_balancers' must be defined and not empty.
Documentation
Code samples¶
Code samples with security vulnerabilities¶
Positive test num. 1 - tf file
resource "aws_autoscaling_group" "bar" {
availability_zones = ["us-east-1a"]
desired_capacity = 1
max_size = 1
min_size = 1
launch_template {
id = aws_launch_template.foobar.id
version = "$Latest"
}
}
Positive test num. 2 - tf file
resource "aws_autoscaling_group" "positive2" {
availability_zones = ["us-east-1a"]
desired_capacity = 1
max_size = 1
min_size = 1
launch_template {
id = aws_launch_template.foobar.id
version = "$Latest"
}
load_balancers = []
}
Positive test num. 3 - tf file
module "positive3" {
source = "terraform-aws-modules/autoscaling/aws"
version = "~> 4.0"
# Autoscaling group
name = "example-asg"
min_size = 0
max_size = 1
desired_capacity = 1
wait_for_capacity_timeout = 0
health_check_type = "EC2"
vpc_zone_identifier = ["subnet-1235678", "subnet-87654321"]
initial_lifecycle_hooks = [
{
name = "ExampleStartupLifeCycleHook"
default_result = "CONTINUE"
heartbeat_timeout = 60
lifecycle_transition = "autoscaling:EC2_INSTANCE_LAUNCHING"
notification_metadata = jsonencode({ "hello" = "world" })
},
{
name = "ExampleTerminationLifeCycleHook"
default_result = "CONTINUE"
heartbeat_timeout = 180
lifecycle_transition = "autoscaling:EC2_INSTANCE_TERMINATING"
notification_metadata = jsonencode({ "goodbye" = "world" })
}
]
instance_refresh = {
strategy = "Rolling"
preferences = {
min_healthy_percentage = 50
}
triggers = ["tag"]
}
# Launch template
lt_name = "example-asg"
description = "Launch template example"
update_default_version = true
use_lt = true
create_lt = true
image_id = "ami-ebd02392"
instance_type = "t3.micro"
ebs_optimized = true
enable_monitoring = true
block_device_mappings = [
{
# Root volume
device_name = "/dev/xvda"
no_device = 0
ebs = {
delete_on_termination = true
encrypted = true
volume_size = 20
volume_type = "gp2"
}
}, {
device_name = "/dev/sda1"
no_device = 1
ebs = {
delete_on_termination = true
encrypted = true
volume_size = 30
volume_type = "gp2"
}
}
]
capacity_reservation_specification = {
capacity_reservation_preference = "open"
}
cpu_options = {
core_count = 1
threads_per_core = 1
}
credit_specification = {
cpu_credits = "standard"
}
instance_market_options = {
market_type = "spot"
spot_options = {
block_duration_minutes = 60
}
}
metadata_options = {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 32
}
network_interfaces = [
{
delete_on_termination = true
description = "eth0"
device_index = 0
security_groups = ["sg-12345678"]
},
{
delete_on_termination = true
description = "eth1"
device_index = 1
security_groups = ["sg-12345678"]
}
]
placement = {
availability_zone = "us-west-1b"
}
tag_specifications = [
{
resource_type = "instance"
tags = { WhatAmI = "Instance" }
},
{
resource_type = "volume"
tags = { WhatAmI = "Volume" }
},
{
resource_type = "spot-instances-request"
tags = { WhatAmI = "SpotInstanceRequest" }
}
]
tags = [
{
key = "Environment"
value = "dev"
propagate_at_launch = true
},
{
key = "Project"
value = "megasecret"
propagate_at_launch = true
},
]
tags_as_map = {
extra_tag1 = "extra_value1"
extra_tag2 = "extra_value2"
}
}
Positive test num. 4 - tf file
module "positive4" {
source = "terraform-aws-modules/autoscaling/aws"
version = "~> 4.0"
# Autoscaling group
name = "example-asg"
min_size = 0
max_size = 1
desired_capacity = 1
wait_for_capacity_timeout = 0
health_check_type = "EC2"
vpc_zone_identifier = ["subnet-1235678", "subnet-87654321"]
load_balancers = []
initial_lifecycle_hooks = [
{
name = "ExampleStartupLifeCycleHook"
default_result = "CONTINUE"
heartbeat_timeout = 60
lifecycle_transition = "autoscaling:EC2_INSTANCE_LAUNCHING"
notification_metadata = jsonencode({ "hello" = "world" })
},
{
name = "ExampleTerminationLifeCycleHook"
default_result = "CONTINUE"
heartbeat_timeout = 180
lifecycle_transition = "autoscaling:EC2_INSTANCE_TERMINATING"
notification_metadata = jsonencode({ "goodbye" = "world" })
}
]
instance_refresh = {
strategy = "Rolling"
preferences = {
min_healthy_percentage = 50
}
triggers = ["tag"]
}
# Launch template
lt_name = "example-asg"
description = "Launch template example"
update_default_version = true
use_lt = true
create_lt = true
image_id = "ami-ebd02392"
instance_type = "t3.micro"
ebs_optimized = true
enable_monitoring = true
block_device_mappings = [
{
# Root volume
device_name = "/dev/xvda"
no_device = 0
ebs = {
delete_on_termination = true
encrypted = true
volume_size = 20
volume_type = "gp2"
}
}, {
device_name = "/dev/sda1"
no_device = 1
ebs = {
delete_on_termination = true
encrypted = true
volume_size = 30
volume_type = "gp2"
}
}
]
capacity_reservation_specification = {
capacity_reservation_preference = "open"
}
cpu_options = {
core_count = 1
threads_per_core = 1
}
credit_specification = {
cpu_credits = "standard"
}
instance_market_options = {
market_type = "spot"
spot_options = {
block_duration_minutes = 60
}
}
metadata_options = {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 32
}
network_interfaces = [
{
delete_on_termination = true
description = "eth0"
device_index = 0
security_groups = ["sg-12345678"]
},
{
delete_on_termination = true
description = "eth1"
device_index = 1
security_groups = ["sg-12345678"]
}
]
placement = {
availability_zone = "us-west-1b"
}
tag_specifications = [
{
resource_type = "instance"
tags = { WhatAmI = "Instance" }
},
{
resource_type = "volume"
tags = { WhatAmI = "Volume" }
},
{
resource_type = "spot-instances-request"
tags = { WhatAmI = "SpotInstanceRequest" }
}
]
tags = [
{
key = "Environment"
value = "dev"
propagate_at_launch = true
},
{
key = "Project"
value = "megasecret"
propagate_at_launch = true
},
]
tags_as_map = {
extra_tag1 = "extra_value1"
extra_tag2 = "extra_value2"
}
}
Positive test num. 5 - tf file
resource "aws_autoscaling_group" "foo" {
name_prefix = "bar-"
vpc_zone_identifier = ["subnet-abcd1234", "subnet-1a2b3c4d"]
launch_configuration = aws_launch_configuration.foobar.name
target_group_arns = []
min_size = 1
max_size = 3
desired_capacity = 2
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 50
}
}
}
Positive test num. 6 - tf file
resource "aws_autoscaling_group" "foo" {
name_prefix = "bar-"
vpc_zone_identifier = ["subnet-abcd1234", "subnet-1a2b3c4d"]
launch_configuration = aws_launch_configuration.foobar.name
min_size = 1
max_size = 3
desired_capacity = 2
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 50
}
}
}
Code samples without security vulnerabilities¶
Negative test num. 1 - tf file
resource "aws_autoscaling_group" "bar3" {
availability_zones = ["us-east-1a"]
desired_capacity = 1
max_size = 1
min_size = 1
launch_template {
id = aws_launch_template.foobar.id
version = "$Latest"
}
load_balancers = ["elb_1"]
}
Negative test num. 2 - tf file
module "asg" {
source = "terraform-aws-modules/autoscaling/aws"
version = "~> 4.0"
# Autoscaling group
name = "example-asg"
min_size = 0
max_size = 1
desired_capacity = 1
wait_for_capacity_timeout = 0
health_check_type = "EC2"
vpc_zone_identifier = ["subnet-1235678", "subnet-87654321"]
load_balancers = ["elb_1"]
initial_lifecycle_hooks = [
{
name = "ExampleStartupLifeCycleHook"
default_result = "CONTINUE"
heartbeat_timeout = 60
lifecycle_transition = "autoscaling:EC2_INSTANCE_LAUNCHING"
notification_metadata = jsonencode({ "hello" = "world" })
},
{
name = "ExampleTerminationLifeCycleHook"
default_result = "CONTINUE"
heartbeat_timeout = 180
lifecycle_transition = "autoscaling:EC2_INSTANCE_TERMINATING"
notification_metadata = jsonencode({ "goodbye" = "world" })
}
]
instance_refresh = {
strategy = "Rolling"
preferences = {
min_healthy_percentage = 50
}
triggers = ["tag"]
}
# Launch template
lt_name = "example-asg"
description = "Launch template example"
update_default_version = true
use_lt = true
create_lt = true
image_id = "ami-ebd02392"
instance_type = "t3.micro"
ebs_optimized = true
enable_monitoring = true
block_device_mappings = [
{
# Root volume
device_name = "/dev/xvda"
no_device = 0
ebs = {
delete_on_termination = true
encrypted = true
volume_size = 20
volume_type = "gp2"
}
}, {
device_name = "/dev/sda1"
no_device = 1
ebs = {
delete_on_termination = true
encrypted = true
volume_size = 30
volume_type = "gp2"
}
}
]
capacity_reservation_specification = {
capacity_reservation_preference = "open"
}
cpu_options = {
core_count = 1
threads_per_core = 1
}
credit_specification = {
cpu_credits = "standard"
}
instance_market_options = {
market_type = "spot"
spot_options = {
block_duration_minutes = 60
}
}
metadata_options = {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 32
}
network_interfaces = [
{
delete_on_termination = true
description = "eth0"
device_index = 0
security_groups = ["sg-12345678"]
},
{
delete_on_termination = true
description = "eth1"
device_index = 1
security_groups = ["sg-12345678"]
}
]
placement = {
availability_zone = "us-west-1b"
}
tag_specifications = [
{
resource_type = "instance"
tags = { WhatAmI = "Instance" }
},
{
resource_type = "volume"
tags = { WhatAmI = "Volume" }
},
{
resource_type = "spot-instances-request"
tags = { WhatAmI = "SpotInstanceRequest" }
}
]
tags = [
{
key = "Environment"
value = "dev"
propagate_at_launch = true
},
{
key = "Project"
value = "megasecret"
propagate_at_launch = true
},
]
tags_as_map = {
extra_tag1 = "extra_value1"
extra_tag2 = "extra_value2"
}
}
Negative test num. 3 - tf file
resource "aws_autoscaling_group" "my_asg" {
name_prefix = format("%s-", var.name)
vpc_zone_identifier = var.private_zone_identifiers
launch_configuration = aws_launch_configuration.config.name
target_group_arns = [var.target_group_arns]
min_size = 1
max_size = 2
desired_capacity = 1
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 50
}
}
}
Negative test num. 4 - tf file
resource "aws_autoscaling_group" "foo" {
name_prefix = "bar-"
vpc_zone_identifier = ["subnet-abcd1234", "subnet-1a2b3c4d"]
launch_configuration = aws_launch_configuration.foobar.name
target_group_arns = ["bar", "baz", "qux"]
min_size = 1
max_size = 3
desired_capacity = 2
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 50
}
}
}