-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(elasticache): Ensure Redis replication groups have automatic failover enabled #4853
Merged
MrCloudSec
merged 9 commits into
master
from
PRWLR-4508-elasti-cache-redis-oss-replication-groups-should-have-automatic-failover-enabled
Sep 12, 2024
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
d431ea1
feat(elasticache): Ensure Redis cache clusters have automatic failove…
HugoPBrito 5bd4682
Merge branch 'master' of https://github.com/prowler-cloud/prowler int…
HugoPBrito f7593c2
feat(elasticache): changed automatic_failover type from bool to str
HugoPBrito b6826f8
fix(elasticache): Try to fix codecov
HugoPBrito c86d9b1
feat(elasticache): resolved comments and updated mocking
HugoPBrito 2aced89
feat(elaticache): resolved comments
HugoPBrito 61a15c6
chore(elasticache): put caps in ElastiCache check output
HugoPBrito 4c0faee
feat(elasticache): improved links in metadata
HugoPBrito 7b62c9c
chore: enhance check
MrCloudSec File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
30 changes: 30 additions & 0 deletions
30
...matic_failover_enabled/elasticache_redis_cluster_automatic_failover_enabled.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": "elasticache_redis_cluster_automatic_failover_enabled", | ||
"CheckTitle": "Ensure Elasticache Redis clusters have automatic failover enabled.", | ||
"CheckType": [], | ||
"ServiceName": "elasticache", | ||
"SubServiceName": "", | ||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", | ||
"Severity": "medium", | ||
"ResourceType": "AWSElastiCacheReplicationGroup", | ||
"Description": "Ensure Elasticache Redis OSS cache clusters use automatic failover.", | ||
"Risk": "If automatic failover is not enabled, a failure in the primary node could result in significant downtime, impacting the availability and resilience of your application.", | ||
"RelatedUrl": "https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/AutoFailover.html", | ||
"Remediation": { | ||
"Code": { | ||
"CLI": "", | ||
"NativeIaC": "", | ||
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/elasticache-controls.html#elasticache-3", | ||
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-aws-elasticache-redis-cluster-with-multi-az-automatic-failover-feature-set-to-enabled/" | ||
}, | ||
"Recommendation": { | ||
"Text": "Enable automatic failover for ElastiCache (Redis OSS) clusters to ensure high availability and minimize downtime during failures.", | ||
"Url": "https://redis.io/blog/highly-available-in-memory-cloud-datastores/" | ||
} | ||
}, | ||
"Categories": [], | ||
"DependsOn": [], | ||
"RelatedTo": [], | ||
"Notes": "" | ||
} |
25 changes: 25 additions & 0 deletions
25
...luster_automatic_failover_enabled/elasticache_redis_cluster_automatic_failover_enabled.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,25 @@ | ||||||
from prowler.lib.check.models import Check, Check_Report_AWS | ||||||
from prowler.providers.aws.services.elasticache.elasticache_client import ( | ||||||
elasticache_client, | ||||||
) | ||||||
|
||||||
|
||||||
class elasticache_redis_cluster_automatic_failover_enabled(Check): | ||||||
def execute(self): | ||||||
findings = [] | ||||||
for repl_group in elasticache_client.replication_groups.values(): | ||||||
report = Check_Report_AWS(self.metadata()) | ||||||
report.region = repl_group.region | ||||||
report.resource_id = repl_group.id | ||||||
report.resource_arn = repl_group.arn | ||||||
report.resource_tags = repl_group.tags | ||||||
report.status = "FAIL" | ||||||
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} does not have automatic failover enabled." | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
if repl_group.automatic_failover == "enabled": | ||||||
report.status = "PASS" | ||||||
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} does have automatic failover enabled." | ||||||
|
||||||
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
143 changes: 143 additions & 0 deletions
143
...r_automatic_failover_enabled/elasticache_redis_cluster_automatic_failover_enabled_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,143 @@ | ||
from unittest import mock | ||
|
||
from mock import MagicMock | ||
|
||
from prowler.providers.aws.services.elasticache.elasticache_service import ( | ||
ReplicationGroup, | ||
) | ||
from tests.providers.aws.services.elasticache.elasticache_service_test import ( | ||
AUTO_MINOR_VERSION_UPGRADE, | ||
AUTOMATIC_FAILOVER, | ||
REPLICATION_GROUP_ARN, | ||
REPLICATION_GROUP_ENCRYPTION, | ||
REPLICATION_GROUP_ID, | ||
REPLICATION_GROUP_MULTI_AZ, | ||
REPLICATION_GROUP_SNAPSHOT_RETENTION, | ||
REPLICATION_GROUP_STATUS, | ||
REPLICATION_GROUP_TAGS, | ||
) | ||
from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider | ||
|
||
VPC_ID = "vpc-12345678901234567" | ||
|
||
|
||
class Test_elasticache_redis_cluster_automatic_failover_enabled: | ||
def test_elasticache_no_clusters(self): | ||
# Mock VPC Service | ||
vpc_client = MagicMock | ||
vpc_client.vpc_subnets = {} | ||
|
||
# Mock ElastiCache Service | ||
elasticache_service = MagicMock | ||
elasticache_service.replication_groups = {} | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=set_mocked_aws_provider([AWS_REGION_US_EAST_1]), | ||
), mock.patch( | ||
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache", | ||
new=elasticache_service, | ||
), mock.patch( | ||
"prowler.providers.aws.services.vpc.vpc_service.VPC", | ||
new=vpc_client, | ||
), mock.patch( | ||
"prowler.providers.aws.services.vpc.vpc_client.vpc_client", | ||
new=vpc_client, | ||
): | ||
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_automatic_failover_enabled.elasticache_redis_cluster_automatic_failover_enabled import ( | ||
elasticache_redis_cluster_automatic_failover_enabled, | ||
) | ||
|
||
check = elasticache_redis_cluster_automatic_failover_enabled() | ||
result = check.execute() | ||
assert len(result) == 0 | ||
|
||
def test_elasticache_clusters_automatic_failover_disabled(self): | ||
# Mock ElastiCache Service | ||
elasticache_service = MagicMock | ||
elasticache_service.replication_groups = {} | ||
|
||
elasticache_service.replication_groups[REPLICATION_GROUP_ARN] = ( | ||
ReplicationGroup( | ||
arn=REPLICATION_GROUP_ARN, | ||
id=REPLICATION_GROUP_ID, | ||
region=AWS_REGION_US_EAST_1, | ||
status=REPLICATION_GROUP_STATUS, | ||
snapshot_retention=REPLICATION_GROUP_SNAPSHOT_RETENTION, | ||
encrypted=REPLICATION_GROUP_ENCRYPTION, | ||
transit_encryption=False, | ||
multi_az=REPLICATION_GROUP_MULTI_AZ, | ||
tags=REPLICATION_GROUP_TAGS, | ||
auto_minor_version_upgrade=not AUTO_MINOR_VERSION_UPGRADE, | ||
automatic_failover="disabled", | ||
) | ||
) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=set_mocked_aws_provider([AWS_REGION_US_EAST_1]), | ||
), mock.patch( | ||
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache", | ||
new=elasticache_service, | ||
): | ||
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_automatic_failover_enabled.elasticache_redis_cluster_automatic_failover_enabled import ( | ||
elasticache_redis_cluster_automatic_failover_enabled, | ||
) | ||
|
||
check = elasticache_redis_cluster_automatic_failover_enabled() | ||
result = check.execute() | ||
assert len(result) == 1 | ||
assert result[0].status == "FAIL" | ||
assert ( | ||
result[0].status_extended | ||
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} does not have automatic failover enabled." | ||
) | ||
assert result[0].region == AWS_REGION_US_EAST_1 | ||
assert result[0].resource_id == REPLICATION_GROUP_ID | ||
assert result[0].resource_arn == REPLICATION_GROUP_ARN | ||
assert result[0].resource_tags == REPLICATION_GROUP_TAGS | ||
|
||
def test_elasticache_clusters_automatic_failover_enabled(self): | ||
# Mock ElastiCache Service | ||
elasticache_service = MagicMock | ||
elasticache_service.replication_groups = {} | ||
|
||
elasticache_service.replication_groups[REPLICATION_GROUP_ARN] = ( | ||
ReplicationGroup( | ||
arn=REPLICATION_GROUP_ARN, | ||
id=REPLICATION_GROUP_ID, | ||
region=AWS_REGION_US_EAST_1, | ||
status=REPLICATION_GROUP_STATUS, | ||
snapshot_retention=REPLICATION_GROUP_SNAPSHOT_RETENTION, | ||
encrypted=REPLICATION_GROUP_ENCRYPTION, | ||
transit_encryption=False, | ||
multi_az=REPLICATION_GROUP_MULTI_AZ, | ||
tags=REPLICATION_GROUP_TAGS, | ||
auto_minor_version_upgrade=AUTO_MINOR_VERSION_UPGRADE, | ||
automatic_failover=AUTOMATIC_FAILOVER, | ||
) | ||
) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=set_mocked_aws_provider([AWS_REGION_US_EAST_1]), | ||
), mock.patch( | ||
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache", | ||
new=elasticache_service, | ||
): | ||
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_automatic_failover_enabled.elasticache_redis_cluster_automatic_failover_enabled import ( | ||
elasticache_redis_cluster_automatic_failover_enabled, | ||
) | ||
|
||
check = elasticache_redis_cluster_automatic_failover_enabled() | ||
result = check.execute() | ||
assert len(result) == 1 | ||
assert result[0].status == "PASS" | ||
assert ( | ||
result[0].status_extended | ||
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} does have automatic failover enabled." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change this according to new changes in the checks |
||
) | ||
assert result[0].region == AWS_REGION_US_EAST_1 | ||
assert result[0].resource_id == REPLICATION_GROUP_ID | ||
assert result[0].resource_arn == REPLICATION_GROUP_ARN | ||
assert result[0].resource_tags == REPLICATION_GROUP_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
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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should now something more like:
elasticache_replication_group_redis_has_automatic_failover