Components

A component groups several resources behind one parameterized object, filling the same role as Pulumi's ComponentResource or a CDK Construct. Components are how a recurring piece of architecture — a hardened bucket, a queue with its dead-letter queue, a service and its role — becomes a single call.

Config uses components but cannot define them. Atlas-lang forbids class, so a component is ordinary Python written by a library or provider author:

from atlantide.core import Component, child
from atlantide.providers.aws import S3Bucket

class SecureBucket(Component):
    def __init__(self, name, *, bucket):
        self.bucket = child(S3Bucket, "assets", bucket=bucket)
        # ...plus a TLS-only hardening policy wired to self.bucket

A component has no presence in the graph of its own. Its children become ordinary flat resources, and each child's name is namespaced under the instance as {component}-{child}. Two instances of the same component therefore never collide.

Publishing and consuming

Components are fetched once and pinned, following the same model as terraform init. There is no import from a live URL, because config runs in a sandbox that may import only atlantide.* and has no network access — fetching during evaluation would breach both restrictions.

Instead, component add clones the source, records the resolved commit and a content hash, and writes the tree into .atlantis/. Vendored code is imported under the atlantide.components.* namespace, which the sandbox permits.

atlantide component add https://github.com/acme/secure-bucket --ref v1.2.0 --as acme --subdir src
atlantide component verify   # re-hash vendored trees vs the lock (tamper/drift)
atlantide component vendor   # rebuild .atlantis/ from the lock alone
atlantide component lock     # re-resolve declared refs -> commits
from atlantide.components.acme import SecureBucket
SecureBucket("assets", bucket="acme-assets")

add records the source under [components.acme] in atlantide.toml, and the resolved pin in atlantide.lock. Commit atlantide.lock and git-ignore .atlantis/, which is derived from it. A build artifact records each component's commit as provenance.

Worked examples

Two components are published from the same organisation, each a small repository with its source in src/ and a test suite covering the expansion, the diff and the plan:

  • aws-remote-state — a versioned S3 bucket, a TLS-only bucket policy and a DynamoDB lock table, plus an optional access role and policy. This is the backend remote state expects you to have created.
  • aws-static-website — a private origin bucket, an origin access control, a CloudFront distribution and a bucket policy scoped to that distribution by AWS:SourceArn.

Both keep the component itself in src/, so both are added the same way — name whichever tag you want to pin to, and add resolves it to an exact commit:

atlantide component add https://github.com/atlantide-org/aws-remote-state \
  --ref <tag> --as acme --subdir src

component-template is the starting point for a new one: the layout, the CI workflow and a test suite already wired up, with a scripts/rename.py that renames the placeholder.

A published component is trusted code

Like a provider, a component runs with the same access the engine has. Review it before adding it. Integrity after that rests on the pin: verify re-hashes every vendored tree and fails on any tampering or drift.