mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
feat(autoscaling): Add autoscaling_group_capacity_rebalance_enabled check (#5523)
Co-authored-by: Sergio <sergio@prowler.com>
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "autoscaling_group_capacity_rebalance_enabled",
|
||||
"CheckTitle": "Check if Amazon EC2 Auto Scaling groups have capacity rebalance enabled.",
|
||||
"CheckType": [
|
||||
"Resiliance"
|
||||
],
|
||||
"ServiceName": "autoscaling",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:aws:autoscaling:region:account-id:autoScalingGroup/autoScalingGroupName",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsAutoScalingAutoScalingGroup",
|
||||
"Description": "This control checks whether an Amazon EC2 Auto Scaling group has capacity rebalance enabled.",
|
||||
"Risk": "When you don't use Capacity Rebalancing, Amazon EC2 Auto Scaling doesn't replace Spot Instances until after the Amazon EC2 Spot service interrupts the instances and their health check fails. Before interrupting an instance, Amazon EC2 always gives both an EC2 instance rebalance recommendation and a Spot two-minute instance interruption notice.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-capacity-rebalancing.html",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws autoscaling create-auto-scaling-group --capacity-rebalance",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://docs.aws.amazon.com/autoscaling/ec2/userguide/enable-capacity-rebalancing-console-cli.html",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "When you enable Capacity Rebalancing for your Auto Scaling group, Amazon EC2 Auto Scaling attempts to proactively replace the Spot Instances in your group that have received a rebalance recommendation. This provides an opportunity to rebalance your workload to new Spot Instances that aren't at an elevated risk of interruption.",
|
||||
"Url": "https://docs.aws.amazon.com/awssupport/latest/user/fault-tolerance-checks.html#amazon-ec2-auto-scaling-group-capacity-rebalance-enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"redundancy"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_client import (
|
||||
autoscaling_client,
|
||||
)
|
||||
|
||||
|
||||
class autoscaling_group_capacity_rebalance_enabled(Check):
|
||||
def execute(self):
|
||||
findings = []
|
||||
for group in autoscaling_client.groups:
|
||||
if group.load_balancers and group.target_groups:
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = group.region
|
||||
report.resource_id = group.name
|
||||
report.resource_arn = group.arn
|
||||
report.resource_tags = group.tags
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Autoscaling group {group.name} does not have capacity rebalance enabled."
|
||||
if group.capacity_rebalance:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Autoscaling group {group.name} has capacity rebalance enabled."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -85,6 +85,9 @@ class AutoScaling(AWSService):
|
||||
tags=group.get("Tags"),
|
||||
instance_types=instance_types,
|
||||
az_instance_types=az_instance_types,
|
||||
capacity_rebalance=group.get(
|
||||
"CapacityRebalance", False
|
||||
),
|
||||
launch_template=group.get("LaunchTemplate", {}),
|
||||
mixed_instances_policy_launch_template=group.get(
|
||||
"MixedInstancesPolicy", {}
|
||||
@@ -168,6 +171,7 @@ class Group(BaseModel):
|
||||
tags: list = []
|
||||
instance_types: list = []
|
||||
az_instance_types: dict = {}
|
||||
capacity_rebalance: bool
|
||||
launch_template: dict = {}
|
||||
mixed_instances_policy_launch_template: dict = {}
|
||||
health_check_type: str
|
||||
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_aws
|
||||
|
||||
from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider
|
||||
|
||||
|
||||
class Test_autoscaling_group_capacity_rebalance_enabled:
|
||||
@mock_aws
|
||||
def test_no_autoscaling(self):
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION_US_EAST_1)
|
||||
autoscaling_client.groups = []
|
||||
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_group_capacity_rebalance_enabled.autoscaling_group_capacity_rebalance_enabled.autoscaling_client",
|
||||
new=AutoScaling(aws_provider),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_group_capacity_rebalance_enabled.autoscaling_group_capacity_rebalance_enabled import (
|
||||
autoscaling_group_capacity_rebalance_enabled,
|
||||
)
|
||||
|
||||
check = autoscaling_group_capacity_rebalance_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_groups_capacity_rebalance_enabled(self):
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION_US_EAST_1)
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="test",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
)
|
||||
|
||||
ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1)
|
||||
vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
|
||||
|
||||
elastic_load_balancer = client("elbv2", region_name=AWS_REGION_US_EAST_1)
|
||||
target_group = elastic_load_balancer.create_target_group(
|
||||
Name="my-target-group",
|
||||
Protocol="HTTP",
|
||||
Port=80,
|
||||
VpcId=vpc_id,
|
||||
HealthCheckProtocol="HTTP",
|
||||
HealthCheckPort="80",
|
||||
HealthCheckPath="/",
|
||||
HealthCheckIntervalSeconds=30,
|
||||
HealthCheckTimeoutSeconds=5,
|
||||
HealthyThresholdCount=5,
|
||||
UnhealthyThresholdCount=2,
|
||||
Matcher={"HttpCode": "200"},
|
||||
)
|
||||
|
||||
autoscaling_group_name = "my-autoscaling-group"
|
||||
autoscaling_client.create_auto_scaling_group(
|
||||
AutoScalingGroupName=autoscaling_group_name,
|
||||
LaunchConfigurationName="test",
|
||||
MinSize=0,
|
||||
MaxSize=0,
|
||||
DesiredCapacity=0,
|
||||
AvailabilityZones=["us-east-1a", "us-east-1b"],
|
||||
HealthCheckType="ELB",
|
||||
CapacityRebalance=True,
|
||||
LoadBalancerNames=["my-load-balancer"],
|
||||
TargetGroupARNs=[target_group["TargetGroups"][0]["TargetGroupArn"]],
|
||||
)
|
||||
|
||||
autoscaling_group_arn = autoscaling_client.describe_auto_scaling_groups(
|
||||
AutoScalingGroupNames=[autoscaling_group_name]
|
||||
)["AutoScalingGroups"][0]["AutoScalingGroupARN"]
|
||||
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_group_capacity_rebalance_enabled.autoscaling_group_capacity_rebalance_enabled.autoscaling_client",
|
||||
new=AutoScaling(aws_provider),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_group_capacity_rebalance_enabled.autoscaling_group_capacity_rebalance_enabled import (
|
||||
autoscaling_group_capacity_rebalance_enabled,
|
||||
)
|
||||
|
||||
check = autoscaling_group_capacity_rebalance_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Autoscaling group {autoscaling_group_name} has capacity rebalance enabled."
|
||||
)
|
||||
assert result[0].resource_id == autoscaling_group_name
|
||||
assert result[0].resource_arn == autoscaling_group_arn
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_tags == []
|
||||
|
||||
@mock_aws
|
||||
def test_groups_with_capacity_rebalance_disabled(self):
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION_US_EAST_1)
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="test",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
)
|
||||
|
||||
ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1)
|
||||
vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
|
||||
|
||||
elastic_load_balancer = client("elbv2", region_name=AWS_REGION_US_EAST_1)
|
||||
target_group = elastic_load_balancer.create_target_group(
|
||||
Name="my-target-group",
|
||||
Protocol="HTTP",
|
||||
Port=80,
|
||||
VpcId=vpc_id,
|
||||
HealthCheckProtocol="HTTP",
|
||||
HealthCheckPort="80",
|
||||
HealthCheckPath="/",
|
||||
HealthCheckIntervalSeconds=30,
|
||||
HealthCheckTimeoutSeconds=5,
|
||||
HealthyThresholdCount=5,
|
||||
UnhealthyThresholdCount=2,
|
||||
Matcher={"HttpCode": "200"},
|
||||
)
|
||||
|
||||
autoscaling_group_name = "my-autoscaling-group"
|
||||
autoscaling_client.create_auto_scaling_group(
|
||||
AutoScalingGroupName=autoscaling_group_name,
|
||||
LaunchConfigurationName="test",
|
||||
MinSize=0,
|
||||
MaxSize=0,
|
||||
DesiredCapacity=0,
|
||||
AvailabilityZones=["us-east-1a"],
|
||||
HealthCheckType="EC2",
|
||||
LoadBalancerNames=["my-load-balancer"],
|
||||
TargetGroupARNs=[target_group["TargetGroups"][0]["TargetGroupArn"]],
|
||||
)
|
||||
|
||||
autoscaling_group_arn = autoscaling_client.describe_auto_scaling_groups(
|
||||
AutoScalingGroupNames=[autoscaling_group_name]
|
||||
)["AutoScalingGroups"][0]["AutoScalingGroupARN"]
|
||||
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_group_capacity_rebalance_enabled.autoscaling_group_capacity_rebalance_enabled.autoscaling_client",
|
||||
new=AutoScaling(aws_provider),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_group_capacity_rebalance_enabled.autoscaling_group_capacity_rebalance_enabled import (
|
||||
autoscaling_group_capacity_rebalance_enabled,
|
||||
)
|
||||
|
||||
check = autoscaling_group_capacity_rebalance_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Autoscaling group {autoscaling_group_name} does not have capacity rebalance enabled."
|
||||
)
|
||||
assert result[0].resource_id == autoscaling_group_name
|
||||
assert result[0].resource_tags == []
|
||||
assert result[0].resource_arn == autoscaling_group_arn
|
||||
@@ -27,6 +27,7 @@ def mock_make_api_call(self, operation_name, kwarg):
|
||||
"AutoScalingGroupName": "my-autoscaling-group",
|
||||
"AutoScalingGroupARN": "arn:aws:autoscaling:us-east-1:123456789012:autoScalingGroup:uuid:autoScalingGroupName/my-autoscaling-group",
|
||||
"AvailabilityZones": ["us-east-1a", "us-east-1b"],
|
||||
"CapacityRebalance": True,
|
||||
"Tags": [
|
||||
{
|
||||
"Key": "tag_test",
|
||||
@@ -176,6 +177,7 @@ class Test_AutoScaling_Service:
|
||||
MaxSize=0,
|
||||
DesiredCapacity=0,
|
||||
AvailabilityZones=["us-east-1a", "us-east-1b"],
|
||||
CapacityRebalance=True,
|
||||
Tags=[
|
||||
{
|
||||
"Key": "tag_test",
|
||||
@@ -196,6 +198,7 @@ class Test_AutoScaling_Service:
|
||||
"us-east-1a",
|
||||
"us-east-1b",
|
||||
]
|
||||
assert autoscaling.groups[0].capacity_rebalance
|
||||
assert autoscaling.groups[0].tags == [
|
||||
{
|
||||
"Key": "tag_test",
|
||||
|
||||
Reference in New Issue
Block a user