Why use ECS for flow run execution?
ECS (Elastic Container Service) tasks are a good option for executing Prefect flow runs for several reasons:- Scalability: ECS scales your infrastructure in response to demand, effectively managing Prefect flow runs. ECS automatically administers container distribution across multiple instances based on demand.
- Flexibility: ECS lets you choose between AWS Fargate and Amazon EC2 for container operation. Fargate abstracts the underlying infrastructure, while EC2 has faster job start times and offers additional control over instance management and configuration.
- AWS Integration: Easily connect with other AWS services, such as AWS IAM and CloudWatch.
- Containerization: ECS supports Docker containers and offers managed execution. Containerization encourages reproducible deployments.
ECS flow run execution
Prefect enables remote flow execution via workers and work pools. To learn more about these concepts please see our deployment docs. For details on how workers and work pools are implemented for ECS, see the diagram below.ECS and Prefect
ECS tasks != Prefect tasksAn ECS task is not the same thing as a Prefect task.ECS tasks are groupings of containers that run within an ECS Cluster. An ECS task’s behavior is determined by its task definition.
ecs
typed work pool are executed as ECS tasks. Only Prefect ECS workers can poll an ecs
typed work pool.
When the ECS worker receives a scheduled flow run from the ECS work pool it is polling, it spins up the specified infrastructure on AWS ECS. The worker knows to build an ECS task definition for each flow run based on the configuration specified in the work pool.
Once the flow run completes, the ECS containers of the cluster are spun down to a single container that continues to run the Prefect worker. This worker continues polling for work from the Prefect work pool.
If you specify a task definition ARN (Amazon Resource Name) in the work pool, the worker will use that ARN when spinning up the ECS Task, rather than creating a task definition from the fields supplied in the work pool configuration.
You can use either EC2 or Fargate as the capacity provider. Fargate simplifies initiation, but lengthens infrastructure setup time for each flow run. Using EC2 for the ECS cluster can reduce setup time. In this example, we will show how to use Fargate.
If you prefer infrastructure as code check out this Terraform module to provision an ECS cluster with a worker.
Prerequisites
- An AWS account with permissions to create ECS services and IAM roles.
- The AWS CLI installed on your local machine. You can download it from the AWS website.
- An ECS Cluster to host both the worker and the flow runs it submits. This guide uses the default cluster. To create your own follow this guide.
- A VPC configured for your ECS tasks. This guide uses the default VPC.
- Prefect Cloud account or Prefect self-managed instance.
Step 1: Set up an ECS work pool
Before setting up the worker, create a work pool of type ECS for the worker to pull work from. If doing so from the CLI, be sure to authenticate with Prefect Cloud or run a local Prefect server instance. Create a work pool from the CLI:
Step 2: Start a Prefect worker in your ECS cluster
First start by creating the IAM role required in order for your worker and flows to run. The sample flow in this guide doesn’t interact with many other AWS services, so you will only be creating one role,taskExecutionRole
. To create an IAM role for the ECS task using the AWS CLI, follow these steps:
1. Create a trust policy
The trust policy will specify that the ECS service containing the Prefect worker will be able to assume the role required for calling other AWS services. Save this policy to a file, such asecs-trust-policy.json
:
2. Create the IAM roles
Use theaws iam create-role
command to create the roles that you will be using. For this guide, the ecsTaskExecutionRole
will be used by the worker to start ECS tasks, and will also be the role assigned to the ECS tasks running your Prefect flows.
3. Attach the policy to the role
For this guide the ECS worker will require permissions to pull images from ECR and publish logs to CloudWatch. Amazon has a managed policy namedAmazonECSTaskExecutionRolePolicy
that grants the permissions necessary for starting ECS tasks. See here for other common execution role permissions. Attach this policy to your task execution role:
--role-name
and --policy-arn
with the actual role name and policy Amazon Resource Name (ARN) you want to use.
Step 3: Creating an ECS worker service
1. Launch an ECS Service to host the worker
Next, create an ECS task definition that specifies the Docker image for the Prefect worker, the resources it requires, and the command it should run. In this example, the command to start the worker isprefect worker start --pool my-ecs-pool
.
Create a JSON file with the following contents:
-
Use
prefect config view
to view thePREFECT_API_URL
for your current Prefect profile. Use this to replace<prefect-api-url>
. -
For the
PREFECT_API_KEY
, if you are on a paid plan you can create a service account for the worker. If your are on a free plan, you can pass a user’s API key. -
Replace both instances of
<ecs-task-role-arn>
with the ARN of the IAM role you created in Step 2. You can grab this by running:
- Notice that the CPU and Memory allocations are relatively small. The worker’s main responsibility is to submit work through API calls to AWS, not to execute your Prefect flow code.
To avoid hardcoding your API key into the task definition JSON see how to add sensitive data using AWS secrets manager to the container definition.
2. Register the task definition
Before creating a service, you first need to register a task definition. You can do that using theregister-task-definition
command in the AWS CLI. Here is an example:
task-definition.json
with the name of your JSON file.
3. Create an ECS service to host your worker
Finally, create a service that will manage your Prefect worker: Open a terminal window and run the following command to create an ECS Fargate service:- Replace
<ecs-cluster>
with the name of your ECS cluster. - Replace
<task-definition-arn>
with the ARN of the task definition you just registered. - Replace
<subnet-ids>
with a comma-separated list of your VPC subnet IDs. Ensure that these subnets are aligned with the vpc specified on the work pool in step 1. You can view subnet ids with the following command:aws ec2 describe-subnets --filter Name=<vpc-id>
- Replace
<security-group-ids>
with a comma-separated list of your VPC security group IDs.
Step 4: Pick up a flow run with your new worker
This guide uses ECR to store a Docker image containing your flow code. To do this, we will write a flow, then deploy it using build and push steps that copy flow code into a Docker image and push that image to an ECR repository.1. Write a simple test flow
my_flow.py
2. Create an ECR repository
Use the following AWS CLI command to create an ECR repository. The name you choose for your repository will be reused in the next step when defining your Prefect deployment.3. Create a prefect.yaml
file
To have Prefect build your image when deploying your flow create a prefect.yaml
file with the following specification:
4. Deploy the flow to the Prefect Cloud or your self-managed server instance, specifying the ECS work pool when prompted
5. Find the deployment in the UI and click the Quick Run button!
Optional next steps
-
Now that you are confident your ECS worker is healthy, you can experiment with different work pool configurations.
- Do your flow runs require higher
CPU
? - Would an EC2
Launch Type
speed up your flow run execution?
- Do your flow runs require higher