From 032feb343f9accfff688bf36e3ff553b7c1ad62a Mon Sep 17 00:00:00 2001
From: Sergio Garcia <38561120+sergargar@users.noreply.github.com>
Date: Thu, 2 Mar 2023 10:59:49 +0100
Subject: [PATCH] feat(tags): add resource tags in A services (#1997)
---
prowler/lib/outputs/html.py | 2 +
prowler/lib/outputs/models.py | 6 +-
.../accessanalyzer_enabled.py | 2 +
...accessanalyzer_enabled_without_findings.py | 3 +
.../accessanalyzer/accessanalyzer_service.py | 7 +-
.../acm_certificates_expiration_check.py | 2 +
..._certificates_transparency_logs_enabled.py | 3 +
.../providers/aws/services/acm/acm_service.py | 16 +++++
.../apigateway_authorizers_enabled.py | 1 +
.../apigateway_client_certificate_enabled.py | 1 +
.../apigateway_endpoint_public.py | 1 +
.../apigateway_logging_enabled.py | 1 +
.../services/apigateway/apigateway_service.py | 69 ++++++-------------
.../apigateway_waf_acl_attached.py | 1 +
.../apigatewayv2_access_logging_enabled.py | 2 +
.../apigatewayv2_authorizers_enabled.py | 2 +
.../apigatewayv2/apigatewayv2_service.py | 48 +++++--------
..._fleet_default_internet_access_disabled.py | 1 +
...ppstream_fleet_maximum_session_duration.py | 1 +
...stream_fleet_session_disconnect_timeout.py | 1 +
...m_fleet_session_idle_disconnect_timeout.py | 1 +
.../services/appstream/appstream_service.py | 16 +++++
.../autoscaling/autoscaling_service.py | 32 +++------
...i_operations_cloudtrail_logging_enabled.py | 1 +
.../awslambda_function_no_secrets_in_code.py | 1 +
...lambda_function_no_secrets_in_variables.py | 1 +
...lambda_function_not_publicly_accessible.py | 1 +
.../awslambda_function_url_cors_policy.py | 1 +
.../awslambda_function_url_public.py | 1 +
...ambda_function_using_supported_runtimes.py | 1 +
.../services/awslambda/awslambda_service.py | 14 ++++
.../accessanalyzer_enabled_test.py | 8 +--
...sanalyzer_enabled_without_findings_test.py | 10 +--
.../accessanalyzer_service_test.py | 4 +-
.../aws/services/acm/acm_service_test.py | 26 +++++++
...gateway_client_certificate_enabled_test.py | 5 +-
.../apigateway/apigateway_service_test.py | 5 +-
.../apigatewayv2/apigatewayv2_service_test.py | 5 +-
.../appstream/appstream_service_test.py | 12 ++++
.../awslambda/awslambda_service_test.py | 3 +
40 files changed, 195 insertions(+), 123 deletions(-)
diff --git a/prowler/lib/outputs/html.py b/prowler/lib/outputs/html.py
index d6680861..8299c0fb 100644
--- a/prowler/lib/outputs/html.py
+++ b/prowler/lib/outputs/html.py
@@ -187,6 +187,7 @@ def add_html_header(file_descriptor, audit_info):
Region |
Check Title |
Resource ID |
+ Resource Tags |
Check Description |
Check ID |
Status Extended |
@@ -221,6 +222,7 @@ def fill_html(file_descriptor, finding):
{finding.region} |
{finding.check_metadata.CheckTitle} |
{finding.resource_id.replace("<", "<").replace(">", ">").replace("_", "_")} |
+ {str(finding.resource_tags)} |
{finding.check_metadata.Description} |
{finding.check_metadata.CheckID.replace("_", "_")} |
{finding.status_extended.replace("<", "<").replace(">", ">").replace("_", "_")} |
diff --git a/prowler/lib/outputs/models.py b/prowler/lib/outputs/models.py
index f923746e..11db8c53 100644
--- a/prowler/lib/outputs/models.py
+++ b/prowler/lib/outputs/models.py
@@ -162,7 +162,7 @@ class Check_Output_CSV(BaseModel):
severity: str
resource_type: str
resource_details: str
- resource_tags: list
+ resource_tags: Optional[list]
description: str
risk: str
related_url: str
@@ -235,6 +235,7 @@ def generate_provider_output_json(provider: str, finding, audit_info, mode: str,
finding_output.Region = finding.region
finding_output.ResourceId = finding.resource_id
finding_output.ResourceArn = finding.resource_arn
+ finding_output.ResourceTags = finding.resource_tags
finding_output.FindingUniqueId = f"prowler-{provider}-{finding.check_metadata.CheckID}-{audit_info.audited_account}-{finding.region}-{finding.resource_id}"
if audit_info.organizations_metadata:
@@ -292,6 +293,7 @@ class Aws_Check_Output_JSON(Check_Output_JSON):
Region: str = ""
ResourceId: str = ""
ResourceArn: str = ""
+ ResourceTags: list = []
def __init__(self, **metadata):
super().__init__(**metadata)
@@ -299,7 +301,7 @@ class Aws_Check_Output_JSON(Check_Output_JSON):
class Azure_Check_Output_JSON(Check_Output_JSON):
"""
- Aws_Check_Output_JSON generates a finding's output in JSON format for the AWS provider.
+ Azure_Check_Output_JSON generates a finding's output in JSON format for the AWS provider.
"""
Tenant_Domain: str = ""
diff --git a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py
index 62c605fc..153a2d9b 100644
--- a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py
+++ b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py
@@ -17,6 +17,7 @@ class accessanalyzer_enabled(Check):
)
report.resource_id = analyzer.name
report.resource_arn = analyzer.arn
+ report.resource_tags = analyzer.tags
elif analyzer.status == "NOT_AVAILABLE":
report.status = "FAIL"
@@ -31,6 +32,7 @@ class accessanalyzer_enabled(Check):
)
report.resource_id = analyzer.name
report.resource_arn = analyzer.arn
+ report.resource_tags = analyzer.tags
findings.append(report)
return findings
diff --git a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py
index eedadc55..af4de939 100644
--- a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py
+++ b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py
@@ -17,6 +17,7 @@ class accessanalyzer_enabled_without_findings(Check):
)
report.resource_id = analyzer.name
report.resource_arn = analyzer.arn
+ report.resource_tags = analyzer.tags
if len(analyzer.findings) != 0:
active_finding_counter = 0
for finding in analyzer.findings:
@@ -28,6 +29,7 @@ class accessanalyzer_enabled_without_findings(Check):
report.status_extended = f"IAM Access Analyzer {analyzer.name} has {active_finding_counter} active findings"
report.resource_id = analyzer.name
report.resource_arn = analyzer.arn
+ report.resource_tags = analyzer.tags
elif analyzer.status == "NOT_AVAILABLE":
report.status = "FAIL"
report.status_extended = (
@@ -41,6 +43,7 @@ class accessanalyzer_enabled_without_findings(Check):
)
report.resource_id = analyzer.name
report.resource_arn = analyzer.arn
+ report.resource_tags = analyzer.tags
findings.append(report)
return findings
diff --git a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_service.py b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_service.py
index 9c98e304..dfe75d4c 100644
--- a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_service.py
+++ b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_service.py
@@ -1,4 +1,5 @@
import threading
+from typing import Optional
from pydantic import BaseModel
@@ -48,7 +49,7 @@ class AccessAnalyzer:
arn=analyzer["arn"],
name=analyzer["name"],
status=analyzer["status"],
- tags=str(analyzer["tags"]),
+ tags=[analyzer.get("tags")],
type=analyzer["type"],
region=regional_client.region,
)
@@ -60,7 +61,7 @@ class AccessAnalyzer:
arn="",
name=self.audited_account,
status="NOT_AVAILABLE",
- tags="",
+ tags=[],
type="",
region=regional_client.region,
)
@@ -119,6 +120,6 @@ class Analyzer(BaseModel):
name: str
status: str
findings: list[Finding] = []
- tags: str
+ tags: Optional[list] = []
type: str
region: str
diff --git a/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.py b/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.py
index 6e73b173..97acecb2 100644
--- a/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.py
+++ b/prowler/providers/aws/services/acm/acm_certificates_expiration_check/acm_certificates_expiration_check.py
@@ -15,11 +15,13 @@ class acm_certificates_expiration_check(Check):
report.status_extended = f"ACM Certificate for {certificate.name} expires in {certificate.expiration_days} days."
report.resource_id = certificate.name
report.resource_arn = certificate.arn
+ report.resource_tags = certificate.tags
else:
report.status = "FAIL"
report.status_extended = f"ACM Certificate for {certificate.name} is about to expire in {DAYS_TO_EXPIRE_THRESHOLD} days."
report.resource_id = certificate.name
report.resource_arn = certificate.arn
+ report.resource_tags = certificate.tags
findings.append(report)
return findings
diff --git a/prowler/providers/aws/services/acm/acm_certificates_transparency_logs_enabled/acm_certificates_transparency_logs_enabled.py b/prowler/providers/aws/services/acm/acm_certificates_transparency_logs_enabled/acm_certificates_transparency_logs_enabled.py
index c0680639..69c0a13a 100644
--- a/prowler/providers/aws/services/acm/acm_certificates_transparency_logs_enabled/acm_certificates_transparency_logs_enabled.py
+++ b/prowler/providers/aws/services/acm/acm_certificates_transparency_logs_enabled/acm_certificates_transparency_logs_enabled.py
@@ -15,16 +15,19 @@ class acm_certificates_transparency_logs_enabled(Check):
)
report.resource_id = certificate.name
report.resource_arn = certificate.arn
+ report.resource_tags = certificate.tags
else:
if not certificate.transparency_logging:
report.status = "FAIL"
report.status_extended = f"ACM Certificate for {certificate.name} has Certificate Transparency logging disabled."
report.resource_id = certificate.name
report.resource_arn = certificate.arn
+ report.resource_tags = certificate.tags
else:
report.status = "PASS"
report.status_extended = f"ACM Certificate for {certificate.name} has Certificate Transparency logging enabled."
report.resource_id = certificate.name
report.resource_arn = certificate.arn
+ report.resource_tags = certificate.tags
findings.append(report)
return findings
diff --git a/prowler/providers/aws/services/acm/acm_service.py b/prowler/providers/aws/services/acm/acm_service.py
index 1fcf2dbd..71763db9 100644
--- a/prowler/providers/aws/services/acm/acm_service.py
+++ b/prowler/providers/aws/services/acm/acm_service.py
@@ -20,6 +20,7 @@ class ACM:
self.certificates = []
self.__threading_call__(self.__list_certificates__)
self.__describe_certificates__()
+ self.__list_tags_for_certificate__()
def __get_session__(self):
return self.session
@@ -91,11 +92,26 @@ class ACM:
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
+ def __list_tags_for_certificate__(self):
+ logger.info("ACM - List Tags...")
+ try:
+ for certificate in self.certificates:
+ regional_client = self.regional_clients[certificate.region]
+ response = regional_client.list_tags_for_certificate(
+ CertificateArn=certificate.arn
+ )["Tags"]
+ certificate.tags = response
+ except Exception as error:
+ logger.error(
+ f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+ )
+
class Certificate(BaseModel):
arn: str
name: str
type: str
+ tags: Optional[list] = []
expiration_days: int
transparency_logging: Optional[bool]
region: str
diff --git a/prowler/providers/aws/services/apigateway/apigateway_authorizers_enabled/apigateway_authorizers_enabled.py b/prowler/providers/aws/services/apigateway/apigateway_authorizers_enabled/apigateway_authorizers_enabled.py
index cf39a792..828ef242 100644
--- a/prowler/providers/aws/services/apigateway/apigateway_authorizers_enabled/apigateway_authorizers_enabled.py
+++ b/prowler/providers/aws/services/apigateway/apigateway_authorizers_enabled/apigateway_authorizers_enabled.py
@@ -12,6 +12,7 @@ class apigateway_authorizers_enabled(Check):
report.region = rest_api.region
report.resource_id = rest_api.name
report.resource_arn = rest_api.arn
+ report.resource_tags = rest_api.tags
if rest_api.authorizer:
report.status = "PASS"
report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} has authorizer configured."
diff --git a/prowler/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled.py b/prowler/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled.py
index 391ede9d..4f38eccb 100644
--- a/prowler/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled.py
+++ b/prowler/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled.py
@@ -13,6 +13,7 @@ class apigateway_client_certificate_enabled(Check):
report.resource_id = rest_api.name
report.region = rest_api.region
report.resource_arn = stage.arn
+ report.resource_tags = stage.tags
if stage.client_certificate:
report.status = "PASS"
report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} in stage {stage.name} has client certificate enabled."
diff --git a/prowler/providers/aws/services/apigateway/apigateway_endpoint_public/apigateway_endpoint_public.py b/prowler/providers/aws/services/apigateway/apigateway_endpoint_public/apigateway_endpoint_public.py
index dd48255b..51fded5a 100644
--- a/prowler/providers/aws/services/apigateway/apigateway_endpoint_public/apigateway_endpoint_public.py
+++ b/prowler/providers/aws/services/apigateway/apigateway_endpoint_public/apigateway_endpoint_public.py
@@ -12,6 +12,7 @@ class apigateway_endpoint_public(Check):
report.region = rest_api.region
report.resource_id = rest_api.name
report.resource_arn = rest_api.arn
+ report.resource_tags = rest_api.tags
if rest_api.public_endpoint:
report.status = "FAIL"
report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} is internet accesible."
diff --git a/prowler/providers/aws/services/apigateway/apigateway_logging_enabled/apigateway_logging_enabled.py b/prowler/providers/aws/services/apigateway/apigateway_logging_enabled/apigateway_logging_enabled.py
index e4e84c92..d5e86aa9 100644
--- a/prowler/providers/aws/services/apigateway/apigateway_logging_enabled/apigateway_logging_enabled.py
+++ b/prowler/providers/aws/services/apigateway/apigateway_logging_enabled/apigateway_logging_enabled.py
@@ -13,6 +13,7 @@ class apigateway_logging_enabled(Check):
report.region = rest_api.region
report.resource_id = rest_api.name
report.resource_arn = stage.arn
+ report.resource_tags = stage.tags
if stage.logging:
report.status = "PASS"
report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} in stage {stage.name} has logging enabled."
diff --git a/prowler/providers/aws/services/apigateway/apigateway_service.py b/prowler/providers/aws/services/apigateway/apigateway_service.py
index 958fa479..cbc46dba 100644
--- a/prowler/providers/aws/services/apigateway/apigateway_service.py
+++ b/prowler/providers/aws/services/apigateway/apigateway_service.py
@@ -1,5 +1,7 @@
import threading
-from dataclasses import dataclass
+from typing import Optional
+
+from pydantic import BaseModel
from prowler.lib.logger import logger
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
@@ -45,10 +47,11 @@ class APIGateway:
):
self.rest_apis.append(
RestAPI(
- apigw["id"],
- arn,
- regional_client.region,
- apigw["name"],
+ id=apigw["id"],
+ arn=arn,
+ region=regional_client.region,
+ name=apigw["name"],
+ tags=[apigw.get("tags")],
)
)
except Exception as error:
@@ -100,61 +103,33 @@ class APIGateway:
arn = f"arn:{self.audited_partition}:apigateway:{regional_client.region}::/apis/{rest_api.id}/stages/{stage['stageName']}"
rest_api.stages.append(
Stage(
- stage["stageName"],
- arn,
- logging,
- client_certificate,
- waf,
+ name=stage["stageName"],
+ arn=arn,
+ logging=logging,
+ client_certificate=client_certificate,
+ waf=waf,
+ tags=[stage.get("tags")],
)
)
except Exception as error:
logger.error(f"{error.__class__.__name__}: {error}")
-@dataclass
-class Stage:
+class Stage(BaseModel):
name: str
arn: str
logging: bool
client_certificate: bool
- waf: str
-
- def __init__(
- self,
- name,
- arn,
- logging,
- client_certificate,
- waf,
- ):
- self.name = name
- self.arn = arn
- self.logging = logging
- self.client_certificate = client_certificate
- self.waf = waf
+ waf: Optional[str]
+ tags: Optional[list] = []
-@dataclass
-class RestAPI:
+class RestAPI(BaseModel):
id: str
arn: str
region: str
name: str
- authorizer: bool
- public_endpoint: bool
- stages: list[Stage]
-
- def __init__(
- self,
- id,
- arn,
- region,
- name,
- ):
- self.id = id
- self.arn = arn
- self.region = region
- self.name = name
- self.authorizer = False
- self.public_endpoint = True
- self.stages = []
+ authorizer: bool = False
+ public_endpoint: bool = True
+ stages: list[Stage] = []
+ tags: Optional[list] = []
diff --git a/prowler/providers/aws/services/apigateway/apigateway_waf_acl_attached/apigateway_waf_acl_attached.py b/prowler/providers/aws/services/apigateway/apigateway_waf_acl_attached/apigateway_waf_acl_attached.py
index 68cc887d..aa18e0ce 100644
--- a/prowler/providers/aws/services/apigateway/apigateway_waf_acl_attached/apigateway_waf_acl_attached.py
+++ b/prowler/providers/aws/services/apigateway/apigateway_waf_acl_attached/apigateway_waf_acl_attached.py
@@ -13,6 +13,7 @@ class apigateway_waf_acl_attached(Check):
report.region = rest_api.region
report.resource_id = rest_api.name
report.resource_arn = stage.arn
+ report.resource_tags = stage.tags
if stage.waf:
report.status = "PASS"
report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} in stage {stage.name} has {stage.waf} WAF ACL attached."
diff --git a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_access_logging_enabled/apigatewayv2_access_logging_enabled.py b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_access_logging_enabled/apigatewayv2_access_logging_enabled.py
index b3f1e994..8f7b8eee 100644
--- a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_access_logging_enabled/apigatewayv2_access_logging_enabled.py
+++ b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_access_logging_enabled/apigatewayv2_access_logging_enabled.py
@@ -15,10 +15,12 @@ class apigatewayv2_access_logging_enabled(Check):
report.status = "PASS"
report.status_extended = f"API Gateway V2 {api.name} ID {api.id} in stage {stage.name} has access logging enabled."
report.resource_id = api.name
+ report.resource_tags = api.tags
else:
report.status = "FAIL"
report.status_extended = f"API Gateway V2 {api.name} ID {api.id} in stage {stage.name} has access logging disabled."
report.resource_id = api.name
+ report.resource_tags = api.tags
findings.append(report)
return findings
diff --git a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_authorizers_enabled/apigatewayv2_authorizers_enabled.py b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_authorizers_enabled/apigatewayv2_authorizers_enabled.py
index a582a94b..25f3df16 100644
--- a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_authorizers_enabled/apigatewayv2_authorizers_enabled.py
+++ b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_authorizers_enabled/apigatewayv2_authorizers_enabled.py
@@ -16,10 +16,12 @@ class apigatewayv2_authorizers_enabled(Check):
f"API Gateway V2 {api.name} ID {api.id} has authorizer configured."
)
report.resource_id = api.name
+ report.resource_tags = api.tags
else:
report.status = "FAIL"
report.status_extended = f"API Gateway V2 {api.name} ID {api.id} has not authorizer configured."
report.resource_id = api.name
+ report.resource_tags = api.tags
findings.append(report)
return findings
diff --git a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_service.py b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_service.py
index e01f862a..fe234720 100644
--- a/prowler/providers/aws/services/apigatewayv2/apigatewayv2_service.py
+++ b/prowler/providers/aws/services/apigatewayv2/apigatewayv2_service.py
@@ -1,5 +1,7 @@
import threading
-from dataclasses import dataclass
+from typing import Optional
+
+from pydantic import BaseModel
from prowler.lib.logger import logger
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
@@ -42,9 +44,10 @@ class ApiGatewayV2:
):
self.apis.append(
API(
- apigw["ApiId"],
- regional_client.region,
- apigw["Name"],
+ id=apigw["ApiId"],
+ region=regional_client.region,
+ name=apigw["Name"],
+ tags=[apigw.get("Tags")],
)
)
except Exception as error:
@@ -77,8 +80,9 @@ class ApiGatewayV2:
logging = True
api.stages.append(
Stage(
- stage["StageName"],
- logging,
+ name=stage["StageName"],
+ logging=logging,
+ tags=[stage.get("Tags")],
)
)
except Exception as error:
@@ -87,36 +91,16 @@ class ApiGatewayV2:
)
-@dataclass
-class Stage:
+class Stage(BaseModel):
name: str
logging: bool
-
- def __init__(
- self,
- name,
- logging,
- ):
- self.name = name
- self.logging = logging
+ tags: Optional[list] = []
-@dataclass
-class API:
+class API(BaseModel):
id: str
region: str
name: str
- authorizer: bool
- stages: list[Stage]
-
- def __init__(
- self,
- id,
- region,
- name,
- ):
- self.id = id
- self.region = region
- self.name = name
- self.authorizer = False
- self.stages = []
+ authorizer: bool = False
+ stages: list[Stage] = []
+ tags: Optional[list] = []
diff --git a/prowler/providers/aws/services/appstream/appstream_fleet_default_internet_access_disabled/appstream_fleet_default_internet_access_disabled.py b/prowler/providers/aws/services/appstream/appstream_fleet_default_internet_access_disabled/appstream_fleet_default_internet_access_disabled.py
index d3a87002..9512376c 100644
--- a/prowler/providers/aws/services/appstream/appstream_fleet_default_internet_access_disabled/appstream_fleet_default_internet_access_disabled.py
+++ b/prowler/providers/aws/services/appstream/appstream_fleet_default_internet_access_disabled/appstream_fleet_default_internet_access_disabled.py
@@ -14,6 +14,7 @@ class appstream_fleet_default_internet_access_disabled(Check):
report.region = fleet.region
report.resource_id = fleet.name
report.resource_arn = fleet.arn
+ report.resource_tags = fleet.tags
if fleet.enable_default_internet_access:
report.status = "FAIL"
diff --git a/prowler/providers/aws/services/appstream/appstream_fleet_maximum_session_duration/appstream_fleet_maximum_session_duration.py b/prowler/providers/aws/services/appstream/appstream_fleet_maximum_session_duration/appstream_fleet_maximum_session_duration.py
index c42d9777..49bfa96b 100644
--- a/prowler/providers/aws/services/appstream/appstream_fleet_maximum_session_duration/appstream_fleet_maximum_session_duration.py
+++ b/prowler/providers/aws/services/appstream/appstream_fleet_maximum_session_duration/appstream_fleet_maximum_session_duration.py
@@ -17,6 +17,7 @@ class appstream_fleet_maximum_session_duration(Check):
report.region = fleet.region
report.resource_id = fleet.name
report.resource_arn = fleet.arn
+ report.resource_tags = fleet.tags
if fleet.max_user_duration_in_seconds < max_session_duration_seconds:
report.status = "PASS"
diff --git a/prowler/providers/aws/services/appstream/appstream_fleet_session_disconnect_timeout/appstream_fleet_session_disconnect_timeout.py b/prowler/providers/aws/services/appstream/appstream_fleet_session_disconnect_timeout/appstream_fleet_session_disconnect_timeout.py
index acae445c..fa0ff5e6 100644
--- a/prowler/providers/aws/services/appstream/appstream_fleet_session_disconnect_timeout/appstream_fleet_session_disconnect_timeout.py
+++ b/prowler/providers/aws/services/appstream/appstream_fleet_session_disconnect_timeout/appstream_fleet_session_disconnect_timeout.py
@@ -17,6 +17,7 @@ class appstream_fleet_session_disconnect_timeout(Check):
report.region = fleet.region
report.resource_id = fleet.name
report.resource_arn = fleet.arn
+ report.resource_tags = fleet.tags
if fleet.disconnect_timeout_in_seconds <= max_disconnect_timeout_in_seconds:
report.status = "PASS"
diff --git a/prowler/providers/aws/services/appstream/appstream_fleet_session_idle_disconnect_timeout/appstream_fleet_session_idle_disconnect_timeout.py b/prowler/providers/aws/services/appstream/appstream_fleet_session_idle_disconnect_timeout/appstream_fleet_session_idle_disconnect_timeout.py
index c1efd150..71e6bef1 100644
--- a/prowler/providers/aws/services/appstream/appstream_fleet_session_idle_disconnect_timeout/appstream_fleet_session_idle_disconnect_timeout.py
+++ b/prowler/providers/aws/services/appstream/appstream_fleet_session_idle_disconnect_timeout/appstream_fleet_session_idle_disconnect_timeout.py
@@ -19,6 +19,7 @@ class appstream_fleet_session_idle_disconnect_timeout(Check):
report.region = fleet.region
report.resource_id = fleet.name
report.resource_arn = fleet.arn
+ report.resource_tags = fleet.tags
if (
fleet.idle_disconnect_timeout_in_seconds
diff --git a/prowler/providers/aws/services/appstream/appstream_service.py b/prowler/providers/aws/services/appstream/appstream_service.py
index 8ceafddd..492f836a 100644
--- a/prowler/providers/aws/services/appstream/appstream_service.py
+++ b/prowler/providers/aws/services/appstream/appstream_service.py
@@ -18,6 +18,7 @@ class AppStream:
self.regional_clients = generate_regional_clients(self.service, audit_info)
self.fleets = []
self.__threading_call__(self.__describe_fleets__)
+ self.__list_tags_for_resource__()
def __get_session__(self):
return self.session
@@ -65,6 +66,20 @@ class AppStream:
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
+ def __list_tags_for_resource__(self):
+ logger.info("AppStream - List Tags...")
+ try:
+ for fleet in self.fleets:
+ regional_client = self.regional_clients[fleet.region]
+ response = regional_client.list_tags_for_resource(
+ ResourceArn=fleet.arn
+ )["Tags"]
+ fleet.tags = [response]
+ except Exception as error:
+ logger.error(
+ f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+ )
+
class Fleet(BaseModel):
arn: str
@@ -74,3 +89,4 @@ class Fleet(BaseModel):
idle_disconnect_timeout_in_seconds: Optional[int]
enable_default_internet_access: bool
region: str
+ tags: Optional[list] = []
diff --git a/prowler/providers/aws/services/autoscaling/autoscaling_service.py b/prowler/providers/aws/services/autoscaling/autoscaling_service.py
index f602fd17..51ebdfb5 100644
--- a/prowler/providers/aws/services/autoscaling/autoscaling_service.py
+++ b/prowler/providers/aws/services/autoscaling/autoscaling_service.py
@@ -1,5 +1,6 @@
import threading
-from dataclasses import dataclass
+
+from pydantic import BaseModel
from prowler.lib.logger import logger
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
@@ -45,11 +46,11 @@ class AutoScaling:
):
self.launch_configurations.append(
LaunchConfiguration(
- configuration["LaunchConfigurationARN"],
- configuration["LaunchConfigurationName"],
- configuration["UserData"],
- configuration["ImageId"],
- regional_client.region,
+ arn=configuration["LaunchConfigurationARN"],
+ name=configuration["LaunchConfigurationName"],
+ user_data=configuration["UserData"],
+ image_id=configuration["ImageId"],
+ region=regional_client.region,
)
)
@@ -59,24 +60,9 @@ class AutoScaling:
)
-@dataclass
-class LaunchConfiguration:
+class LaunchConfiguration(BaseModel):
arn: str
name: str
user_data: str
- image_id: int
+ image_id: str
region: str
-
- def __init__(
- self,
- arn,
- name,
- user_data,
- image_id,
- region,
- ):
- self.arn = arn
- self.name = name
- self.image_id = image_id
- self.user_data = user_data
- self.region = region
diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.py b/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.py
index c6524312..15d91ea6 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled/awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.py
@@ -13,6 +13,7 @@ class awslambda_function_invoke_api_operations_cloudtrail_logging_enabled(Check)
report.region = function.region
report.resource_id = function.name
report.resource_arn = function.arn
+ report.resource_tags = function.tags
report.status = "FAIL"
report.status_extended = (
diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py
index 3d743853..aa218486 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py
@@ -17,6 +17,7 @@ class awslambda_function_no_secrets_in_code(Check):
report.region = function.region
report.resource_id = function.name
report.resource_arn = function.arn
+ report.resource_tags = function.tags
report.status = "PASS"
report.status_extended = (
diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py
index 0bad2a4e..f2dee4e2 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py
@@ -17,6 +17,7 @@ class awslambda_function_no_secrets_in_variables(Check):
report.region = function.region
report.resource_id = function.name
report.resource_arn = function.arn
+ report.resource_tags = function.tags
report.status = "PASS"
report.status_extended = (
diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_not_publicly_accessible/awslambda_function_not_publicly_accessible.py b/prowler/providers/aws/services/awslambda/awslambda_function_not_publicly_accessible/awslambda_function_not_publicly_accessible.py
index 8efc74b2..445b6519 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_function_not_publicly_accessible/awslambda_function_not_publicly_accessible.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_function_not_publicly_accessible/awslambda_function_not_publicly_accessible.py
@@ -10,6 +10,7 @@ class awslambda_function_not_publicly_accessible(Check):
report.region = function.region
report.resource_id = function.name
report.resource_arn = function.arn
+ report.resource_tags = function.tags
report.status = "PASS"
report.status_extended = f"Lambda function {function.name} has a policy resource-based policy not public"
diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_url_cors_policy/awslambda_function_url_cors_policy.py b/prowler/providers/aws/services/awslambda/awslambda_function_url_cors_policy/awslambda_function_url_cors_policy.py
index c5755b4a..76bd1c5f 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_function_url_cors_policy/awslambda_function_url_cors_policy.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_function_url_cors_policy/awslambda_function_url_cors_policy.py
@@ -10,6 +10,7 @@ class awslambda_function_url_cors_policy(Check):
report.region = function.region
report.resource_id = function.name
report.resource_arn = function.arn
+ report.resource_tags = function.tags
if function.url_config:
if "*" in function.url_config.cors_config.allow_origins:
report.status = "FAIL"
diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_url_public/awslambda_function_url_public.py b/prowler/providers/aws/services/awslambda/awslambda_function_url_public/awslambda_function_url_public.py
index 20488ff4..01543f70 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_function_url_public/awslambda_function_url_public.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_function_url_public/awslambda_function_url_public.py
@@ -11,6 +11,7 @@ class awslambda_function_url_public(Check):
report.region = function.region
report.resource_id = function.name
report.resource_arn = function.arn
+ report.resource_tags = function.tags
if function.url_config:
if function.url_config.auth_type == AuthType.AWS_IAM:
report.status = "PASS"
diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.py b/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.py
index 70e22c2a..017bddd2 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.py
@@ -12,6 +12,7 @@ class awslambda_function_using_supported_runtimes(Check):
report.region = function.region
report.resource_id = function.name
report.resource_arn = function.arn
+ report.resource_tags = function.tags
if function.runtime in get_config_var("obsolete_lambda_runtimes"):
report.status = "FAIL"
diff --git a/prowler/providers/aws/services/awslambda/awslambda_service.py b/prowler/providers/aws/services/awslambda/awslambda_service.py
index 90bbf48c..24ac8fb0 100644
--- a/prowler/providers/aws/services/awslambda/awslambda_service.py
+++ b/prowler/providers/aws/services/awslambda/awslambda_service.py
@@ -24,6 +24,7 @@ class Lambda:
self.regional_clients = generate_regional_clients(self.service, audit_info)
self.functions = {}
self.__threading_call__(self.__list_functions__)
+ self.__list_tags_for_resource__()
# We only want to retrieve the Lambda code if the
# awslambda_function_no_secrets_in_code check is set
@@ -156,6 +157,18 @@ class Lambda:
f" {error}"
)
+ def __list_tags_for_resource__(self):
+ logger.info("Lambda - List Tags...")
+ try:
+ for function in self.functions.values():
+ regional_client = self.regional_clients[function.region]
+ response = regional_client.list_tags(Resource=function.arn)["Tags"]
+ function.tags = [response]
+ except Exception as error:
+ logger.error(
+ f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+ )
+
class LambdaCode(BaseModel):
location: str
@@ -186,3 +199,4 @@ class Function(BaseModel):
policy: dict = None
code: LambdaCode = None
url_config: URLConfig = None
+ tags: Optional[list] = []
diff --git a/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_test.py b/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_test.py
index 671f16ea..f0d86286 100644
--- a/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_test.py
+++ b/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_test.py
@@ -31,7 +31,7 @@ class Test_accessanalyzer_enabled:
arn="",
name="012345678910",
status="NOT_AVAILABLE",
- tags="",
+ tags=[],
type="",
region="eu-west-1",
)
@@ -62,7 +62,7 @@ class Test_accessanalyzer_enabled:
arn="",
name="012345678910",
status="NOT_AVAILABLE",
- tags="",
+ tags=[],
type="",
region="eu-west-1",
),
@@ -70,7 +70,7 @@ class Test_accessanalyzer_enabled:
arn="",
name="Test Analyzer",
status="ACTIVE",
- tags="",
+ tags=[],
type="",
region="eu-west-2",
),
@@ -112,7 +112,7 @@ class Test_accessanalyzer_enabled:
arn="",
name="Test Analyzer",
status="ACTIVE",
- tags="",
+ tags=[],
type="",
region="eu-west-2",
)
diff --git a/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py b/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py
index 08b05816..bc3fdcbe 100644
--- a/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py
+++ b/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py
@@ -32,7 +32,7 @@ class Test_accessanalyzer_enabled_without_findings:
arn="",
name="012345678910",
status="NOT_AVAILABLE",
- tags="",
+ tags=[],
type="",
region="eu-west-1",
)
@@ -63,7 +63,7 @@ class Test_accessanalyzer_enabled_without_findings:
arn="",
name="012345678910",
status="NOT_AVAILABLE",
- tags="",
+ tags=[],
type="",
region="eu-west-1",
),
@@ -81,7 +81,7 @@ class Test_accessanalyzer_enabled_without_findings:
status="ARCHIVED",
),
],
- tags="",
+ tags=[],
type="",
region="eu-west-2",
),
@@ -123,7 +123,7 @@ class Test_accessanalyzer_enabled_without_findings:
arn="",
name="Test Analyzer",
status="ACTIVE",
- tags="",
+ tags=[],
type="",
region="eu-west-2",
)
@@ -157,7 +157,7 @@ class Test_accessanalyzer_enabled_without_findings:
arn="",
name="012345678910",
status="NOT_AVAILABLE",
- tags="",
+ tags=[],
type="",
region="eu-west-1",
),
diff --git a/tests/providers/aws/services/accessanalyzer/accessanalyzer_service_test.py b/tests/providers/aws/services/accessanalyzer/accessanalyzer_service_test.py
index 0a539851..de76b164 100644
--- a/tests/providers/aws/services/accessanalyzer/accessanalyzer_service_test.py
+++ b/tests/providers/aws/services/accessanalyzer/accessanalyzer_service_test.py
@@ -30,7 +30,7 @@ def mock_make_api_call(self, operation_name, kwarg):
"name": "Test Analyzer",
"status": "ACTIVE",
"findings": 0,
- "tags": "",
+ "tags": {"test": "test"},
"type": "ACCOUNT",
"region": "eu-west-1",
}
@@ -92,7 +92,7 @@ class Test_AccessAnalyzer_Service:
assert access_analyzer.analyzers[0].arn == "ARN"
assert access_analyzer.analyzers[0].name == "Test Analyzer"
assert access_analyzer.analyzers[0].status == "ACTIVE"
- assert access_analyzer.analyzers[0].tags == ""
+ assert access_analyzer.analyzers[0].tags == [{"test": "test"}]
assert access_analyzer.analyzers[0].type == "ACCOUNT"
assert access_analyzer.analyzers[0].region == AWS_REGION
diff --git a/tests/providers/aws/services/acm/acm_service_test.py b/tests/providers/aws/services/acm/acm_service_test.py
index dbf313ef..fbbb7191 100644
--- a/tests/providers/aws/services/acm/acm_service_test.py
+++ b/tests/providers/aws/services/acm/acm_service_test.py
@@ -67,6 +67,14 @@ def mock_make_api_call(self, operation_name, kwargs):
"Options": {"CertificateTransparencyLoggingPreference": "DISABLED"},
}
}
+ if operation_name == "ListTagsForCertificate":
+ if kwargs["CertificateArn"] == certificate_arn:
+ return {
+ "Tags": [
+ {"Key": "test", "Value": "test"},
+ ]
+ }
+
return make_api_call(self, operation_name, kwargs)
@@ -163,3 +171,21 @@ class Test_ACM_Service:
assert acm.certificates[0].expiration_days == 365
assert acm.certificates[0].transparency_logging is False
assert acm.certificates[0].region == AWS_REGION
+
+ # Test ACM List Tags
+ # @mock_acm
+ def test__list_tags_for_certificate__(self):
+ # Generate ACM Client
+ # acm_client = client("acm", region_name=AWS_REGION)
+ # Request ACM certificate
+ # certificate = acm_client.request_certificate(
+ # DomainName="test.com",
+ # )
+
+ # ACM client for this test class
+ audit_info = self.set_mocked_audit_info()
+ acm = ACM(audit_info)
+ assert len(acm.certificates) == 1
+ assert acm.certificates[0].tags == [
+ {"Key": "test", "Value": "test"},
+ ]
diff --git a/tests/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled_test.py b/tests/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled_test.py
index d373bdfc..fcf49c63 100644
--- a/tests/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled_test.py
+++ b/tests/providers/aws/services/apigateway/apigateway_client_certificate_enabled/apigateway_client_certificate_enabled_test.py
@@ -106,7 +106,6 @@ class Test_apigateway_client_certificate_enabled:
@mock_apigateway
def test_apigateway_one_stage_with_certificate(self):
-
# Create APIGateway Mocked Resources
apigateway_client = client("apigateway", region_name=AWS_REGION)
# Create APIGateway Deployment Stage
@@ -131,8 +130,8 @@ class Test_apigateway_client_certificate_enabled:
service_client.rest_apis[0].stages.append(
Stage(
- "test",
- f"arn:{current_audit_info.audited_partition}:apigateway:{AWS_REGION}::/apis/test-rest-api/stages/test",
+ name="test",
+ arn=f"arn:{current_audit_info.audited_partition}:apigateway:{AWS_REGION}::/apis/test-rest-api/stages/test",
logging=True,
client_certificate=True,
waf=True,
diff --git a/tests/providers/aws/services/apigateway/apigateway_service_test.py b/tests/providers/aws/services/apigateway/apigateway_service_test.py
index f82e3b45..cac50c53 100644
--- a/tests/providers/aws/services/apigateway/apigateway_service_test.py
+++ b/tests/providers/aws/services/apigateway/apigateway_service_test.py
@@ -108,12 +108,15 @@ class Test_APIGateway_Service:
apigateway_client = client("apigateway", region_name=AWS_REGION)
# Create private APIGateway Rest API
apigateway_client.create_rest_api(
- name="test-rest-api", endpointConfiguration={"types": ["PRIVATE"]}
+ name="test-rest-api",
+ endpointConfiguration={"types": ["PRIVATE"]},
+ tags={"test": "test"},
)
# APIGateway client for this test class
audit_info = self.set_mocked_audit_info()
apigateway = APIGateway(audit_info)
assert apigateway.rest_apis[0].public_endpoint is False
+ assert apigateway.rest_apis[0].tags == [{"test": "test"}]
# Test APIGateway Get Stages
@mock_apigateway
diff --git a/tests/providers/aws/services/apigatewayv2/apigatewayv2_service_test.py b/tests/providers/aws/services/apigatewayv2/apigatewayv2_service_test.py
index 30c5afa6..2af97715 100644
--- a/tests/providers/aws/services/apigatewayv2/apigatewayv2_service_test.py
+++ b/tests/providers/aws/services/apigatewayv2/apigatewayv2_service_test.py
@@ -102,11 +102,14 @@ class Test_ApiGatewayV2_Service:
# Generate ApiGatewayV2 Client
apigatewayv2_client = client("apigatewayv2", region_name=AWS_REGION)
# Create ApiGatewayV2 API
- apigatewayv2_client.create_api(Name="test-api", ProtocolType="HTTP")
+ apigatewayv2_client.create_api(
+ Name="test-api", ProtocolType="HTTP", Tags={"test": "test"}
+ )
# ApiGatewayV2 client for this test class
audit_info = self.set_mocked_audit_info()
apigatewayv2 = ApiGatewayV2(audit_info)
assert len(apigatewayv2.apis) == len(apigatewayv2_client.get_apis()["Items"])
+ assert apigatewayv2.apis[0].tags == [{"test": "test"}]
# Test ApiGatewayV2 Get Authorizers
@mock_apigatewayv2
diff --git a/tests/providers/aws/services/appstream/appstream_service_test.py b/tests/providers/aws/services/appstream/appstream_service_test.py
index 0d3b2508..77fd07a8 100644
--- a/tests/providers/aws/services/appstream/appstream_service_test.py
+++ b/tests/providers/aws/services/appstream/appstream_service_test.py
@@ -43,6 +43,8 @@ def mock_make_api_call(self, operation_name, kwarg):
},
]
}
+ if operation_name == "ListTagsForResource":
+ return {"Tags": {"test": "test"}}
return make_api_call(self, operation_name, kwarg)
@@ -102,3 +104,13 @@ class Test_AppStream_Service:
assert appstream.fleets[1].idle_disconnect_timeout_in_seconds == 900
assert appstream.fleets[1].enable_default_internet_access is True
assert appstream.fleets[1].region == AWS_REGION
+
+ def test__list_tags_for_resource__(self):
+ # Set partition for the service
+ current_audit_info.audited_partition = "aws"
+ appstream = AppStream(current_audit_info)
+ assert len(appstream.fleets) == 2
+
+ assert appstream.fleets[0].tags == [{"test": "test"}]
+
+ assert appstream.fleets[1].tags == [{"test": "test"}]
diff --git a/tests/providers/aws/services/awslambda/awslambda_service_test.py b/tests/providers/aws/services/awslambda/awslambda_service_test.py
index 49889d78..9a2d9f53 100644
--- a/tests/providers/aws/services/awslambda/awslambda_service_test.py
+++ b/tests/providers/aws/services/awslambda/awslambda_service_test.py
@@ -137,6 +137,7 @@ class Test_Lambda_Service:
"SubnetIds": ["subnet-123abc"],
},
Environment={"Variables": {"db-password": "test-password"}},
+ Tags={"test": "test"},
)
# Update Lambda Policy
lambda_policy = {
@@ -218,6 +219,8 @@ class Test_Lambda_Service:
lambda_name
].url_config.cors_config.allow_origins == ["*"]
+ assert awslambda.functions[lambda_name].tags == [{"test": "test"}]
+
# Pending ZipFile tests
with tempfile.TemporaryDirectory() as tmp_dir_name:
awslambda.functions[lambda_name].code.code_zip.extractall(tmp_dir_name)