From 6cdab6b5e1ca2573fb593e5c1a3b225a5ff6d749 Mon Sep 17 00:00:00 2001 From: marius-mather Date: Wed, 17 Sep 2025 09:01:29 +1000 Subject: [PATCH 1/4] Increase CPU/memory for running another container --- deploy/aai_backend_deploy/aai_backend_deploy_stack.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/aai_backend_deploy/aai_backend_deploy_stack.py b/deploy/aai_backend_deploy/aai_backend_deploy_stack.py index bdd3cd41..afc6d92c 100644 --- a/deploy/aai_backend_deploy/aai_backend_deploy_stack.py +++ b/deploy/aai_backend_deploy/aai_backend_deploy_stack.py @@ -60,9 +60,9 @@ def __init__(self, scope: Construct, construct_id: str, config: dict, **kwargs) # Task definition for Fargate task_definition = ecs.FargateTaskDefinition(self, "AaiBackendTaskDef", - memory_limit_mib=1024, - cpu=512) - # Allow executing comands in the ECS container + memory_limit_mib=2048, + cpu=1024) + # Allow executing commands in the ECS container task_definition.task_role.add_managed_policy( iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMManagedInstanceCore") ) From e73d4a61c2b2dcb6251e5f438f0f8a4717fba5c8 Mon Sep 17 00:00:00 2001 From: marius-mather Date: Wed, 17 Sep 2025 09:11:09 +1000 Subject: [PATCH 2/4] Add a new container for the job scheduler (same image but different command) --- .../aai_backend_deploy_stack.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/deploy/aai_backend_deploy/aai_backend_deploy_stack.py b/deploy/aai_backend_deploy/aai_backend_deploy_stack.py index afc6d92c..2b19d1b3 100644 --- a/deploy/aai_backend_deploy/aai_backend_deploy_stack.py +++ b/deploy/aai_backend_deploy/aai_backend_deploy_stack.py @@ -85,6 +85,25 @@ def __init__(self, scope: Construct, construct_id: str, config: dict, **kwargs) }, logging=ecs.LogDrivers.aws_logs(stream_prefix="FastAPI"), ) + # Run the job scheduler as a separate container + task_definition.add_container( + "SchedulerContainer", + image=ecs.ContainerImage.from_ecr_repository( + ecr_repo, + tag="latest" + ), + # Override the default command to run the scheduler + command=["uv", "run", "python", "run_scheduler.py"], + environment={ + "FORCE_REDEPLOY": str(datetime.datetime.now()), + "DB_HOST": self.db_host, + }, + secrets={ + "DB_USER": ecs.Secret.from_secrets_manager(db_secret, field="username"), + "DB_PASSWORD": ecs.Secret.from_secrets_manager(db_secret, field="password"), + }, + logging=ecs.LogDrivers.aws_logs(stream_prefix="Scheduler"), + ) container.add_port_mappings( ecs.PortMapping(container_port=8000) From b2c30be89251930d966eca403df4548da53323bd Mon Sep 17 00:00:00 2001 From: marius-mather Date: Wed, 17 Sep 2025 09:12:05 +1000 Subject: [PATCH 3/4] Output ARNs for the service via CfnOutput --- deploy/aai_backend_deploy/aai_backend_deploy_stack.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deploy/aai_backend_deploy/aai_backend_deploy_stack.py b/deploy/aai_backend_deploy/aai_backend_deploy_stack.py index 2b19d1b3..bbce030b 100644 --- a/deploy/aai_backend_deploy/aai_backend_deploy_stack.py +++ b/deploy/aai_backend_deploy/aai_backend_deploy_stack.py @@ -131,4 +131,12 @@ def __init__(self, scope: Construct, construct_id: str, config: dict, **kwargs) service.target_group.configure_health_check(path="/", healthy_http_codes="200-399") + # Output relevant ARNs and IDs CfnOutput(self, "LoadBalancerDNS", value=service.load_balancer.load_balancer_dns_name) + CfnOutput(self, "ServiceArn", value=service.service.service_arn) + CfnOutput(self, "ServiceName", value=service.service.service_name) + CfnOutput(self, "ClusterArn", value=cluster.cluster_arn) + CfnOutput(self, "ClusterName", value=cluster.cluster_name) + CfnOutput(self, "TaskDefinitionArn", value=task_definition.task_definition_arn) + CfnOutput(self, "TaskDefinitionFamily", value=task_definition.family) + CfnOutput(self, "LoadBalancerArn", value=service.load_balancer.load_balancer_arn) From f48c9ff739039f5f46941cf4b19c5d84b8229950 Mon Sep 17 00:00:00 2001 From: marius-mather Date: Wed, 17 Sep 2025 10:04:04 +1000 Subject: [PATCH 4/4] Add info on scheduler to README --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index e2b49efb..12cf911f 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,20 @@ and run the migrations: uv run alembic upgrade head ``` +# Job scheduler + +We use the `apscheduler` library to schedule recurring jobs. Currently +this is used to synchronize user information from Auth0 to the AAI +database. You can run the job scheduler locally using: + +```shell +uv run python run_scheduler.py +``` + +Note that for small jobs that run on-demand, e.g. sending a notification email when a user +signs up, you can use FastAPI's built-in [background tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/) +within the FastAPI app, instead of using the dedicated job scheduler. + # Deployment Currently the service is deployed to AWS via the CDK scripts in `deploy/`, @@ -112,3 +126,8 @@ and updated on each commit to `main`. Secrets/configuration variables for the deployment are stored in the GitHub Secrets for the repository. + +The service deploys two containers (which both use the same image/Python environment): + +* The FastAPI app +* The `apscheduler` job scheduler