At Pavilion, we deploy our application on AWS Elastic Container Service (ECS) using Github Actions. In addition to managing our web services and background tasks, we run periodic long-running processes using ECS Scheduled Tasks. These Scheduled Tasks allow us to start ECS containers on a predefined schedule to run specific commands, then shut them down when the tasks are complete.
ECS Scheduled Tasks use cron-like schedules to start ECS containers that execute specific commands and shut down upon completion. These rely on two AWS concepts: CloudWatch Event Rules, which define the schedule, and CloudWatch Event Targets, which specify the ECS task definition and number of tasks to run. Critically, Event Targets point to a specific version of a task definition, not the latest. When deploying new versions of a task definition, these Event Targets don’t update automatically and continue using outdated configurations. For a team like ours that deploys continuously, manually updating Event Targets for each Scheduled Task is error-prone and impractical.
To ensure Scheduled Tasks always run the latest task definition, we needed a way to automatically update Event Targets whenever we deploy. Finding no existing solution, we created an open-source GitHub Action: aws-update-cloudwatch-ecs-event-target. This action takes a list of Event Rule names and updates their Event Targets to the latest version of the given Task Definition.
This example updates the Event Targets for the rules rule-1, rule-2, and rule-3 to the latest version of the scheduled-tasks task definition:
- name: Update task definitions
uses: coprocure.us/aws-update-cloudwatch-ecs-event-target@v1.0
with:
task-definition-family: scheduled-tasks
rules: |-
rule-1
rule-2
rule-3
Here’s an example of how to integrate the aws-update-cloudwatch-ecs-event-target action into a full ECS deployment pipeline:
deploy:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build, tag, and push image to Amazon ECR
id: build-image
uses: docker/build-push-action@v1
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ./path/to/task-definition.json
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: my-service
cluster: my-cluster
- name: Update Scheduled Task Definitions
uses: coprocure/aws-update-cloudwatch-ecs-event-target@v0.2
with:
task-definition-family: my-task-definition
rule-names: |-
rule-1
rule-2
The deploy job builds a docker image, fills in your task definition, and updates the event rules for your scheduled tasks to the latest version. Now, you can ensure your Scheduled Tasks are running the same code as the rest of your application, automatically!
Interested in solving tricky technical problems to helping local governments deliver better public services? Apply to join Pavilion!