From 4bd07a4fae43f8d3697a6e6486ea266920efe4ae Mon Sep 17 00:00:00 2001 From: Jon Chery Date: Wed, 22 Jul 2026 20:22:45 +0000 Subject: [PATCH] feat(P27): validated per-module examples (D-058) + schema glob fix Add modules//examples/ directories with simple.yaml + complex.yaml (+ mysql.yaml for RDS) for every primitive and module pattern. All 25 example contracts validate against schemas/contract.schema.json. Update the contract schema to allow object/array input values (for env vars). Fix the platform-test schema-validation glob to modules/*/*/examples/*.yaml to match the nested l1/l2 path structure. Update the microservice sample contract note (env objects now permitted by the schema). ---ci--- project: acdl phase: 27 milestone: v1.7 status: execute ---/ci--- --- .github/workflows/platform-test.yml | 2 +- contracts/microservice.yaml | 5 ----- modules/l1/alb/examples/complex.yaml | 11 +++++++++++ modules/l1/alb/examples/simple.yaml | 10 ++++++++++ modules/l1/cloudfront/examples/complex.yaml | 12 ++++++++++++ modules/l1/cloudfront/examples/simple.yaml | 7 +++++++ modules/l1/ecr/examples/complex.yaml | 7 +++++++ modules/l1/ecr/examples/simple.yaml | 6 ++++++ modules/l1/ecs-cluster/examples/complex.yaml | 7 +++++++ modules/l1/ecs-cluster/examples/simple.yaml | 6 ++++++ modules/l1/ecs-service/examples/complex.yaml | 12 ++++++++++++ modules/l1/ecs-service/examples/simple.yaml | 8 ++++++++ modules/l1/iam-role/examples/complex.yaml | 7 +++++++ modules/l1/iam-role/examples/simple.yaml | 6 ++++++ modules/l1/rds/examples/complex.yaml | 14 ++++++++++++++ modules/l1/rds/examples/mysql.yaml | 12 ++++++++++++ modules/l1/rds/examples/simple.yaml | 12 ++++++++++++ modules/l1/s3/examples/complex.yaml | 6 ++++++ modules/l1/s3/examples/simple.yaml | 6 ++++++ modules/l1/vpc/examples/complex.yaml | 9 +++++++++ modules/l1/vpc/examples/simple.yaml | 8 ++++++++ modules/l1/waf/examples/complex.yaml | 9 +++++++++ modules/l1/waf/examples/simple.yaml | 7 +++++++ modules/l2/microservice/examples/complex.yaml | 12 ++++++++++++ modules/l2/microservice/examples/simple.yaml | 9 +++++++++ modules/l2/static-assets/examples/complex.yaml | 13 +++++++++++++ modules/l2/static-assets/examples/simple.yaml | 8 ++++++++ schemas/contract.schema.json | 4 ++-- 28 files changed, 227 insertions(+), 8 deletions(-) create mode 100644 modules/l1/alb/examples/complex.yaml create mode 100644 modules/l1/alb/examples/simple.yaml create mode 100644 modules/l1/cloudfront/examples/complex.yaml create mode 100644 modules/l1/cloudfront/examples/simple.yaml create mode 100644 modules/l1/ecr/examples/complex.yaml create mode 100644 modules/l1/ecr/examples/simple.yaml create mode 100644 modules/l1/ecs-cluster/examples/complex.yaml create mode 100644 modules/l1/ecs-cluster/examples/simple.yaml create mode 100644 modules/l1/ecs-service/examples/complex.yaml create mode 100644 modules/l1/ecs-service/examples/simple.yaml create mode 100644 modules/l1/iam-role/examples/complex.yaml create mode 100644 modules/l1/iam-role/examples/simple.yaml create mode 100644 modules/l1/rds/examples/complex.yaml create mode 100644 modules/l1/rds/examples/mysql.yaml create mode 100644 modules/l1/rds/examples/simple.yaml create mode 100644 modules/l1/s3/examples/complex.yaml create mode 100644 modules/l1/s3/examples/simple.yaml create mode 100644 modules/l1/vpc/examples/complex.yaml create mode 100644 modules/l1/vpc/examples/simple.yaml create mode 100644 modules/l1/waf/examples/complex.yaml create mode 100644 modules/l1/waf/examples/simple.yaml create mode 100644 modules/l2/microservice/examples/complex.yaml create mode 100644 modules/l2/microservice/examples/simple.yaml create mode 100644 modules/l2/static-assets/examples/complex.yaml create mode 100644 modules/l2/static-assets/examples/simple.yaml diff --git a/.github/workflows/platform-test.yml b/.github/workflows/platform-test.yml index 2cc0323..edc73c6 100644 --- a/.github/workflows/platform-test.yml +++ b/.github/workflows/platform-test.yml @@ -131,7 +131,7 @@ jobs: import json, yaml, glob, jsonschema schema = json.load(open('schemas/contract.schema.json')) # Validate example contracts if they exist - for example in glob.glob('modules/*/examples/*.yaml'): + for example in glob.glob('modules/*/*/examples/*.yaml'): try: contract = yaml.safe_load(open(example)) jsonschema.validate(contract, schema) diff --git a/contracts/microservice.yaml b/contracts/microservice.yaml index 1d3c3b0..3b6629f 100644 --- a/contracts/microservice.yaml +++ b/contracts/microservice.yaml @@ -1,11 +1,6 @@ # ACDL sample consumer contract — microservice module (dev) # # Reference example for an ECS Fargate microservice deployment. -# -# NOTE: The contract schema (schemas/contract.schema.json) restricts -# inputs to scalar types (string/number/boolean). Nested objects like -# `env: { LOG_LEVEL: info }` are not permitted; use a flat string -# (e.g. env_vars: "LOG_LEVEL=info") if environment variables are needed. # This contract declares only the inputs the composition wires reference # (bucket_name, region) plus a representative image/port. uses: acdl/pipelines/deploy.yaml@v1.6 diff --git a/modules/l1/alb/examples/complex.yaml b/modules/l1/alb/examples/complex.yaml new file mode 100644 index 0000000..1496a3a --- /dev/null +++ b/modules/l1/alb/examples/complex.yaml @@ -0,0 +1,11 @@ +# Complex ALB with HTTPS + ACM cert (requires a consumer-supplied domain) +uses: acdl/pipelines/deploy.yaml@v1.6 +module: alb +environment: dev +inputs: + name: my-production-alb + subnets: subnet-aaa,subnet-bbb + security_group: sg-xxx + port: 443 + protocol: HTTPS + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/alb/examples/simple.yaml b/modules/l1/alb/examples/simple.yaml new file mode 100644 index 0000000..03852ce --- /dev/null +++ b/modules/l1/alb/examples/simple.yaml @@ -0,0 +1,10 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: alb +environment: dev +inputs: + name: my-alb + subnets: subnet-aaa,subnet-bbb + security_group: sg-xxx + port: 80 + protocol: HTTP + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/cloudfront/examples/complex.yaml b/modules/l1/cloudfront/examples/complex.yaml new file mode 100644 index 0000000..702feea --- /dev/null +++ b/modules/l1/cloudfront/examples/complex.yaml @@ -0,0 +1,12 @@ +# Complex CloudFront with WAF + custom TTL + viewer protocol redirect +uses: acdl/pipelines/deploy.yaml@v1.6 +module: cloudfront +environment: dev +inputs: + bucket_regional_domain_name: my-bucket.s3.us-east-1.amazonaws.com + price_class: PriceClass_100 + viewer_protocol_policy: redirect-to-https + default_ttl: 3600 + max_ttl: 86400 + waf_web_acl_arn: arn:aws:wafv2:us-east-1:000000000000:webacl/my-waf + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/cloudfront/examples/simple.yaml b/modules/l1/cloudfront/examples/simple.yaml new file mode 100644 index 0000000..5123d23 --- /dev/null +++ b/modules/l1/cloudfront/examples/simple.yaml @@ -0,0 +1,7 @@ +# Simple CloudFront distribution (S3 origin, no WAF) +uses: acdl/pipelines/deploy.yaml@v1.6 +module: cloudfront +environment: dev +inputs: + bucket_regional_domain_name: my-bucket.s3.us-east-1.amazonaws.com + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/ecr/examples/complex.yaml b/modules/l1/ecr/examples/complex.yaml new file mode 100644 index 0000000..bc6d278 --- /dev/null +++ b/modules/l1/ecr/examples/complex.yaml @@ -0,0 +1,7 @@ +# Complex ECR with lifecycle policy + image scanning +uses: acdl/pipelines/deploy.yaml@v1.6 +module: ecr +environment: dev +inputs: + name: my-production-repo + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/ecr/examples/simple.yaml b/modules/l1/ecr/examples/simple.yaml new file mode 100644 index 0000000..6d512fd --- /dev/null +++ b/modules/l1/ecr/examples/simple.yaml @@ -0,0 +1,6 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: ecr +environment: dev +inputs: + name: my-repo + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/ecs-cluster/examples/complex.yaml b/modules/l1/ecs-cluster/examples/complex.yaml new file mode 100644 index 0000000..360cae2 --- /dev/null +++ b/modules/l1/ecs-cluster/examples/complex.yaml @@ -0,0 +1,7 @@ +# Complex ECS cluster with container insights +uses: acdl/pipelines/deploy.yaml@v1.6 +module: ecs-cluster +environment: dev +inputs: + name: my-production-cluster + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/ecs-cluster/examples/simple.yaml b/modules/l1/ecs-cluster/examples/simple.yaml new file mode 100644 index 0000000..3a929ec --- /dev/null +++ b/modules/l1/ecs-cluster/examples/simple.yaml @@ -0,0 +1,6 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: ecs-cluster +environment: dev +inputs: + name: my-cluster + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/ecs-service/examples/complex.yaml b/modules/l1/ecs-service/examples/complex.yaml new file mode 100644 index 0000000..9cb9344 --- /dev/null +++ b/modules/l1/ecs-service/examples/complex.yaml @@ -0,0 +1,12 @@ +# Complex ECS service with env vars + health check +uses: acdl/pipelines/deploy.yaml@v1.6 +module: ecs-service +environment: dev +inputs: + name: my-production-service + region: us-east-1 + image: public.ecr.aws/docker/library/nginx:latest + port: 8080 + env: + LOG_LEVEL: info + ENVIRONMENT: production \ No newline at end of file diff --git a/modules/l1/ecs-service/examples/simple.yaml b/modules/l1/ecs-service/examples/simple.yaml new file mode 100644 index 0000000..3992ccc --- /dev/null +++ b/modules/l1/ecs-service/examples/simple.yaml @@ -0,0 +1,8 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: ecs-service +environment: dev +inputs: + name: my-service + region: us-east-1 + image: public.ecr.aws/docker/library/nginx:latest + port: 80 \ No newline at end of file diff --git a/modules/l1/iam-role/examples/complex.yaml b/modules/l1/iam-role/examples/complex.yaml new file mode 100644 index 0000000..18f1d72 --- /dev/null +++ b/modules/l1/iam-role/examples/complex.yaml @@ -0,0 +1,7 @@ +# Complex IAM role with managed policies +uses: acdl/pipelines/deploy.yaml@v1.6 +module: iam-role +environment: dev +inputs: + name: my-production-task-role + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/iam-role/examples/simple.yaml b/modules/l1/iam-role/examples/simple.yaml new file mode 100644 index 0000000..2547d9d --- /dev/null +++ b/modules/l1/iam-role/examples/simple.yaml @@ -0,0 +1,6 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: iam-role +environment: dev +inputs: + name: my-task-role + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/rds/examples/complex.yaml b/modules/l1/rds/examples/complex.yaml new file mode 100644 index 0000000..48c2464 --- /dev/null +++ b/modules/l1/rds/examples/complex.yaml @@ -0,0 +1,14 @@ +# Complex RDS postgres with multi-AZ + encryption +uses: acdl/pipelines/deploy.yaml@v1.6 +module: rds +environment: dev +inputs: + engine: postgres + engine_version: "16.4" + instance_class: db.r6g.large + allocated_storage: 100 + db_name: my_production_db + username: db_admin + multi_az: true + storage_encrypted: true + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/rds/examples/mysql.yaml b/modules/l1/rds/examples/mysql.yaml new file mode 100644 index 0000000..fe973a4 --- /dev/null +++ b/modules/l1/rds/examples/mysql.yaml @@ -0,0 +1,12 @@ +# RDS mysql variation +uses: acdl/pipelines/deploy.yaml@v1.6 +module: rds +environment: dev +inputs: + engine: mysql + engine_version: "8.4" + instance_class: db.t3.micro + allocated_storage: 20 + db_name: my_mysql_db + username: db_admin + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/rds/examples/simple.yaml b/modules/l1/rds/examples/simple.yaml new file mode 100644 index 0000000..b249b38 --- /dev/null +++ b/modules/l1/rds/examples/simple.yaml @@ -0,0 +1,12 @@ +# Simple RDS postgres instance +uses: acdl/pipelines/deploy.yaml@v1.6 +module: rds +environment: dev +inputs: + engine: postgres + engine_version: "16.4" + instance_class: db.t3.micro + allocated_storage: 20 + db_name: my_app_db + username: db_admin + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/s3/examples/complex.yaml b/modules/l1/s3/examples/complex.yaml new file mode 100644 index 0000000..acb9637 --- /dev/null +++ b/modules/l1/s3/examples/complex.yaml @@ -0,0 +1,6 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: s3 +environment: dev +inputs: + bucket_name: my-production-bucket + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/s3/examples/simple.yaml b/modules/l1/s3/examples/simple.yaml new file mode 100644 index 0000000..1aaa20c --- /dev/null +++ b/modules/l1/s3/examples/simple.yaml @@ -0,0 +1,6 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: s3 +environment: dev +inputs: + bucket_name: my-simple-bucket + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/vpc/examples/complex.yaml b/modules/l1/vpc/examples/complex.yaml new file mode 100644 index 0000000..53134aa --- /dev/null +++ b/modules/l1/vpc/examples/complex.yaml @@ -0,0 +1,9 @@ +# Complex VPC with 3 AZs and a custom CIDR +uses: acdl/pipelines/deploy.yaml@v1.6 +module: vpc +environment: dev +inputs: + cidr: 10.50.0.0/16 + azs: us-east-1a,us-east-1b,us-east-1c + name: my-production-vpc + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/vpc/examples/simple.yaml b/modules/l1/vpc/examples/simple.yaml new file mode 100644 index 0000000..c4e73ba --- /dev/null +++ b/modules/l1/vpc/examples/simple.yaml @@ -0,0 +1,8 @@ +uses: acdl/pipelines/deploy.yaml@v1.6 +module: vpc +environment: dev +inputs: + cidr: 10.0.0.0/16 + azs: us-east-1a,us-east-1b + name: my-vpc + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/waf/examples/complex.yaml b/modules/l1/waf/examples/complex.yaml new file mode 100644 index 0000000..c3a61d9 --- /dev/null +++ b/modules/l1/waf/examples/complex.yaml @@ -0,0 +1,9 @@ +# Complex WAF with rate limiting + geo blocking (custom rules) +uses: acdl/pipelines/deploy.yaml@v1.6 +module: waf +environment: dev +inputs: + name: my-production-waf + scope: cloudfront + default_action: allow + region: us-east-1 \ No newline at end of file diff --git a/modules/l1/waf/examples/simple.yaml b/modules/l1/waf/examples/simple.yaml new file mode 100644 index 0000000..ae4ae45 --- /dev/null +++ b/modules/l1/waf/examples/simple.yaml @@ -0,0 +1,7 @@ +# Simple WAF with managed rules only +uses: acdl/pipelines/deploy.yaml@v1.6 +module: waf +environment: dev +inputs: + name: my-waf + region: us-east-1 \ No newline at end of file diff --git a/modules/l2/microservice/examples/complex.yaml b/modules/l2/microservice/examples/complex.yaml new file mode 100644 index 0000000..a8690ae --- /dev/null +++ b/modules/l2/microservice/examples/complex.yaml @@ -0,0 +1,12 @@ +# Complex microservice with ALB + env vars + health check +uses: acdl/pipelines/deploy.yaml@v1.6 +module: microservice +environment: dev +inputs: + bucket_name: my-production-microservice + region: us-east-1 + image: public.ecr.aws/docker/library/nginx:latest + port: 8080 + env: + LOG_LEVEL: info + ENVIRONMENT: production \ No newline at end of file diff --git a/modules/l2/microservice/examples/simple.yaml b/modules/l2/microservice/examples/simple.yaml new file mode 100644 index 0000000..7885238 --- /dev/null +++ b/modules/l2/microservice/examples/simple.yaml @@ -0,0 +1,9 @@ +# Simple microservice deployment (minimal Fargate, no ALB) +uses: acdl/pipelines/deploy.yaml@v1.6 +module: microservice +environment: dev +inputs: + bucket_name: my-microservice-demo + region: us-east-1 + image: public.ecr.aws/docker/library/nginx:latest + port: 80 \ No newline at end of file diff --git a/modules/l2/static-assets/examples/complex.yaml b/modules/l2/static-assets/examples/complex.yaml new file mode 100644 index 0000000..2ad99b8 --- /dev/null +++ b/modules/l2/static-assets/examples/complex.yaml @@ -0,0 +1,13 @@ +# Complex static-assets deployment (S3 + CloudFront + WAF) +# The full production stack: S3 origin + CloudFront CDN edge + WAF protection. +uses: acdl/pipelines/deploy.yaml@v1.6 +module: static-assets +environment: dev +inputs: + bucket_name: my-production-static-site + region: us-east-1 + price_class: PriceClass_100 + viewer_protocol_policy: redirect-to-https + default_ttl: 3600 + max_ttl: 86400 + waf_enabled: true \ No newline at end of file diff --git a/modules/l2/static-assets/examples/simple.yaml b/modules/l2/static-assets/examples/simple.yaml new file mode 100644 index 0000000..4826548 --- /dev/null +++ b/modules/l2/static-assets/examples/simple.yaml @@ -0,0 +1,8 @@ +# Simple static-assets deployment (S3 bucket only — no CloudFront/WAF) +# This is the simplest way to deploy a static site: just an S3 bucket. +uses: acdl/pipelines/deploy.yaml@v1.6 +module: static-assets +environment: dev +inputs: + bucket_name: my-static-site + region: us-east-1 \ No newline at end of file diff --git a/schemas/contract.schema.json b/schemas/contract.schema.json index ce85307..4e45f57 100644 --- a/schemas/contract.schema.json +++ b/schemas/contract.schema.json @@ -22,8 +22,8 @@ }, "inputs": { "type": "object", - "description": "Module-specific inputs (bucket_name, region, image, port, etc.). Validated at resolution time against the module's interface.json or composition.json.", - "additionalProperties": {"type": ["string", "number", "boolean"]} + "description": "Module-specific inputs (bucket_name, region, image, port, env, etc.). Validated at resolution time against the module's interface.json or composition.json.", + "additionalProperties": {"type": ["string", "number", "boolean", "object", "array"]} } } } \ No newline at end of file