🔑 Key points
- Understanding ECS and its core components.
- Manually deploying containers using AWS Fargate.
- Exposing containers through an Application Load Balancer (ALB).
- Configuring DNS records to point to an ECS service.
- Deploying the JWT Pizza Service to ECS.
📖 Deeper dive reading: What is Amazon ECS?
Amazon Elastic Container Service (ECS) provides the orchestration necessary to deploy and manage Docker containers. Once you have uploaded your container image to Amazon ECR, you can create an ECS cluster and service to run your container on either EC2 instances or AWS Fargate.
If you configure ECS to deploy to EC2 instances, you are responsible for launching, scaling, and managing the underlying virtual machines. Alternatively, if you use AWS Fargate, AWS manages the infrastructure for you, automatically handling the provisioning and scaling of the resources required by your containers. For this course, we will use AWS Fargate to simplify infrastructure management.
The core components of ECS are:
- Task Definition: A blueprint that defines the container image to execute, the required memory and vCPU, environment variables, and health check parameters. You can define multiple containers within a single task definition if they are highly coupled (e.g., a main application and a "sidecar" logging container).
- Task: The instantiation of a task definition. A running task is the ECS equivalent of a running Docker container, including additional metadata regarding its health and network status.
- Scheduler: The logic responsible for placing tasks on the cluster, ensuring the desired number of tasks are running, and rescheduling tasks if they fail.
- Service: A configuration that maintains a specified number of simultaneous instances of a task definition in an ECS cluster. If a task fails or stops, the service scheduler launches another instance.
- Cluster: A logical grouping of tasks or services. Clusters can span multiple Availability Zones (AZs) to ensure the application is resilient to localized infrastructure failures.
Important
Ensure you are using the us-east-1 (N. Virginia) AWS region for all work in this course.
Before running Docker containers in ECS, you must define the permissions the service and the containers will have. Two specific IAM roles control these permissions:
- Task Execution Role: Grants the ECS agent permission to make AWS API calls on your behalf. This includes pulling images from ECR and sending container logs to CloudWatch.
- Task Role: Defines the permissions for the application inside the container. This includes rights to access resources like S3 buckets or DynamoDB tables.
We will not define a Task Role immediately, but you may need one later if your application needs to connect to other AWS services (like RDS or S3) without using hardcoded credentials.
To allow ECS to start tasks and pull images, you must create a Task Execution Role.
-
Sign in to the AWS Management Console and navigate to the IAM (Identity and Access Management) service.
-
Select Roles from the left navigation panel.
-
Click Create role.
-
Select AWS service as the Trusted entity type.
-
Under the Use case dropdown, select Elastic Container Service, then select the Elastic Container Service Task radio button.
-
Click Next.
-
Search for and select the policy named
AmazonECSTaskExecutionRolePolicy. This policy provides the necessary permissions to run ECS tasks. Click Next. -
Set the Role name to
jwt-pizza-ecs. -
Click Create role.
Next, define the task that will run the JWT Pizza backend.
- Navigate to the Elastic Container Service (ECS) service in the AWS Console.
- Select Task definitions from the left navigation panel.
- Click Create new task definition and choose Create new task definition from the dropdown.
- Set the Task definition family name to
jwt-pizza-service. - Under Infrastructure requirements:
- Ensure the Launch type is set to AWS Fargate.
- Set the Operating system/Architecture to Linux/ARM64.
- Select .5 vCPU for CPU and 1 GB for Memory. (Low settings help minimize AWS costs).
- Leave Task role blank for now.
- Set the Task execution role to the
jwt-pizza-ecsrole you created earlier.
- Under Container - 1:
- Set the Name to
jwt-pizza-service. - Set the Image URI to the URI generated when you pushed your image to ECR. It should look like this:
Ensure you include the
1234567890.dkr.ecr.us-east-1.amazonaws.com/jwt-pizza-service:latest:latesttag. - Set the Container port to
80with the protocol set to HTTP.
- Set the Name to
- Click Create.
A cluster is the logical group where your service will live.
- In the ECS console, select Clusters from the left navigation panel.
- Click Create cluster.
- Set the Cluster name to
jwt-pizza-service. - Under Infrastructure, ensure AWS Fargate (serverless) is selected.
- Click Create.
Wait for the cluster status to change from Provisioning to Active.
The service manages the deployment and scaling of your tasks. When you create the service, ECS will immediately attempt to launch the tasks.
-
In the ECS console, select Clusters and click on the
jwt-pizza-servicecluster. -
Under the Services tab, click Create.
-
Under Deployment configuration:
- Select Service as the application type.
- Select
jwt-pizza-servicefrom the Family dropdown (under Task definition). - Set the Service name to
jwt-pizza-service. - Set Desired tasks to
1.
-
Under Networking:
- Select your VPC.
- Ensure at least two Subnets are selected (standard for high availability).
- Under Security group, click Select existing security group and choose the
jwt-pizza-servicesecurity group you created previously. Ensure it allows port 80 and/or 443. - Ensure Public IP is turned ON.
-
Under Load balancing:
-
Select Application Load Balancer.
-
For the Load balancer name, enter
jwt-pizza-service. -
Set the Container to load balance to
jwt-pizza-service 80:80. -
Listener: Create a new listener on port
443using protocol HTTPS. -
Certificate: Select the wildcard certificate you created in previous steps (ACM).
-
Target group: Create a new target group named
jwt-pizza-service.- Protocol: HTTP
- Health check path:
/api/docs(The ALB uses this to verify the container is responsive).
-
-
Click Create.
Deployment will take several minutes. You can monitor progress in the Service events tab or via the CloudFormation console.
To check if your container is running:
- Navigate to your ECS Cluster ->
jwt-pizza-serviceservice. - Click the Tasks tab.
- The Last status should eventually show Running.
If the task fails to start, click on the Task ID to view details. Check the Logs tab to see the application's console output, which is invaluable for debugging startup errors.
Once the service and load balancer are active, you can access the service via the ALB's DNS name.
- Navigate to the EC2 console.
- Select Load Balancers from the left menu.
- Select the
jwt-pizza-serviceload balancer. - Copy the DNS name.
Since we are using a self-signed or specific domain certificate, you may need to use the -k (insecure) flag with curl if the DNS name doesn't match the certificate exactly yet:
curl -k https://LOADBALANCER_DNSNAME_HERE
{"message":"welcome to JWT Pizza","version":"20240525.191742"}The final step is to map your custom domain to the load balancer so users can access the service via a friendly URL.
- Navigate to the Route 53 service in the AWS Console.
- Select Hosted zones and click on your domain name.
- Click Create record.
- Record name: Enter
pizza-service(creating the subdomainpizza-service.yourdomain.com). - Record type: Select CNAME.
- Value: Paste the DNS name of your Application Load Balancer.
- Click Create records.
Note
The subdomain must be exactly pizza-service for your project deliverables to be validated correctly.
Use the dig command to check if the DNS record has propagated:
dig pizza-service.yourdomainnamehere.com +noall +answerOnce propagated, you should see the CNAME pointing to the AWS load balancer. You can then navigate to https://pizza-service.yourdomainnamehere.com in your browser.
Deploy the JWT Pizza Service container by completing the following:
- Create IAM Roles: Set up the ECS Task Execution role.
- Define the Task: Create a task definition using your ECR image URI.
- Provision the Cluster: Create a Fargate cluster.
- Deploy the Service: Create an ECS service integrated with an Application Load Balancer and HTTPS.
- Configure DNS: Create a CNAME record in Route 53 pointing to your ALB.
{"id":"024757e7-e85c-4f79-97ac-bfd8c4772df8", "title":"AWS ECS", "type":"url-submission", "syncGrade":false, "autoGrade":false, "validateUrl":true, "gradingCriteria":"- The response is a JSON object with a message field that says 'welcome to JWT Pizza'" }
Submit the URL to your JWT Pizza service.
_Example: https://pizza-service.yourhostname.click_











