DEV Community

Cover image for a first look at aws fargate
anthony-campolo
anthony-campolo

Posted on

a first look at aws fargate

Fargate is an AWS service that allows you to run containers on ECS without managing servers or clusters of EC2 instances. It manages provisioning, configuring, and scaling clusters of virtual machines to run containers. This includes selecting the server type, deciding when to scale the clusters, and optimizing cluster packing.

When you run your tasks and services with the Fargate launch type you:

  • Package your application in containers
  • Specify the CPU and memory requirements
  • Define networking and IAM policies
  • Launch the application

Each Fargate task has its own isolation boundary and does not share the underlying kernel, CPU resources, memory resources, or elastic network interface with another task.

Outline

  • Example task definition
    • Container Definition
    • Network Mode
  • Setup and verify the ECS CLI using PGP signatures
    • Install script
    • Install GnuPG with Homebrew
    • Create a local file with the ECS PGP public key
    • Import the ECS PGP public key with gpg --import
    • Download the ECS CLI signatures
    • Verify the signature with gpg --verify
    • Apply execute permissions to the binary
    • Verify that the CLI is working properly by checking the version number
  • Configure AWS credentials
    • Create project directory
    • Specify the task execution IAM role in task-execution-assume-role.json
    • Create the task execution role with aws iam create-role
    • Attach the task execution role policy with aws iam attach-role-policy
    • Configure the ECS CLI with ecs-cli configure
    • Create a CLI profile with ecs-cli configure profile
  • Create ECS cluster
    • Create cluster with ecs-cli up
    • Retrieve the VPC's default security group ID with aws ec2 describe-security-groups
    • Add a security group rule with aws ec2 authorize-security-group-ingress
  • Deploy Docker container to the cluster
    • Create a compose file called docker-compose.yml
    • Create a parameters file called ecs-params.yml
    • Deploy the compose file with ecs-cli compose service up
    • View the running containers with ecs-cli compose service ps
    • View your Web Application
  • Clean Up
    • Delete the service with ecs-cli compose service down
    • Take down the cluster with ecs-cli down

Example task definition

This task definition sets up a web server using the Fargate launch type and an Apache httpd:2.4 image.

{
   "containerDefinitions": [ 
      { 
         "command": [
            "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
         ],
         "entryPoint": [
            "sh",
            "-c"
         ],
         "essential": true,
         "image": "httpd:2.4",
         "logConfiguration": { 
            "logDriver": "awslogs",
            "options": { 
               "awslogs-group" : "/ecs/fargate-task-definition",
               "awslogs-region": "us-east-1",
               "awslogs-stream-prefix": "ecs"
            }
         },
         "name": "sample-fargate-app",
         "portMappings": [ 
            { 
               "containerPort": 80,
               "hostPort": 80,
               "protocol": "tcp"
            }
         ]
      }
   ],
   "cpu": "256",
   "executionRoleArn": "arn:aws:iam::012345678910:role/ecsTaskExecutionRole",
   "family": "fargate-task-definition",
   "memory": "512",
   "networkMode": "awsvpc",
   "requiresCompatibilities": [ 
       "FARGATE" 
    ]
}
Enter fullscreen mode Exit fullscreen mode

Container Definition

The container is named sample-fargate-app and includes log configuration and port mappings. It sets the entry point to sh -c and runs a shell command that prints an HTML document to a file called index.html. This is placed inside the usr/local/apache2/htdocs/ directory.

Network Mode

Lastly, the Apache HyperText Transfer Protocol (HTTP) server program, httpd, is started with port 80 open and the network mode set to awsvpc. This means the task is allocated the same networking properties as Amazon EC2 instances which includes having its own elastic network interface (ENI) and a primary private IPv4 address.

Setup and verify the ECS CLI using PGP signatures

Instructions for downloading the Amazon ECS CLI binary will be different for each operating system. The instructions in this article are for macOS. See the AWS docs to find installation instructions for Windows or Linux.

Install script

sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest
Enter fullscreen mode Exit fullscreen mode

Install GnuPG with Homebrew

The Amazon ECS CLI executables are cryptographically signed using PGP signatures. The PGP signatures can be used to verify the validity of the Amazon ECS CLI executable.

To verify the signatures download and install GnuPG with Homebrew.

brew install gnupg
Enter fullscreen mode Exit fullscreen mode

Create a local file with the ECS PGP public key

touch aws-ecs-pgp
Enter fullscreen mode Exit fullscreen mode

See Step 2: Verify the Amazon ECS CLI using PGP signatures for the public key block. The details of the Amazon ECS PGP public key for reference:

Key ID: BCE9D9A42D51784F
Type: RSA
Size: 4096/4096
Expires: Never
User ID: Amazon ECS
Key fingerprint: F34C 3DDA E729 26B0 79BE AEC6 BCE9 D9A4 2D51 784F
Enter fullscreen mode Exit fullscreen mode

Import the ECS PGP public key with gpg --import

gpg --import aws-ecs-pgp
Enter fullscreen mode Exit fullscreen mode

Download the ECS CLI signatures

The signatures are ASCII detached PGP signatures stored in files with the extension .asc. The signatures file has the same name as its corresponding executable, with .asc appended.

curl -Lo ecs-cli.asc https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest.asc
Enter fullscreen mode Exit fullscreen mode

Verify the signature with gpg --verify

gpg --verify ecs-cli.asc /usr/local/bin/ecs-cli
Enter fullscreen mode Exit fullscreen mode

The output will include a warning that there is no chain of trust between your personal PGP key (if you have one) and the Amazon ECS PGP key.

Signature made Tue Apr 3 13:29:30 2018 PDT using RSA key DE3CBD61ADAF8B8E

Good signature from "Amazon ECS <ecs-security@amazon.com>" [unknown]

WARNING: This key is not certified with a trusted signature!

There is no indication that the signature belongs to the owner.

Primary key fingerprint: F34C 3DDA E729 26B0 79BE AEC6 BCE9 D9A4 2D51 784F
Subkey fingerprint: EB3D F841 E2C9 212A 2BD4 2232 DE3C BD61 ADAF 8B8E
Enter fullscreen mode Exit fullscreen mode

Apply execute permissions to the binary

sudo chmod +x /usr/local/bin/ecs-cli
Enter fullscreen mode Exit fullscreen mode

Verify that the CLI is working properly by checking the version number

ecs-cli --version
Enter fullscreen mode Exit fullscreen mode

Output:

ecs-cli version 1.21.0 (bb0b8f0)
Enter fullscreen mode Exit fullscreen mode

Configure AWS credentials

You must configure the ECS CLI with your AWS credentials, an AWS Region, and an Amazon ECS cluster name before you can use it. This tutorial shows you how to set up a cluster and deploy a service with tasks using the Fargate launch type.

Create project directory

mkdir ajcwebdev-fargate
cd ajcwebdev-fargate
Enter fullscreen mode Exit fullscreen mode

Specify the task execution IAM role in task-execution-assume-role.json

The Amazon ECS container agent makes calls to AWS APIs on your behalf, so it requires an IAM policy and role for the service to know that the agent belongs to you. An IAM role is an IAM identity that you can create in your account that has specific permissions.

Create a file named task-execution-assume-role.json.

touch task-execution-assume-role.json
Enter fullscreen mode Exit fullscreen mode

This IAM role is referred to as a task execution IAM role. Add the following contents to the file.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Create the task execution role with aws iam create-role

An IAM role is similar to an IAM user, in that it is an AWS identity with permission policies that determine what the identity can and cannot do in AWS. However, instead of being uniquely associated with one person, a role is intended to be assumable by anyone who needs it.

aws iam create-role \
  --region us-west-2 \
  --role-name ecsTaskExecutionRole \
  --assume-role-policy-document file://task-execution-assume-role.json
Enter fullscreen mode Exit fullscreen mode

Output:

{
  "Role": {
    "Path": "/",
    "RoleName": "ecsTaskExecutionRole",
    "RoleId": "xxxx",
    "Arn": "arn:aws:iam::xxxx:role/ecsTaskExecutionRole",
    "CreateDate": "2021-09-04T06:11:29+00:00",
    "AssumeRolePolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "Service": "ecs-tasks.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

When you assume a role it provides you with temporary security credentials for your role session. You can see this role in the IAM console.

01-iam-role-in-console

Attach the task execution role policy with aws iam attach-role-policy

A role does not have standard long-term credentials such as a password or access keys associated with it. Instead we will attach the role policy created in the previous section.

aws iam attach-role-policy \
  --region us-west-2 \
  --role-name ecsTaskExecutionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Enter fullscreen mode Exit fullscreen mode

Back in your console you will see a policy name under the Permissions tab.

02-role-permissions-policies

Click the name of the policy to see more details.

03-role-policy-summary

Configure the ECS CLI with ecs-cli configure

The Amazon ECS CLI requires credentials in order to make API requests on your behalf. It can pull credentials from environment variables, an AWS profile, or an Amazon ECS profile.

ecs-cli configure \
  --cluster tutorial \
  --default-launch-type FARGATE \
  --config-name tutorial \
  --region us-west-2
Enter fullscreen mode Exit fullscreen mode

Output:

Saved ECS CLI cluster configuration tutorial. 
Enter fullscreen mode Exit fullscreen mode

This creates a cluster configuration defining the AWS region to use, resource creation prefixes, and the cluster name to use with the ECS CLI.

Create a CLI profile with ecs-cli configure profile

The Amazon ECS CLI supports the configuring of multiple sets of AWS credentials as named profiles using the ecs-cli configure profile command. Use your AWS access key and secret key found on My Security Credentials.

ecs-cli configure profile \
  --access-key AWS_ACCESS_KEY_ID \
  --secret-key AWS_SECRET_ACCESS_KEY \
  --profile-name tutorial-profile
Enter fullscreen mode Exit fullscreen mode

Output:

Saved ECS CLI profile configuration tutorial-profile.
Enter fullscreen mode Exit fullscreen mode

Create ECS cluster

An Amazon ECS cluster is a logical grouping of tasks or services. Your tasks and services are run on infrastructure that is registered to a cluster.

Create cluster with ecs-cli up

Because you specified Fargate as your default launch type in the cluster configuration, this command creates an empty cluster and a VPC configured with two public subnets.

ecs-cli up \
  --cluster-config tutorial \
  --ecs-profile tutorial-profile
Enter fullscreen mode Exit fullscreen mode

Output:

Created cluster
cluster=tutorial
region=us-west-2

Waiting for your cluster resources to be created...
Cloudformation stack status
stackStatus=CREATE_IN_PROGRESS

VPC created: vpc-02cbd07d59e782a33

Subnet created: subnet-0a796d4c4ff23c7f2
Subnet created: subnet-0aad68512ca7b0916

Cluster creation succeeded.
Enter fullscreen mode Exit fullscreen mode

This may take a few minutes to complete as your resources are created. Once the cluster is created you can find it on the ECS console.

04-ecs-clusters

Each cluster is region specific, so if you do not see your cluster in the console double check the region at the top right of the AWS console. In this example the cluster is in us-west-2. Click the name of the cluster to see more details.

05-tutorial-cluster-overview

You can find more VPC details on the VPC console under the Your VPCs and Subnets tabs.

06-vpc-details

07-vpc-subnets

Retrieve the VPC's default security group ID with aws ec2 describe-security-groups

Use the VPC ID from the previous output.

aws ec2 describe-security-groups \
  --filters Name=vpc-id,Values=VPC_ID \
  --region us-west-2
Enter fullscreen mode Exit fullscreen mode

This will print out a JSON object with our GroupId. Save this value for future reference.

{
  "SecurityGroups": [
    {
      "Description": "default VPC security group",
      "GroupName": "default",
      "IpPermissions": [
        {
          "IpProtocol": "-1",
          "IpRanges": [],
          "Ipv6Ranges": [],
          "PrefixListIds": [],
          "UserIdGroupPairs": [
            {
              "GroupId": "sg-01c0bfefb23e4e94d",
              "UserId": "xxxx"
            }
          ]
        }
      ],
      "OwnerId": "xxxx",
      "GroupId": "sg-01c0bfefb23e4e94d",
      "IpPermissionsEgress": [
        {
          "IpProtocol": "-1",
          "IpRanges": [
            {
              "CidrIp": "0.0.0.0/0"
            }
          ],
          "Ipv6Ranges": [],
          "PrefixListIds": [],
          "UserIdGroupPairs": []
        }
      ],
      "VpcId": "vpc-02cbd07d59e782a33"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

You can also find this information under the Security Groups tab.

08-vpc-security-groups

Add a security group rule with aws ec2 authorize-security-group-ingress

To allow inbound access on port 80, use the security group ID from the previous output.

aws ec2 authorize-security-group-ingress \
  --group-id SECURITY_GROUP_ID \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0 \
  --region us-west-2
Enter fullscreen mode Exit fullscreen mode

Deploy Docker container to the cluster

Compose is a tool for defining and running multi-container Docker applications.

Create a compose file called docker-compose.yml

After configuring your application’s services with a YAML file, you can create and start all your services with a single command.

touch docker-compose.yml
Enter fullscreen mode Exit fullscreen mode

The Docker compose file will create a PHP web application. The web container exposes port 80 for inbound traffic to the web server. It also configures container logs to go to the CloudWatch log group created earlier.

# docker-compose.yml

version: '3'
services:
  web:
    image: amazon/amazon-ecs-sample
    ports:
      - "80:80"
    logging:
      driver: awslogs
      options: 
        awslogs-group: tutorial
        awslogs-region: us-west-2
        awslogs-stream-prefix: web
Enter fullscreen mode Exit fullscreen mode

Create a parameters file called ecs-params.yml

In addition to the Docker compose information, there are some parameters specific to ECS that you must specify for the service.

touch ecs-params.yml
Enter fullscreen mode Exit fullscreen mode

Enter the following content and include the VPC, subnet, and security group IDs from the previous steps.

# ecs-params.yml

version: 1
task_definition:
  task_execution_role: ecsTaskExecutionRole
  ecs_network_mode: awsvpc
  task_size:
    mem_limit: 0.5GB
    cpu_limit: 256
run_params:
  network_configuration:
    awsvpc_configuration:
      subnets:
        - "subnet ID 1"
        - "subnet ID 2"
      security_groups:
        - "security group ID"
      assign_public_ip: ENABLED
Enter fullscreen mode Exit fullscreen mode

Deploy the compose file with ecs-cli compose service up

After you create the compose file, you can deploy it to your cluster. The command looks for files called docker-compose.yml and ecs-params.yml in the current directory.

ecs-cli compose --project-name tutorial service up \
  --create-log-groups \
  --cluster-config tutorial \
  --ecs-profile tutorial-profile
Enter fullscreen mode Exit fullscreen mode

Output:

Using ECS task definition
TaskDefinition="tutorial:1"

Created Log Group tutorial in us-west-2  
Auto-enabling ECS Managed Tags 

(service tutorial) has started 1 tasks:
(task 35aca78fc077428b92cde359beb50acb). 
timestamp="2021-09-04 06:26:08 +0000 UTC"

Service status
desiredCount=1
runningCount=1
serviceName=tutorial

ECS Service has reached a stable state
desiredCount=1
runningCount=1
serviceName=tutorial

Created an ECS service
service=tutorial
taskDefinition="tutorial:1"
Enter fullscreen mode Exit fullscreen mode

By default, the resources created by this command have the current directory in their titles, but you can override that with the --project-name option. The --create-log-groups option creates the CloudWatch log groups for the container logs.

View the running containers with ecs-cli compose service ps

After you deploy the compose file, you can view the containers that are running in the service by returning to the ECS console.

09-task-definition-status

Click the network tab to see your public IP address.

10-task-definition-network

Alternatively, you can run the following command to view the running containers.

ecs-cli compose --project-name tutorial service ps \
  --cluster-config tutorial \
  --ecs-profile tutorial-profile
Enter fullscreen mode Exit fullscreen mode

Output:

Name
tutorial/35aca78fc077428b92cde359beb50acb/web

State
RUNNING

Ports
34.223.226.89:80->80/tcp

TaskDefinition 
tutorial:1

Health
UNKNOWN
Enter fullscreen mode Exit fullscreen mode

View your Web Application

Open the IP address in your browser to see a PHP web application.

11-deployed-php-application

Clean Up

When you are done with this tutorial, you should clean up your resources so they do not incur any more charges.

Delete the service with ecs-cli compose service down

Stop the existing container and do not try to run any more tasks.

ecs-cli compose --project-name tutorial service down \
  --cluster-config tutorial \
  --ecs-profile tutorial-profile
Enter fullscreen mode Exit fullscreen mode

Take down the cluster with ecs-cli down

Clean up the resources that you created earlier with ecs-cli up.

ecs-cli down --cluster-config tutorial \
  --force \
  --ecs-profile tutorial-profile
Enter fullscreen mode Exit fullscreen mode

Wow that took a long time. Should have just used Fly or Qovery.

Discussion (0)