add ecs web pre & post deploy commands#20
Merged
Merged
Conversation
Ravion Module Publish PlanDry run only. No Ravion API mutations were made.
Diffsrvn-ecs-web 0.3.0 -> 0.4.0--- remote
+++ compiled
placeholder: sha256:... or latest or <run-id>-nixpacks
required: true
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 >>'
task_definition:
container_definitions: "<< (module.input.firelens_enabled ? [{\"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)}}}] : [{\"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)) >>'
@@
- name: DATABASE_URL
valueFrom: arn:aws:ssm:...
type: array
+ - description: Optional one-off commands that run in ECS before or after each deployment, using the same task image, roles, networking, and environment as the web container.
+ id: section_deploy_commands
+ label: Pre and post deploy
+ type: section
+ - default: false
+ description: Run a one-off ECS task before updating the ECS service.
+ id: pre_deploy_enabled
+ label: Run pre-deploy command
+ type: boolean
+ - add_button_label: Add cmd segment
+ default: []
+ description: Command arguments to run before updating the ECS service. For shell behavior, use `/bin/sh`, `-lc`, and your command string as separate arguments.
+ id: pre_deploy_command
+ label: Pre-deploy command
+ placeholder: npm
+ required: true
+ show_when:
+ pre_deploy_enabled: true
+ type: string_array
+ - collapsible: true
+ default: []
+ description: Additional environment variables for the pre-deploy task. Runtime environment variables and secrets are already inherited from the app container.
+ id: pre_deploy_environment_variables
+ label: Pre-deploy environment variables
+ placeholder: |-
+ - name: MIGRATION_MODE
+ value: online
+ required: false
+ show_when:
+ pre_deploy_enabled: true
+ type: array
+ - collapsible: true
+ description: Optional CPU units for the pre-deploy task. Leave blank to use the app task CPU setting.
+ id: pre_deploy_cpu
+ label: Pre-deploy CPU units
+ min: 1
+ required: false
+ show_when:
+ pre_deploy_enabled: true
+ type: number
+ - collapsible: true
+ description: Optional memory in MiB for the pre-deploy task. Leave blank to use the app task memory setting.
+ id: pre_deploy_memory
+ label: Pre-deploy memory (MiB)
+ min: 1
+ required: false
+ show_when:
+ pre_deploy_enabled: true
+ type: number
+ - collapsible: true
+ description: Optional ephemeral storage size for the pre-deploy task. Leave blank to use the task definition default.
+ id: pre_deploy_ephemeral_storage_size_gib
+ label: Pre-deploy ephemeral storage (GiB)
+ max: 200
+ min: 21
+ required: false
+ show_when:
+ pre_deploy_enabled: true
+ type: number
+ - collapsible: true
+ default: 1800
+ description: Maximum time to wait for the pre-deploy task to finish.
+ id: pre_deploy_timeout
+ label: Pre-deploy timeout (secs)
+ min: 1
+ show_when:
+
... diff truncated ... |
Member
Author
|
@greptile |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Greptile Summary
This PR adds optional pre-deploy and post-deploy ECS task hooks to the
rvn-ecs-webmodule (v0.3.0 → 0.4.0). When enabled, each hook runs a one-off ECS task using the same image, task definition, roles, networking, and capacity provider strategy as the web service.pre_deployandpost_deployexpressions that construct the full RunTask override object (container command, CPU/memory fallback to the app task values, network config, capacity provider strategy) or returnnilwhen disabled or the command is empty.Confidence Score: 4/5
The pre/post deploy hooks are self-contained additions; existing behaviour is unchanged and the new code paths are guarded by both the enable toggle and a command-length check.
CPU/memory fallback logic, capacity provider strategy, and network configuration in the new pre_deploy/post_deploy output expressions all mirror the main task definition correctly. The one minor inconsistency is that pre_deploy_environment_variables and post_deploy_environment_variables are passed to the container override without the nil-guard used consistently elsewhere for optional array inputs.
compute/ecs_service/rvn-ecs-web-definition.yml — specifically the container override environment field for both hook expressions (lines 1515 and 1536).
Important Files Changed
Sequence Diagram
sequenceDiagram participant FC as Flightcontrol participant ECS as ECS RunTask (pre_deploy) participant SVC as ECS UpdateService participant ECS2 as ECS RunTask (post_deploy) FC->>ECS: "RunTask (pre_deploy_enabled && command.len > 0)" ECS-->>FC: task exits (success / failure) Note over FC,ECS: waits up to pre_deploy_timeout (default 1800s) FC->>SVC: UpdateService with new task definition SVC-->>FC: deployment stabilises FC->>ECS2: "RunTask (post_deploy_enabled && command.len > 0)" ECS2-->>FC: task exits (success / failure) Note over FC,ECS2: waits up to post_deploy_timeout (default 1800s)Prompt To Fix All With AI
Reviews (2): Last reviewed commit: "add ecs web pre & post deploy commands" | Re-trigger Greptile