-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(elbv2): add new check
elbv2_is_in_multiple_az
(#4800)
Co-authored-by: Sergio Garcia <[email protected]>
- Loading branch information
Showing
10 changed files
with
238 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
30 changes: 30 additions & 0 deletions
30
...roviders/aws/services/elbv2/elbv2_is_in_multiple_az/elbv2_is_in_multiple_az.metadata.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"Provider": "aws", | ||
"CheckID": "elbv2_is_in_multiple_az", | ||
"CheckTitle": "Elastic Load Balancer V2 (ELBv2) is Configured Across Multiple Availability Zones (AZs)", | ||
"CheckType": [], | ||
"ServiceName": "elbv2", | ||
"SubServiceName": "", | ||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", | ||
"Severity": "medium", | ||
"ResourceType": "AwsElasticLoadBalancingV2LoadBalancer", | ||
"Description": "Ensure whether Elastic Load Balancer V2 (Application, Network, or Gateway Load Balancer) is configured to operate across multiple Availability Zones (AZs). Ensuring that your load balancer is spread across at least two AZs helps maintain high availability and fault tolerance in case of an AZ failure.", | ||
"Risk": "If an ELBv2 is not configured across multiple AZs, there is a risk that an Availability Zone failure could lead to downtime for your application. This could result in a single point of failure, impacting the availability and reliability of your services.", | ||
"RelatedUrl": "https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html#availability-zones", | ||
"Remediation": { | ||
"Code": { | ||
"CLI": "", | ||
"NativeIaC": "", | ||
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/elb-controls.html#elb-13", | ||
"Terraform": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELBv2/enable-multi-az.html" | ||
}, | ||
"Recommendation": { | ||
"Text": "It is recommended to configure your ELBv2 to operate across at least two Availability Zones to enhance fault tolerance and availability.", | ||
"Url": "https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-subnets.html" | ||
} | ||
}, | ||
"Categories": [], | ||
"DependsOn": [], | ||
"RelatedTo": [], | ||
"Notes": "" | ||
} |
26 changes: 26 additions & 0 deletions
26
prowler/providers/aws/services/elbv2/elbv2_is_in_multiple_az/elbv2_is_in_multiple_az.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from typing import List | ||
|
||
from prowler.lib.check.models import Check, Check_Report_AWS | ||
from prowler.providers.aws.services.elbv2.elbv2_client import elbv2_client | ||
|
||
|
||
class elbv2_is_in_multiple_az(Check): | ||
def execute(self) -> List[Check_Report_AWS]: | ||
findings = [] | ||
elbv2_min_azs = elbv2_client.audit_config.get("elbv2_min_azs", 2) | ||
for load_balancer_arn, load_balancer in elbv2_client.loadbalancersv2.items(): | ||
report = Check_Report_AWS(self.metadata()) | ||
report.region = load_balancer.region | ||
report.resource_id = load_balancer.name | ||
report.resource_arn = load_balancer_arn | ||
report.resource_tags = load_balancer.tags | ||
report.status = "FAIL" | ||
report.status_extended = f"ELBv2 {load_balancer.name} is not in at least {elbv2_min_azs} AZs. Is only in {', '.join(load_balancer.availability_zones.keys())}." | ||
|
||
if len(load_balancer.availability_zones) >= elbv2_min_azs: | ||
report.status = "PASS" | ||
report.status_extended = f"ELBv2 {load_balancer.name} is at least in {elbv2_min_azs} AZs: {', '.join(load_balancer.availability_zones.keys())}." | ||
|
||
findings.append(report) | ||
|
||
return findings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
tests/providers/aws/services/elbv2/elbv2_is_in_multiple_az/elbv2_is_in_multiple_az_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
from unittest import mock | ||
|
||
from boto3 import client, resource | ||
from moto import mock_aws | ||
|
||
from tests.providers.aws.utils import ( | ||
AWS_REGION_EU_WEST_1, | ||
AWS_REGION_EU_WEST_1_AZA, | ||
AWS_REGION_EU_WEST_1_AZB, | ||
set_mocked_aws_provider, | ||
) | ||
|
||
|
||
class Test_elbv2_is_in_multiple_az: | ||
@mock_aws | ||
def test_no_elbs(self): | ||
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2 | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
), mock.patch( | ||
"prowler.providers.aws.services.elbv2.elbv2_is_in_multiple_az.elbv2_is_in_multiple_az.elbv2_client", | ||
new=ELBv2(aws_provider), | ||
): | ||
# Test Check | ||
from prowler.providers.aws.services.elbv2.elbv2_is_in_multiple_az.elbv2_is_in_multiple_az import ( | ||
elbv2_is_in_multiple_az, | ||
) | ||
|
||
check = elbv2_is_in_multiple_az() | ||
result = check.execute() | ||
|
||
assert len(result) == 0 | ||
|
||
@mock_aws | ||
def test_elbv2_in_one_avaibility_zone(self): | ||
# Create VPC, Subnets and Security Group | ||
elbv2_client = client("elbv2", region_name=AWS_REGION_EU_WEST_1) | ||
|
||
ec2 = resource("ec2", region_name=AWS_REGION_EU_WEST_1) | ||
|
||
security_group = ec2.create_security_group( | ||
GroupName="a-security-group", Description="First One" | ||
) | ||
|
||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | ||
|
||
subnet1 = ec2.create_subnet( | ||
AvailabilityZone=AWS_REGION_EU_WEST_1_AZA, | ||
CidrBlock="10.0.1.0/24", | ||
VpcId=vpc.id, | ||
) | ||
|
||
lb_arn = elbv2_client.create_load_balancer( | ||
Name="test_elbv2", | ||
Subnets=[subnet1.id], | ||
SecurityGroups=[security_group.id], | ||
)["LoadBalancers"][0]["LoadBalancerArn"] | ||
|
||
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2 | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
), mock.patch( | ||
"prowler.providers.aws.services.elbv2.elbv2_is_in_multiple_az.elbv2_is_in_multiple_az.elbv2_client", | ||
new=ELBv2(aws_provider), | ||
): | ||
from prowler.providers.aws.services.elbv2.elbv2_is_in_multiple_az.elbv2_is_in_multiple_az import ( | ||
elbv2_is_in_multiple_az, | ||
) | ||
|
||
check = elbv2_is_in_multiple_az() | ||
result = check.execute() | ||
|
||
assert len(result) == 1 | ||
assert result[0].status == "FAIL" | ||
assert ( | ||
result[0].status_extended | ||
== f"ELBv2 test_elbv2 is not in at least 2 AZs. Is only in {AWS_REGION_EU_WEST_1_AZA}." | ||
) | ||
assert result[0].region == AWS_REGION_EU_WEST_1 | ||
assert result[0].resource_id == "test_elbv2" | ||
assert result[0].resource_arn == lb_arn | ||
assert result[0].resource_tags == [] | ||
|
||
@mock_aws | ||
def test_elbv2_in_two_avaibility_zones(self): | ||
# Create VPC, Subnets and Security Group | ||
elbv2_client = client("elbv2", region_name=AWS_REGION_EU_WEST_1) | ||
|
||
ec2 = resource("ec2", region_name=AWS_REGION_EU_WEST_1) | ||
|
||
security_group = ec2.create_security_group( | ||
GroupName="a-security-group", Description="First One" | ||
) | ||
|
||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | ||
|
||
subnet1 = ec2.create_subnet( | ||
AvailabilityZone=AWS_REGION_EU_WEST_1_AZA, | ||
CidrBlock="10.0.1.0/24", | ||
VpcId=vpc.id, | ||
) | ||
|
||
subnet2 = ec2.create_subnet( | ||
AvailabilityZone=AWS_REGION_EU_WEST_1_AZB, | ||
CidrBlock="10.0.2.0/24", | ||
VpcId=vpc.id, | ||
) | ||
|
||
lb_arn = elbv2_client.create_load_balancer( | ||
Name="test_elbv2", | ||
Subnets=[subnet1.id, subnet2.id], | ||
SecurityGroups=[security_group.id], | ||
)["LoadBalancers"][0]["LoadBalancerArn"] | ||
|
||
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2 | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
), mock.patch( | ||
"prowler.providers.aws.services.elbv2.elbv2_is_in_multiple_az.elbv2_is_in_multiple_az.elbv2_client", | ||
new=ELBv2(aws_provider), | ||
): | ||
from prowler.providers.aws.services.elbv2.elbv2_is_in_multiple_az.elbv2_is_in_multiple_az import ( | ||
elbv2_is_in_multiple_az, | ||
) | ||
|
||
check = elbv2_is_in_multiple_az() | ||
result = check.execute() | ||
|
||
assert len(result) == 1 | ||
assert result[0].status == "PASS" | ||
assert ( | ||
result[0].status_extended | ||
== f"ELBv2 test_elbv2 is at least in 2 AZs: {AWS_REGION_EU_WEST_1_AZA}, {AWS_REGION_EU_WEST_1_AZB}." | ||
) | ||
assert result[0].region == AWS_REGION_EU_WEST_1 | ||
assert result[0].resource_id == "test_elbv2" | ||
assert result[0].resource_arn == lb_arn | ||
assert result[0].resource_tags == [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters