Skip to main content

@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...Arn factories;
  • scraper destinations, sources, and configuration encodings use factories that prevent invalid combinations;
  • resource policies accept and validate iam.PolicyDocument;
  • taggable resources support both props.tags and Tags.of(...);
  • all currently available AWS::APS CloudFormation 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 API or API_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() and Workspace.fromWorkspaceAttributes()
  • RuleGroupsNamespace.fromRuleGroupsNamespaceArn()
  • Scraper.fromScraperArn()
  • AnomalyDetector.fromAnomalyDetectorArn()
  • ResourcePolicy.fromWorkspaceArn()

Validation commands

  • yarn build compiles 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:snapshot verifies or updates the integration snapshot without contacting AWS.
  • yarn integ deploys the integration test in us-east-1; run it as AWS_PROFILE=<non-production-profile> AWS_REGION=us-east-1 yarn integ and verify cleanup.
  • yarn compat compares 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)

Source distribution for robhan-cdk-lib.aws-aps 0.1.0
File Size Uploaded Provenance
robhan_cdk_lib_aws_aps-0.1.0.tar.gz 111.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for robhan-cdk-lib.aws-aps 0.1.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page