Design Notes for dxaws-acm

Position in the dxaws Architecture

dxaws-acm is a certificate lifecycle module in the dxaws ecosystem.

It manages the lifecycle of DNS-validated ACM certificates, but it does not directly manage Route53 validation records.

Validation record creation and hosted zone resolution are delegated to the dxaws-dns module. This makes dxaws-acm a composed module that depends on DNS rather than a fully standalone primitive.

It does not orchestrate higher-level infrastructure such as CloudFront distributions or website stacks. Those concerns live in higher-level modules (e.g., dxaws-website).

This separation enforces clean service boundaries, explicit module dependencies, and stable contracts.


Declarative Convergence Model

This module follows the dxaws declarative convergence pattern.

Callers describe the desired state:

AcmDesired(
    domain_name="example.test.dxaws.com",
    region="ca-central-1",
    tags={...},
)

The module then:

  1. Reads current state (via provider)

  2. Plans differences (planner)

  3. Applies changes (manager + provider)

  4. Optionally waits for convergence (ISSUED)

No imperative “create certificate” calls are exposed directly to consumers.


Certificate Scope Model

dxaws-acm issues one certificate per FQDN.

The public contract does not support Subject Alternative Names (SANs).
If multiple hostnames require certificates (e.g., www.example.com and api.example.com), they must be requested separately.

This constraint ensures:

  • Independent lifecycle management

  • Simpler drift detection

  • Cleaner rotation and replacement workflows

  • Stable and predictable planner behavior

The module always treats domain_name as the fully qualified domain name to certify.

Hosted zone resolution is delegated to the DNS module using a longest-suffix match strategy:

  • The DNS module determines the authoritative Route53 hosted zone

  • Validation records are written to that zone

  • ACM never interacts with Route53 directly

This avoids ambiguity between zone names and hostnames and keeps service boundaries clean.


Layering Rules

1. Planner

The planner:

  • Compares AcmDesired with AcmCurrent

  • Determines the action (noop, request, recreate)

  • Produces a stable, deterministic plan

The planner contains no boto3 logic.

2. Manager

The manager:

  • Coordinates execution of the plan

  • Handles polling (DNS publication + certificate issuance)

  • Emits observability events

  • Ensures idempotency and drift recovery

The manager does not contain AWS SDK calls directly.

3. Provider

The provider encapsulates all AWS-specific behavior:

  • list_certificates

  • describe_certificate

  • request_dns_validated_certificate

  • delete_certificate

  • get_dns_validation_records

It also normalizes AWS responses into internal models.

This keeps AWS shapes and eventual consistency handling out of higher layers.


DNS Validation Handling

ACM DNS validation is inherently asynchronous.

After requesting a certificate:

  • ACM may not immediately publish DomainValidationOptions.ResourceRecord

  • ACM may take time to reach ISSUED

The manager therefore:

  1. Polls until validation records appear

  2. Converges Route53 CNAME records

  3. Polls until certificate status becomes ISSUED

Timeout behavior is controlled via ApplyOptions.


Eventual Consistency Hardening

Acceptance tests revealed several AWS edge cases:

  • Certificates may appear in list_certificates but fail describe_certificate

  • Certificates deleted out-of-band may still appear temporarily in listings

  • Validation records may not be immediately available

The module explicitly tolerates these cases:

  • describe_certificate failures during list are treated as transient

  • Poll loops handle delayed validation record publication

  • Drift (deleted cert) triggers clean re-request

This ensures stable convergence under real AWS timing behavior.


Normalization Rules

To ensure deterministic planner behavior:

  • Domain names are lowercased and stripped of trailing dots

  • Validation record FQDNs are canonicalized with trailing dots

  • Idempotency tokens are deterministic, <=32 chars, alphanumeric

Planner diffs must remain stable across repeated executions.


Acceptance Guarantees

The acceptance suite proves that the module:

  • Creates DNS-validated certificates

  • Converges validation records

  • Reaches ISSUED

  • Is idempotent

  • Recovers from drift (certificate deleted externally)

  • Leaves AWS clean after teardown

Acceptance runs only when explicitly enabled (DXAWS_AWS_TESTS=1).


Explicit Non-Goals

This module intentionally does not:

  • Create or delegate Route53 hosted zones

  • Manage CloudFront distributions

  • Manage application DNS beyond validation records

  • Expose imperative certificate APIs

  • Support multi-domain (SAN) certificates

Keeping the primitive narrow ensures composability and contract stability.