Skip to content

Fix ECS module publishing schema fields#33

Merged
mabadir merged 1 commit into
mainfrom
ma/fix-ecs-web-publish-schema
Jun 19, 2026
Merged

Fix ECS module publishing schema fields#33
mabadir merged 1 commit into
mainfrom
ma/fix-ecs-web-publish-schema

Conversation

@mabadir

@mabadir mabadir commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • bump rvn-ecs-web to 0.6.1
  • replace unsupported object_array item_title_field with schema-backed item_title.template
  • use singular deploy.infrastructure.ecs_service_arn required by the latest ECS deploy schema
  • bump rvn-ecs-worker to 0.1.1 and fix the shared ECS deploy partial so worker compiles with schema-supported infrastructure fields

Validation

  • make modules-tools-build
  • node tools/ravion-modules/dist/src/cli.js validate compute/ecs_service/rvn-ecs-web-definition.yml compute/ecs_service/rvn-ecs-worker-definition.yml
  • node tools/ravion-modules/dist/src/cli.js compile
  • node tools/ravion-modules/dist/src/cli.js status
  • latest /Users/mina/flightcontrol/main schema sweep with modules.ValidateModuleDataTemplatable over all compiled definitions
  • rg -n "ecs_service_arns|item_title_field" . -g '.yml' -g '.yaml' -g '!tools/ravion-modules/test/fixtures/**'
  • git diff --check

Greptile Summary

This PR bumps rvn-ecs-web from 0.6.0 to 0.6.1 and fixes two schema-compatibility issues in the module definition file.

  • Replaces the unsupported item_title_field: stage with the schema-backed item_title: { template: \"{stage}\" } on the deployment_pause_stages object array input.
  • Migrates deploy.infrastructure.ecs_service_arns (a single-item array) to deploy.infrastructure.ecs_service_arn (scalar string), matching the updated ECS deploy schema. The shared partial partials/deploy/ecs-service-deploy-common.yml still carries the old plural key and is inherited unchanged by rvn-ecs-worker-definition.yml; if the schema change applies to worker deployments as well, the worker module will fail validation.

Confidence Score: 4/5

The web definition change itself is safe; the schema fixes are targeted and the PR description confirms validate and compile pass. The risk is that the shared deploy partial is left with the old plural key, which the worker definition inherits without any override.

The web module's deploy infrastructure block is correctly updated. However, partials/deploy/ecs-service-deploy-common.yml still contains ecs_service_arns (plural), and rvn-ecs-worker-definition.yml relies on that partial without overriding the infrastructure block — meaning the worker could break under the same schema requirement this PR is fixing for the web module.

partials/deploy/ecs-service-deploy-common.yml — still uses ecs_service_arns (plural), which rvn-ecs-worker-definition.yml inherits without an override.

Important Files Changed

Filename Overview
compute/ecs_service/rvn-ecs-web-definition.yml Bumps version to 0.6.1, replaces deprecated item_title_field with schema-backed item_title.template, and migrates deploy.infrastructure from ecs_service_arns (array) to ecs_service_arn (scalar) as required by the updated ECS deploy schema; release.description was not updated to reflect these 0.6.1 changes.
partials/deploy/ecs-service-deploy-common.yml Not changed in this PR, but still carries ecs_service_arns (plural array) that the web definition now overrides; rvn-ecs-worker-definition.yml inherits this key without an override, potentially leaving the worker module broken under the same schema change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ecs-service-deploy-common.yml partial\necs_service_arns array - OLD] -->|$merge| B[rvn-ecs-web-definition.yml\ninfrastructure block overrides\necs_service_arn singular - FIXED]
    A -->|$merge, no override| C[rvn-ecs-worker-definition.yml\ninherits ecs_service_arns array\nNOT FIXED]
    B --> D[Web deploy validates ✅]
    C --> E[Worker deploy may fail ⚠️]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[ecs-service-deploy-common.yml partial\necs_service_arns array - OLD] -->|$merge| B[rvn-ecs-web-definition.yml\ninfrastructure block overrides\necs_service_arn singular - FIXED]
    A -->|$merge, no override| C[rvn-ecs-worker-definition.yml\ninherits ecs_service_arns array\nNOT FIXED]
    B --> D[Web deploy validates ✅]
    C --> E[Worker deploy may fail ⚠️]
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
compute/ecs_service/rvn-ecs-web-definition.yml:6-7
The `release.description` was not updated to describe the 0.6.1 changes. Per the AGENTS.md guidelines, `release.description` should summarize the publishable change for the new version, not carry forward the 0.6.0 feature narrative. The current text describes the blue/green/canary features added in 0.6.0; the 0.6.1 patch fixes the publishing schema (`item_title` and singular `ecs_service_arn`).

```suggestion
  version: 0.6.1
  description: Fix publishing schema by replacing unsupported item_title_field with item_title.template and updating ecs_service_arn to the singular form required by the latest ECS deploy schema.
```

Reviews (1): Last reviewed commit: "Fix ECS web module publishing schema" | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@mabadir mabadir requested a review from flybayer June 19, 2026 16:46
@github-actions

Copy link
Copy Markdown

Ravion Module Publish Plan

Dry run only. No Ravion API mutations were made.

Module Current Version New Version Description
rvn-ecs-web 0.5.1 0.6.1 Add native ECS blue/green, linear, and canary deployments with per-deploy strategy controls, manual approval gates, standby validation traffic, production/alternate target groups, ALB group stickiness guidance, ECS infrastructure role, and load-balancer advanced configuration outputs.

Diffs

rvn-ecs-web 0.5.1 -> 0.6.1

--- remote
+++ compiled
     queue_overflow: oldest
     queue_size: 1
   infrastructure:
+    ecs_alternate_target_group_arn: <<stack.output.alternate_target_group_arn>>
     ecs_cluster_arn: <<stack.output.service_cluster>>
-    ecs_service_arns:
-      - <<stack.output.service_arn>>
+    ecs_infrastructure_role_arn: <<stack.output.ecs_infrastructure_role_arn>>
+    ecs_production_listener_rule_arn: <<stack.output.production_listener_rule_arn>>
+    ecs_service_arn: <<stack.output.service_arn>>
+    ecs_target_group_arn: <<stack.output.target_group_arn>>
+    ecs_test_listener_rule_arn: <<stack.output.test_listener_rule_arn>>
   inputs:
     - description: Pass the image tag or digest to deploy. For Nixpacks or Dockerfile builds, this is resolved in the Ravion-created ECR repository. For Prebuilt image from registry mode, this is resolved in the repository configured on the module. Do not pass a full image URI.
       id: image_ref
@@
       type: string
   post_deploy: '<< module.input.post_deploy_enabled && len(module.input.post_deploy_command) > 0 ? {"container_overrides": [{"name": stack.output.container_name, "command": module.input.post_deploy_command, "environment": module.input.post_deploy_environment_variables, "cpu": module.input.post_deploy_cpu || nil, "memory": module.input.post_deploy_memory || nil}], "cpu": string(module.input.post_deploy_cpu || (module.input.capacity_provider == "ec2" ? int(float(module.input.task_cpu) * 1024) : int(float(module.input.fargate_size.vcpu) * 1024))), "memory": string(module.input.post_deploy_memory || (module.input.capacity_provider == "ec2" ? int(float(module.input.task_memory) * 1024) : int(float(module.input.fargate_size.memory_gb) * 1024))), "ephemeral_storage": (module.input.post_deploy_ephemeral_storage_size_gib ? {size_in_gib: module.input.post_deploy_ephemeral_storage_size_gib} : nil), "task_role_arn": stack.output.task_role_arn, "execution_role_arn": stack.output.execution_role_arn, "capacity_provider_strategy": ((module.input.capacity_provider == "fargate" || module.input.additional_fargate_capacity_enabled ? [{capacity_provider: module.input.fargate_capacity_provider_name, weight: 1, base: 0}] : []) | concat(module.input.capacity_provider == "fargate_spot" || module.input.additional_fargate_spot_capacity_enabled ? [{capacity_provider: module.input.fargate_spot_capacity_provider_name, weight: 1, base: 0}] : []) | concat(module.input.capacity_provider == "ec2" || module.input.additional_ec2_capacity_enabled ? [{capacity_provider: module.input.ec2_capacity_provider_name, weight: 1, base: 0}] : [])), "network_configuration": {"awsvpc_configuration": {"subnets": (module.input.private_subnet_placement_enabled ? module.input.private_subnet_ids : module.input.public_subnet_ids), "security_groups": ([stack.output.security_group_id] | concat(module.input.security_group_ids != nil ? module.input.security_group_ids : [])), "assign_public_ip": (module.input.private_subnet_placement_enabled ? "DISABLED" : "ENABLED")}}, "enable_execute_command": module.input.execute_command_enabled, "timeout": module.input.post_deploy_timeout} : nil >>'
   pre_deploy: '<< module.input.pre_deploy_enabled && len(module.input.pre_deploy_command) > 0 ? {"container_overrides": [{"name": stack.output.container_name, "command": module.input.pre_deploy_command, "environment": module.input.pre_deploy_environment_variables, "cpu": module.input.pre_deploy_cpu || nil, "memory": module.input.pre_deploy_memory || nil}], "cpu": string(module.input.pre_deploy_cpu || (module.input.capacity_provider == "ec2" ? int(float(module.input.task_cpu) * 1024) : int(float(module.input.fargate_size.vcpu) * 1024))), "memory": string(module.input.pre_deploy_memory || (module.input.capacity_provider == "ec2" ? int(float(module.input.task_memory) * 1024) : int(float(module.input.fargate_size.memory_gb) * 1024))), "ephemeral_storage": (module.input.pre_deploy_ephemeral_storage_size_gib ? {size_in_gib: module.input.pre_deploy_ephemeral_storage_size_gib} : nil), "task_role_arn": stack.output.task_role_arn, "execution_role_arn": stack.output.execution_role_arn, "capacity_provider_strategy": ((module.input.capacity_provider == "fargate" || module.input.additional_fargate_capacity_enabled ? [{capacity_provider: module.input.fargate_capacity_provider_name, weight: 1, base: 0}] : []) | concat(module.input.capacity_provider == "fargate_spot" || module.input.additional_fargate_spot_capacity_enabled ? [{capacity_provider: module.input.fargate_spot_capacity_provider_name, weight: 1, base: 0}] : []) | concat(module.input.capacity_provider == "ec2" || module.input.additional_ec2_capacity_enabled ? [{capacity_provider: module.input.ec2_capacity_provider_name, weight: 1, base: 0}] : [])), "network_configuration": {"awsvpc_configuration": {"subnets": (module.input.private_subnet_placement_enabled ? module.input.private_subnet_ids : module.input.public_subnet_ids), "security_groups": ([stack.output.security_group_id] | concat(module.input.security_group_ids != nil ? module.input.security_group_ids : [])), "assign_public_ip": (module.input.private_subnet_placement_enabled ? "DISABLED" : "ENABLED")}}, "enable_execute_command": module.input.execute_command_enabled, "timeout": module.input.pre_deploy_timeout} : nil >>'
+  strategy: |
+    <<
+    module.input.deployment_strategy == "rolling" ? nil :
+    module.input.deployment_strategy == "blue_green" ? {
+      "type": "blue_green",
+      "bake_time_in_minutes": module.input.deployment_bake_time_in_minutes,
+      "pause_stages": module.input.deployment_pause_stages
+    } :
+    module.input.deployment_strategy == "linear" ? {
+      "type": "linear",
+      "bake_time_in_minutes": module.input.deployment_bake_time_in_minutes,
+      "pause_stages": module.input.deployment_pause_stages,
+      "linear": {
+        "step_percentage": module.input.linear_step_percentage,
+        "step_bake_time_in_minutes": module.input.linear_step_bake_time_in_minutes
+      }
+    } : {
+      "type": "canary",
+      "bake_time_in_minutes": module.input.deployment_bake_time_in_minutes,
+      "pause_stages": module.input.deployment_pause_stages,
+      "canary": {
+        "canary_percent": module.input.canary_percent,
+        "canary_bake_time_in_minutes": module.input.canary_bake_time_in_minutes
+      }
+    }
+    >>
   task_definition:
     container_definitions: "<< (module.input.firelens_enabled ? [{\"command\": (len(module.input.prebuilt_image_start_command) > 0 ? module.input.prebuilt_image_start_command : nil), \"cpu\": (module.input.capacity_provider == \"ec2\" ? int(float(module.input.task_cpu) * 1024) : int(float(module.input.fargate_size.vcpu) * 1024)), \"depends_on\": [{\"container_name\": \"log_router\", \"condition\": \"START\"}], \"environment\": ([{name: \"PORT\", value: string(module.input.container_port)}] | concat(module.input.environment_variables != nil ? module.input.environment_variables : [])), \"essential\": true, \"image\": (module.input.build_type == \"prebuilt_image\" ? (deploy.input.image_ref contains \"sha256:\" ? module.input.image_repository + \"@\" + deploy.input.image_ref : module.input.image_repository + \":\" + deploy.input.image_ref) : (deploy.input.image_ref contains \"sha256:\" ? stack.output.ecr_repository_url + \"@\" + deploy.input.image_ref : stack.output.ecr_repository_url + \":\" + deploy.input.image_ref)), \"linux_parameters\": {\"init_process_enabled\": true}, \"log_configuration\": {\"log_driver\": \"awsfirelens\"}, \"memory\": (module.input.capacity_provider == \"ec2\" ? int(float(module.input.task_memory) * 1024) : int(float(module.input.fargate_size.memory_gb) * 1024)), \"name\": (stack.output.container_name), \"port_mappings\": [{\"app_protocol\": \"http\", \"container_port\": (module.input.container_port), \"protocol\": \"tcp\"}], \"readonly_root_filesystem\": false, \"repository_credentials\": (module.input.image_registry_credentials_secret_arn ? {credentials_parameter: module.input.image_registry_credentials_secret_arn} : nil), \"secrets\": (module.input.secrets), \"stop_timeout\": 30}, {\"name\": \"log_router\", \"image\": module.input.firelens_image, \"cpu\": 0, \"memory_reservation\": 51, \"essential\": true, \"environment\": ([{name: \"FIRELENS_CONFIG_CONTENT\", value: \"[SERVICE]\\n    Flush 1\\n    Grace 30\\n\\n\" + (module.input.firelens_config ? module.input.firelens_config + \"\\n\" : \"\") + (module.input.firelens_cloudwatch_output_enabled ? \"\\n[OUTPUT]\\n    Name cloudwatch\\n    Match *\\n    region \" + stack.output.region + \"\\n    log_group_name \" + stack.output.log_group_name + \"\\n    auto_create_group true\\n    log_stream_prefix \" + stack.output.log_stream_prefix + \"/\\n    retry_limit 2\\n    log_key log\\n    log_format json/emf\\n\" : \"\")}] | concat(module.input.firelens_environment_variables != nil ? module.input.firelens_environment_variables : [])), \"secrets\": module.input.firelens_secrets != nil ? module.input.firelens_secrets : [], \"command\": [\"/bin/sh\", \"-c\", \"printf '%s' \\\"$FIRELENS_CONFIG_CONTENT\\\" > /flightcontrol-firelens.conf && exec /entrypoint.sh\"], \"user\": \"0\", \"log_configuration\": {\"log_driver\": \"awslogs\", \"options\": {\"awslogs-group\": stack.output.log_group_name, \"awslogs-region\": stack.output.region, \"awslogs-stream-prefix\": stack.output.log_stream_prefix + \"/firelens\"}}, \"firelens_configuration\": {\"type\": \"fluentbit\", \"options\": {\"config-file-type\": \"file\", \"config-file-value\": \"/flightcontrol-firelens.conf\", \"enable-ecs-log-metadata\": string(module.input.firelens_ecs_metadata_enabled)}}}] : [{\"command\": (len(module.input.prebuilt_image_start_command) > 0 ? module.input.prebuilt_image_start_command : nil), \"cpu\": (module.input.capacity_provider == \"ec2\" ? int(float(module.input.task_cpu) * 1024) : int(float(module.input.fargate_size.vcpu) * 1024)), \"environment\": ([{name: \"PORT\", value: string(module.input.container_port)}] | concat(module.input.environment_variables != nil ? module.input.environment_variables : [])), \"essential\": true, \"image\": (module.input.build_type == \"prebuilt_image\" ? (deploy.input.image_ref contains \"sha256:\" ? module.input.image_repository + \"@\" + deploy.input.image_ref : module.input.image_repository + \":\" + deploy.input.image_ref) : (deploy.input.image_ref contains \"sha256:\" ? stack.output.ecr_repository_url + \"@\" + deploy.input.image_ref : stack.output.ecr_repository_url + \":\" + deploy.input.image_ref)), \"linux_parameters\": {\"init_process_enabled\": true}, \"log_configuration\": {\"log_driver\": \"awslogs\", \"options\": {\"awslogs-group\": stack.output.log_group_name, \"awslogs-region\": stack.output.region, \"awslogs-stream-prefix\": stack.output.log_stream_prefix}}, \"memory\": (module.input.capacity_provider == \"ec2\" ? int(float(module.input.task_memory) * 1024) : int(float(module.input.fargate_size.memory_gb) * 1024)), \"name\": (stack.output.container_name), \"port_mappings\": [{\"app_protocol\": \"http\", \"container_port\": (module.input.container_port), \"protocol\": \"tcp\"}], \"readonly_root_filesystem\": false, \"repository_credentials\": (module.input.image_registry_credentials_secret_arn ? {credentials_parameter: module.input.image_registry_credentials_secret_arn} : nil), \"secrets\": (module.input.secrets), \"stop_timeout\": 30}]) | concat(module.input.sidecars ? module.input.sidecars : []) >>"
     cpu: '<< string(module.input.capacity_provider == "ec2" ? int(float(module.input.task_cpu) * 1024) : int(float(module.input.fargate_size.vcpu) * 1024)) >>'
@@
     show_when:
       build_type: nixpacks
     type: string_array
+  - id: section_deployment
+    label: Deployment
+    type: section
+  - default: rolling
+    description: Choose how traffic moves from the current deployment to the new deployment.
+    id: deployment_strategy
+    label: Deployment strategy
+    required: true
+    type: string
+    values:
+      - des
... diff truncated ...

@mabadir mabadir merged commit e3a3d0d into main Jun 19, 2026
6 checks passed
@mabadir mabadir changed the title Fix ECS web module publishing schema Fix ECS module publishing schema fields Jun 19, 2026
Comment on lines +6 to 7
version: 0.6.1
description: Add native ECS blue/green, linear, and canary deployments with per-deploy strategy controls, manual approval gates, standby validation traffic, production/alternate target groups, ALB group stickiness guidance, ECS infrastructure role, and load-balancer advanced configuration outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The release.description was not updated to describe the 0.6.1 changes. Per the AGENTS.md guidelines, release.description should summarize the publishable change for the new version, not carry forward the 0.6.0 feature narrative. The current text describes the blue/green/canary features added in 0.6.0; the 0.6.1 patch fixes the publishing schema (item_title and singular ecs_service_arn).

Suggested change
version: 0.6.1
description: Add native ECS blue/green, linear, and canary deployments with per-deploy strategy controls, manual approval gates, standby validation traffic, production/alternate target groups, ALB group stickiness guidance, ECS infrastructure role, and load-balancer advanced configuration outputs.
version: 0.6.1
description: Fix publishing schema by replacing unsupported item_title_field with item_title.template and updating ecs_service_arn to the singular form required by the latest ECS deploy schema.
Prompt To Fix With AI
This is a comment left during a code review.
Path: compute/ecs_service/rvn-ecs-web-definition.yml
Line: 6-7

Comment:
The `release.description` was not updated to describe the 0.6.1 changes. Per the AGENTS.md guidelines, `release.description` should summarize the publishable change for the new version, not carry forward the 0.6.0 feature narrative. The current text describes the blue/green/canary features added in 0.6.0; the 0.6.1 patch fixes the publishing schema (`item_title` and singular `ecs_service_arn`).

```suggestion
  version: 0.6.1
  description: Fix publishing schema by replacing unsupported item_title_field with item_title.template and updating ecs_service_arn to the singular form required by the latest ECS deploy schema.
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants