@robhan-cdk-lib/aws_aps
Higher-level AWS Cloud Development Kit (CDK) constructs for Amazon Managed Service for Prometheus.
The upstream aws-cdk-lib/aws-aps module currently contains generated L1 constructs only. This library explores an L2 API intended to feel native to the AWS Construct Library:
- references to workspaces, EKS clusters, IAM roles, KMS keys, log groups, subnets, and security groups use CDK resource-reference interfaces rather than raw identifiers;
- owned and existing resources expose minimal, stable identity interfaces and token-safe
from...Arnfactories; - scraper destinations, sources, and configuration encodings use factories that prevent invalid combinations;
- resource policies accept and validate
iam.PolicyDocument; - taggable resources support both
props.tagsandTags.of(...); - all currently available
AWS::APSCloudFormation resource types and properties are covered.
Schema constraints already expressed by CloudFormation, such as most string lengths and numeric ranges, are left to CloudFormation. Repeating them eagerly in an L2 is unsafe for unresolved CDK tokens and can drift from the service schema. A small set of concrete numeric invariants absent from that schema is checked locally; unresolved values and semantic content such as PromQL syntax remain service-validated.
This package is not supported or endorsed by AWS. Please report issues in the project repository.
Workspace and rule groups
A workspace has no required properties. Related constructs accept the generated IWorkspaceRef contract, so both this L2 and the upstream CfnWorkspace can be used.
from robhan_cdk_lib.aws_aps import WorkspaceConfiguration
from aws_cdk import Stack, StackProps
from constructs import Construct
from robhan_cdk_lib.aws_aps import RuleGroupsNamespace, Workspace
class MetricsStack(Stack):
def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)
workspace = Workspace(self, "Workspace",
alias="application-metrics",
workspace_configuration=WorkspaceConfiguration(
out_of_order_time_window_in_seconds=300,
retention_period_in_days=365,
rule_query_offset_in_seconds=60
),
tags={"environment": "production"}
)
RuleGroupsNamespace(self, "Rules",
workspace=workspace,
name="availability",
data="""groups:
- name: availability
rules:
- record: service:up:sum
expr: sum(up)
"""
)
Managed scraper
Scraper factories model the mutually exclusive destination and source variants. ScrapeConfiguration.fromString() accepts raw Prometheus YAML. The CloudFormation resource provider performs the service API blob serialization; do not base64-encode the value.
from aws_cdk import Stack, StackProps
from aws_cdk.aws_ec2 import Subnet
from aws_cdk.aws_eks import Cluster
from constructs import Construct
from robhan_cdk_lib.aws_aps import ScrapeConfiguration, Scraper, ScraperDestination, ScraperSource, Workspace
class ScraperStack(Stack):
def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)
workspace = Workspace(self, "Workspace")
cluster = Cluster.from_cluster_attributes(self, "Cluster",
cluster_name="metrics-cluster"
)
subnet = Subnet.from_subnet_id(self, "Subnet", "subnet-0123456789abcdef0")
Scraper(self, "Scraper",
destination=ScraperDestination.amp(workspace),
source=ScraperSource.eks(cluster=cluster, subnets=[subnet]),
scrape_configuration=ScrapeConfiguration.from_string("""scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
""")
)
ScraperDestination.cloudWatch() supports the account's CloudWatch dataset. ScraperSource.vpc() supports VPC-reachable Prometheus sources and must be paired with a CloudWatch destination; EKS sources can use either AMP or CloudWatch.
Scraper prerequisites
A scraper does not modify the supplied network, EKS authorization, IAM roles, or KMS policy:
- An EKS source requires private cluster endpoint access, VPC DNS, and available addresses in every selected subnet. Automatic access entries require EKS authentication mode
APIorAPI_AND_CONFIG_MAP; otherwise configure the required Kubernetes RBAC manually. See Set up managed collectors for Amazon EKS. - For cross-account collection, provide both source and target roles and configure their trust and permissions. The same explicit role configuration is required when the destination workspace uses a customer-managed KMS key, including a same-account scraper.
- For VPC sources, prefer private subnets and security-group egress limited to the intended Prometheus endpoints. The construct does not add broad network rules.
Anomaly detection
MissingDataAction and IgnoreNearExpected represent service API unions, so callers cannot accidentally request incompatible alternatives. Random Cut Forest queries must be wrapped by avg, count, group, max, min, quantile, stddev, stdvar, or sum; Amazon Managed Service for Prometheus validates the PromQL semantics.
from robhan_cdk_lib.aws_aps import AnomalyDetectorConfiguration, RandomCutForestConfiguration
from aws_cdk import Stack, StackProps
from constructs import Construct
from robhan_cdk_lib.aws_aps import AnomalyDetector, IgnoreNearExpected, MissingDataAction, Workspace
class AnomalyStack(Stack):
def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)
workspace = Workspace.from_workspace_arn(self, "Workspace", "arn:aws:aps:us-east-1:123456789012:workspace/ws-example")
AnomalyDetector(self, "Detector",
workspace=workspace,
alias="request-rate",
configuration=AnomalyDetectorConfiguration(
random_cut_forest=RandomCutForestConfiguration(
query="sum(rate(requests_total[5m]))",
ignore_near_expected_from_above=IgnoreNearExpected.ratio(0.1)
)
),
missing_data_action=MissingDataAction.SKIP
)
Resource policies
Resource policies use the IAM policy model, validate resource-policy requirements at synthesis, and render lazily so statements added after construction are included. If the workspace uses a customer-managed KMS key, every cross-account principal also needs access to that key; the resource policy alone is insufficient.
from aws_cdk import Stack, StackProps
from aws_cdk.aws_iam import AccountPrincipal, PolicyDocument, PolicyStatement
from constructs import Construct
from robhan_cdk_lib.aws_aps import ResourcePolicy, Workspace
class PolicyStack(Stack):
def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)
workspace = Workspace.from_workspace_arn(self, "Workspace", "arn:aws:aps:us-east-1:123456789012:workspace/ws-example")
ResourcePolicy(self, "ResourcePolicy",
workspace=workspace,
policy_document=PolicyDocument(
statements=[PolicyStatement(
actions=["aps:QueryMetrics"],
principals=[AccountPrincipal("210987654321")],
resources=[workspace.workspace_arn]
)]
)
)
Referencing existing resources
Each resource with an ARN has a token-safe reference factory:
Workspace.fromWorkspaceArn()andWorkspace.fromWorkspaceAttributes()RuleGroupsNamespace.fromRuleGroupsNamespaceArn()Scraper.fromScraperArn()AnomalyDetector.fromAnomalyDetectorArn()ResourcePolicy.fromWorkspaceArn()
Validation commands
yarn buildcompiles the jsii API, strictly compiles README examples, runs unit tests and the isolated test-project type check, lints, and packages JavaScript, Java, Python, .NET, and Go.yarn integ:snapshotverifies or updates the integration snapshot without contacting AWS.yarn integdeploys the integration test inus-east-1; run it asAWS_PROFILE=<non-production-profile> AWS_REGION=us-east-1 yarn integand verify cleanup.yarn compatcompares the jsii surface against the latest published package.
Compatibility
Version 0.1.0 introduces this core-aligned API and intentionally breaks the earlier 0.0.x prototype API. The exact reviewed breaks are enumerated in .compatignore; additional jsii incompatibilities still fail the compatibility gate.
Upstream status
The implementation follows the current AWS CDK contributing guide, construct design guidelines, and the adjacent Grafana construct library as local prior art. A core contribution still requires design consensus, an upstream issue or RFC, a port into the aws-cdk monorepo, and a repeat of deploy-backed integration verification in the upstream test layout.
License
MIT
Metadata
Release files for robhan-cdk-lib.aws-aps 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| robhan_cdk_lib_aws_aps-0.1.0.tar.gz | 111.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| robhan_cdk_lib_aws_aps-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 222.1 kB
Release files / robhan_cdk_lib_aws_aps-0.1.0.tar.gz
| Download URL | robhan_cdk_lib_aws_aps-0.1.0.tar.gz |
|---|---|
| Size | 111.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5fba9ac7f5262a2ac59b059c8abcc8d0bf905d1bea5f8ba2392e27a58625be1e
|
|
BLAKE2b-256 checksum How to use checksums |
87f6004e9a312ee00f8f7a6ee87dd37ef8c7728538d2b9624892470d745b9358
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.14.8
|
Release files / robhan_cdk_lib_aws_aps-0.1.0-py3-none-any.whl
| Download URL | robhan_cdk_lib_aws_aps-0.1.0-py3-none-any.whl |
|---|---|
| Size | 110.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0e267d62f62acde59815060538526c5e6decae8d049b1556974a86eba953ed14
|
|
BLAKE2b-256 checksum How to use checksums |
3103f487d47ca5e8f8a7d1d92a8774be0cb622544b4c3b4bae313118b77df287
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.14.8
|
Security for robhan-cdk-lib.aws-aps 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.