feat(P27): RDS primitive + adapter expansion (D-059)

Add modules/l1/rds/ with interface.json (engine enum for postgres, mysql,
mariadb, sqlserver, oracle), instance.json, README.md (full template with
compliance extension points). Register in registry.json. Expand the
adapter TYPE_MAP/INPUT_MAP/OUTPUT_MAP for aws:rds:instance -> aws_db_instance;
emit backup_retention_period, deletion_protection, storage_encrypted, and
skip_final_snapshot from NFRs/inputs. Add RDS to the primitives-plan matrix.
Update tests for the new registry entry count (12) + RDS adapter emission.

---ci---
project: acdl
phase: 27
milestone: v1.7
status: execute
---/ci---
This commit is contained in:
Jon Chery
2026-07-22 20:21:45 +00:00
parent 49462d5e38
commit a9d8b31595
8 changed files with 284 additions and 6 deletions
+47 -4
View File
@@ -31,14 +31,14 @@ class TestInstance:
class TestRegistry:
EXPECTED_L1_KEYS = {"s3", "vpc", "ecs-cluster", "ecs-service", "iam-role", "alb", "ecr", "cloudfront", "waf"}
EXPECTED_L1_KEYS = {"s3", "vpc", "ecs-cluster", "ecs-service", "iam-role", "alb", "ecr", "cloudfront", "waf", "rds"}
EXPECTED_L2_KEYS = {"static-assets", "microservice"}
def test_registry_has_11_entries(self, registry):
assert len(registry) == 11
def test_registry_has_12_entries(self, registry):
assert len(registry) == 12
assert set(registry.keys()) == (self.EXPECTED_L1_KEYS | self.EXPECTED_L2_KEYS)
def test_registry_has_9_l1_entries(self, registry):
def test_registry_has_10_l1_entries(self, registry):
l1 = {k for k in registry if registry[k]["1.0.0"]["interface"].startswith("modules/l1/")}
assert l1 == self.EXPECTED_L1_KEYS
@@ -85,6 +85,9 @@ class TestTypeMap:
def test_waf_type_in_type_map(self):
assert TYPE_MAP["aws:wafv2:webacl"] == "aws_wafv2_web_acl"
def test_rds_type_in_type_map(self):
assert TYPE_MAP["aws:rds:instance"] == "aws_db_instance"
class TestTfValue:
def test_string_quoted(self):
@@ -196,6 +199,46 @@ class TestS3Output:
assert "aws_s3_bucket.s3.bucket_regional_domain_name" in main_tf
class TestRdsPrimitive:
@pytest.fixture
def rds_stack(self):
return json.load(open(ROOT / "modules/l1/rds/instance.json"))
def test_rds_instance_validates_against_stack_schema(self, rds_stack, stack_schema):
jsonschema.validate(rds_stack, stack_schema)
def test_rds_adapt_emits_db_instance(self, rds_stack, tmp_path):
out_dir = str(tmp_path / "tf_out")
adapt(rds_stack, out_dir)
main_tf = open(os.path.join(out_dir, "main.tf")).read()
assert 'resource "aws_db_instance" "rds"' in main_tf
def test_rds_adapt_emits_engine_and_class(self, rds_stack, tmp_path):
out_dir = str(tmp_path / "tf_out")
adapt(rds_stack, out_dir)
main_tf = open(os.path.join(out_dir, "main.tf")).read()
assert 'engine = "postgres"' in main_tf
assert 'engine_version = "16.4"' in main_tf
assert 'instance_class = "db.t3.micro"' in main_tf
def test_rds_adapt_emits_nfrs(self, rds_stack, tmp_path):
out_dir = str(tmp_path / "tf_out")
adapt(rds_stack, out_dir)
main_tf = open(os.path.join(out_dir, "main.tf")).read()
assert "backup_retention_period = 7" in main_tf
assert "deletion_protection = true" in main_tf
assert "skip_final_snapshot = true" in main_tf
def test_rds_adapt_emits_outputs(self, rds_stack, tmp_path):
out_dir = str(tmp_path / "tf_out")
adapt(rds_stack, out_dir)
main_tf = open(os.path.join(out_dir, "main.tf")).read()
assert 'output "db_endpoint"' in main_tf
assert 'output "db_arn"' in main_tf
assert "aws_db_instance.rds.endpoint" in main_tf
assert "aws_db_instance.rds.arn" in main_tf
class TestStaticAssetsStack:
@pytest.fixture
def static_assets_stack(self):
+1 -1
View File
@@ -437,7 +437,7 @@ class TestPlatformWorkflows:
wf = _load_workflow(".github/workflows/primitives-plan.yml")
job = wf["jobs"]["primitive-plan"]
matrix = job["strategy"]["matrix"]
expected = ["s3", "vpc", "ecs-cluster", "ecs-service", "iam-role", "alb", "ecr", "cloudfront", "waf"]
expected = ["s3", "vpc", "ecs-cluster", "ecs-service", "iam-role", "alb", "ecr", "cloudfront", "waf", "rds"]
assert sorted(matrix["primitive"]) == sorted(expected)
def test_primitives_plan_runs_run_primitive_plan(self):