Two architectural changes: 1. Created terraform/ci-vpc/ — a short-lived VPC for L1 module lifecycle testing, separate from the long-lived platform VPC. Created before VPC-dependent modules (alb, ecs-service, rds, uptime) are tested, destroyed after. Outputs (vpc_id, subnet_ids, sg_id, cluster_arn) are passed to those modules via scripts/run_lifecycle_test.sh + run_lifecycle_destroy.sh wrappers that inject the CI VPC outputs into the example contracts. 2. Updated the workflow to use ci-vpc-apply → lifecycle (with artifact passing) → ci-vpc-destroy (always runs). 8 module-specific fixes: - s3: unique bucket names (acdl-ci-s3a-simple/complex) instead of globally-taken 'my-simple-bucket' - kms-key: alias name with no spaces (locals.tf → alias/acdl-ci-kms) - iam-role: example contract uses role_name (not name, which the interface doesn't declare) - ecs-service: example contract uses family (not name); VPC inputs (cluster_arn, subnets, security_group) injected by CI VPC wrapper - uptime: added subnets, security_group, cluster_arn to interface + module; network_configuration is dynamic (only when subnets provided) - rds: added subnet_ids input + db_subnet_group resource (conditional on subnet_ids being non-empty) - alb: removed hardcoded placeholder sg/subnet values from examples; vpc_id + subnets + security_group injected by CI VPC wrapper - cloudfront: removed invalid placeholder WAF ARN from complex example Regression: 479 passed, 0 skipped, 5 deselected. All 24 example contracts pass --check-only. ---ci--- project: acdl phase: P59 milestone: v1.11 status: execute ---/ci---
s3 — S3 bucket
Module kind: primitive | Version: 1.0.0
A single S3 bucket for object storage. The simplest module — one resource, two inputs, two outputs. Versioning is enabled by default.
Resources
| Resource | Type | Purpose |
|---|---|---|
| bucket | aws_s3_bucket |
The S3 bucket itself |
Inputs
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
bucket_name |
string | yes | — | Globally-unique S3 bucket name |
region |
string | yes | — | AWS region the bucket is created in |
Outputs
| Name | Type | Description |
|---|---|---|
bucket_arn |
arn | The S3 bucket ARN |
bucket_name |
string | The bucket name (echoes the input) |
NFRs
| Name | Type | Default | Description |
|---|---|---|---|
versioning |
boolean | true | Enable S3 versioning |
Usage
{
"id": "s3",
"type": "aws:s3:bucket",
"module": "s3@1.0.0",
"inputs": {
"bucket_name": "acdl-spike-bucket",
"region": "us-east-1"
}
}
A concrete instance is at instance.json (used by the platform
pipeline as the regression baseline).
Compliance extension points
- Encryption at rest — add
aws_s3_bucket_server_side_encryption_configurationwith a customer-managed KMS key (SOC2 CC6.1, GDPR Art.32). - Object Lock — add
aws_s3_bucket_object_lock_configurationin compliance mode with 7-year retention for immutable evidence (SOX §802, DORA audit trail). - Access logging — add
aws_s3_bucket_loggingto a target logging bucket (SOC2 CC7.2). - Public access block — add
aws_s3_bucket_public_access_blockto prevent data exfiltration (SOC2 CC6.1, GDPR Art.32). - Lifecycle policy — add
aws_s3_bucket_lifecycle_configurationfor retention enforcement (GDPR Art.5(2).
Examples
Validated example contracts are in examples/. The platform-test
pipeline validates them against schemas/contract.schema.json.
Simple
A minimal deployment:
environment: dev
id: s3a
infrastructure:
s3:
inputs:
bucket_name: my-simple-bucket
region: us-east-1
version: 1.0.0
name: s3-bucket
Complex
A production deployment with optional inputs:
environment: dev
id: s3a
infrastructure:
s3:
inputs:
bucket_name: my-production-bucket
region: us-east-1
version: 1.0.0
name: s3-bucket
Note: the s3 primitive's compliance extensions (Object Lock, access logging, public access block, lifecycle policy) are documented in the Compliance extension points section above but not yet wired as inputs. The complex example uses the same inputs as the simple example; compliance extensions are roadmap.
Versioning
1.0.0 — interface MAJOR, behavior MINOR, lifecycle PATCH. MAJOR bumps
require a new registry entry (immutable publication); old entries enter
a 12-month deprecation window.