diff --git a/docs/header_names/allowed_framework_names.adoc b/docs/header_names/allowed_framework_names.adoc index d91acac3d7a..2309b398ecc 100644 --- a/docs/header_names/allowed_framework_names.adoc +++ b/docs/header_names/allowed_framework_names.adoc @@ -101,11 +101,13 @@ * Mcrypt // Python * aiohttp +* aiobotocore * Amazon DynamoDB * Argon2-cffi * AnyIO * Asyncio * Bcrypt +* boto3 * Cryptodome * databases * Django diff --git a/rules/S7609/metadata.json b/rules/S7609/metadata.json new file mode 100644 index 00000000000..2c63c085104 --- /dev/null +++ b/rules/S7609/metadata.json @@ -0,0 +1,2 @@ +{ +} diff --git a/rules/S7609/python/metadata.json b/rules/S7609/python/metadata.json new file mode 100644 index 00000000000..872fa91925d --- /dev/null +++ b/rules/S7609/python/metadata.json @@ -0,0 +1,23 @@ +{ + "title": "AWS CloudWatch metrics namespace should not begin with `AWS/`", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-7609", + "sqKey": "S7609", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "RELIABILITY": "MEDIUM" + }, + "attribute": "CONVENTIONAL" + } +} diff --git a/rules/S7609/python/rule.adoc b/rules/S7609/python/rule.adoc new file mode 100644 index 00000000000..d61ed9dc92a --- /dev/null +++ b/rules/S7609/python/rule.adoc @@ -0,0 +1,125 @@ +This rule raises and issue when AWS CloudWatch `put_metric_data` namespace begins with `AWS/` + +== Why is this an issue? + +AWS CloudWatch has reserved namespaces that begin with 'AWS/' for its own internal services and metrics. These namespaces are used by AWS to publish official service metrics such as EC2 instance metrics, Lambda function metrics, S3 bucket metrics, and others. When you attempt to publish custom metrics using a namespace that begins with 'AWS/', you are essentially trying to use a reserved namespace that conflicts with AWS's own metric publishing system. + +=== What is the potential impact? + +Using AWS service namespaces can lead to metric publishing failures, data corruption, or unexpected behavior in CloudWatch dashboards. It may also cause confusion between your custom metrics and official AWS service metrics, making monitoring and troubleshooting more difficult. Additionally, AWS may reject such metric publications or they may interfere with existing service metrics. + + +== How to fix it in boto3 + +Use a custom namespace that does not begin with 'AWS/' when publishing metrics with CloudWatch. Choose a meaningful namespace that reflects your application or service name, such as 'MyApp/', 'CustomService/', or your organization name. + +=== Code examples + +==== Noncompliant code example + +[source,python,diff-id=1,diff-type=noncompliant] +---- +import boto3 + +cloudwatch = boto3.client('cloudwatch') + +# Publishing to AWS reserved namespace +cloudwatch.put_metric_data( + Namespace='AWS/MyCustomService', # Noncompliant + MetricData=[ + { + 'MetricName': 'CustomMetric', + 'Value': 123.0 + } + ] +) +---- + +==== Compliant solution + +[source,python,diff-id=1,diff-type=compliant] +---- +import boto3 + +cloudwatch = boto3.client('cloudwatch') + +# Publishing to custom namespace +cloudwatch.put_metric_data( + Namespace='MyApp/CustomService', # Compliant + MetricData=[ + { + 'MetricName': 'CustomMetric', + 'Value': 123.0 + } + ] +) +---- + +== How to fix it in aiobotocore + +When using aiobotocore for asynchronous CloudWatch operations, ensure you use a custom namespace that does not start with 'AWS/' to avoid conflicts with AWS reserved namespaces. + +=== Code examples + +==== Noncompliant code example + +[source,python,diff-id=2,diff-type=noncompliant] +---- +import aiobotocore.session + +async def publish_metrics(): + session = aiobotocore.session.get_session() + async with session.create_client('cloudwatch') as client: + await client.put_metric_data( + Namespace='AWS/Lambda/Custom', # Noncompliant + MetricData=[ + { + 'MetricName': 'ProcessingTime', + 'Value': 45.2 + } + ] + ) +---- + +==== Compliant solution + +[source,python,diff-id=2,diff-type=compliant] +---- +import aiobotocore.session + +async def publish_metrics(): + session = aiobotocore.session.get_session() + async with session.create_client('cloudwatch') as client: + await client.put_metric_data( + Namespace='MyLambda/Custom', # Compliant + MetricData=[ + { + 'MetricName': 'ProcessingTime', + 'Value': 45.2 + } + ] + ) +---- + +== Resources + +=== Documentation + +* https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricData.html[AWS CloudWatch PutMetricData API Reference] +* https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Namespace[CloudWatch Concepts - Namespaces] + + +ifdef::env-github,rspecator-view[] + +== Implementation Specification +(visible only on this page) + +=== Message + +Do not use AWS reserved namespace that begins with 'AWS/' for custom metrics. + +=== Highlighting + +* Primary location: the 'Namespace' parameter value in the put_metric_data call + +endif::env-github,rspecator-view[]