8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

40分でAWS ECS on Fargateチュートリアル

Last updated at Posted at 2025-03-29

はじめに

AWSのFargateを使ってみたいけど、何から始めていいかわからない...という方へ。
一緒に超シンプルな構成を試して「これがFargateか😃」を体感してみましょう。

書こうと思ったきっかけ

この記事は、インフラ・AWS初学者がFargateを理解して使えるようになるための学びの記録です。
初回は下記の記事です。ECRとECS、Fargateの概要説明とCloudShellを使って10分でECRにDockerイメージをプッシュする方法をまとめました。(多分3分で読めます)

今回はちょっとステップアップして、GitHubActionsを使ってECRにイメージをプッシュする方法も併せてご紹介します。

この記事一本で、シンプルなAWS ECS on Fargateを体験できます

ECS on Fargate とは?

Fargateっていうリソース環境(エンジンやメモリがある場所)でコンテナ管理するECSだよ、というやつです。
コンテナとは「アプリケーションを動かすために必要なものの集まり」と思ってください。
リソース環境がEC2になると「ECS on EC2」と呼びます。
Fargate と EC2の違いは「人間がコンテナを動かすためのサーバーを管理しないといけないのか」という点です。
Fargateは、AWSが自動でサーバーを用意してくれるので管理不要です。

ECSは、例えると「牧場」です。
広い草原がある環境(Fargate)で牛(コンテナ)を管理しています。
ということで次は ECS の構成を理解していきます。

ECSの構成要素

ECSは、クラスター、サービス、タスク定義・タスクで構成されます。

image.png
引用画像:https://zenn.dev/issy/articles/zenn-ecs-overview

① クラスター (Cluster)

サービスやタスクを管理する 「まとめ役」です。

② サービス (Service)

タスクを管理する 「実行役」です。

③④ タスクとタスク定義 (Task Definition)

タスク定義は「設計図」です。
タスク定義をもとに「起動させるコンテナの集まり」をタスクといいます。

あるルールに従う構成員、その上に実行役、さらに上にまとめ役がいる...
まるで何かの組織図のようですね。

ECSの構成 → 組織図
クラスター → 親玉
サービス  → 実行役(構成員をまとめるリーダー)
タスク定義 → 構成員のためのルール・仕組み
タスク  → 構成員たち

やってみよう

今回は簡単に、パブリックサブネットにECSを構築して1つのタスクを実行します。
タスクに割り振られたIPアドレスでアクセスするまでがゴールです。

下記の手順で進めます。

  1. GitHubActionsを使って、ECRにDockerイメージをプッシュ
  2. CloudFormation(コードでインフラ構築できるツール)を使ってECSを構築
  3. タスクに割り振られたIPアドレスでアクセスし「これがFargateか😃」を体感する
  4. GUIでクラスターを作ってみる
  5. もう一回タスクに割り振られたIPアドレスでアクセスし「これがFargateか😃」を体感する

前提:AWSとGitHubにログインしている

それではチュートリアルスタートです。

GitHubActionsを使って、ECRにDockerイメージをプッシュ

1-1.ECS → ECR → リポジトリを作成

スクリーンショット 2025-03-28 23.20.38.png

スクリーンショット 2025-03-28 23.22.00.png

1-2. GitHubActionsを使う準備

リポジトリを作成して、下記のDockerfileとhtmlディレクトリ、index.htmlを保存します

Dockerfile
FROM nginx:latest
COPY ./html /usr/share/nginx/html
html/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Web App</title>
</head>
<body>
    <h1>初めてのFargate</h1>
</body>
</html>

GitHubActions用のymlファイルを作成します

スクリーンショット 2025-03-28 23.32.01.png

スクリーンショット 2025-03-28 23.33.29.png

スクリーンショット 2025-03-28 23.36.04.png

エディタ上に下記のコードを貼り付けてymlファイルを作成します

.github/workflows/ecr-push.yml
name: Push to ECR

# トリガー 「mainブランチにプッシュされたら」
on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
# ジョブ
  build-and-push: 
    runs-on: ubuntu-latest # 実行環境(ランナー)を指定 ubuntu-latestを指定した場合、stepsでUNIX系のコマンドが使用できる
    
    # ステップ
    steps:
      # リポジトリのクローン
      - name: Checkout code
        uses: actions/checkout@v3

      # AWS CLI のセットアップ
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      # Dockerログイン
      - name: Log in to Amazon ECR
        run: |
          aws ecr get-login-password --region ${{ secrets.AWS_REGION }} \
            | docker login --username AWS --password-stdin \
              $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com

      # Dockerイメージのビルド
      - name: Build Docker image
        run: |
          docker build -t ${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }} -f Dockerfile .

      # Dockerイメージのタグ付け
      - name: Tag Docker image
        run: |
          docker tag ${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }} \
          $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }}

      # Dockerイメージのプッシュ
      - name: Push Docker image to Amazon ECR
        run: |
          docker push \
          $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }}

1-3. GitHubActionsを使ってリポジトリにイメージをプッシュする

リポジトリのSettingsに、アクセスキー、リージョン、シークレットキー、ECRリポジトリ名、イメージタグを保存します。
IAMユーザーのアクセスキーとシークレットキーは、
AWSコンソールの画面右上のアカウントをクリック → セキュリティ情報 → アクセスキーの作成で作成できます。
新規の場合は、New repository secretをクリックして一つずつ保存してくださいね。

AWS_ACCESS_KEY_ID:
IAMユーザーのアクセスキー。人に見せちゃダメ。

AWS_SECRET_ACCESS_KEY:
IAMユーザーのシークレットキー。人に見せちゃダメ。

AWS_REGION:
ECRのリージョン(例: 東京リージョンならap-northeast-1)。

ECR_REPOSITORY:
ECRリポジトリ名(例: my-docker-repo)。自分のに変更してね

IMAGE_TAG:
Dockerイメージのタグ(例: latest)。このまま使用OK

スクリーンショット 2025-03-28 23.28.03.png

[1-1. ] で付けたリポジトリ名を保存

スクリーンショット 2025-03-28 23.29.58.png

それではGitHubActionsを実行します

スクリーンショット 2025-03-28 23.39.50.png

スクリーンショット 2025-03-28 23.45.42.png

スクリーンショット 2025-03-28 23.45.55.png

ちょっと興奮しますね

スクリーンショット 2025-03-28 23.46.07.png

ECRの中に、イメージがプッシュできました

スクリーンショット 2025-03-28 23.46.38.png

2. CloudFormationを使ってECSを構築

まず、イメージのURLをコピーします

スクリーンショット 2025-03-28 23.49.07.png

CloudFormationにアップロードするファイルを、ローカルで作成します。
自動でECS構築する魔法のファイルです。
今回は必要最小限のリソースを構築します。

下記のコードを使用する場合は、
"xxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo:latest"の部分に
イメージのURLを貼り付けてください

test.yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  # VPCの作成
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: "10.0.0.0/16"
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: "Name"
          Value: "honda-vpc"

  # サブネットの作成
  PublicSubnet1:
    Type: "AWS::EC2::Subnet"
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.0.0/20"
      AvailabilityZone: "ap-northeast-1a"
      Tags:
        - Key: "Name"
          Value: "honda-subnet-public1-ap-northeast-1a"

  # インターネットゲートウェイの設定
  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: "Name"
          Value: "honda-igw"

  AttachInternetGateway:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  # ルートテーブルの設定
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: "Name"
          Value: "honda-rtb-public"

  PublicRoute:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  SubnetRouteTableAssociation:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  # ECS用セキュリティグループ
  SecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "Allow HTTP traffic"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: 80
          ToPort: 80
          CidrIp: "0.0.0.0/0"

  # ECSクラスターの作成
  ECSCluster:
    Type: "AWS::ECS::Cluster"
    Properties:
      ClusterName: "my-ecs-cluster"

  # ECSタスク定義
  ECSTaskDefinition:
    Type: "AWS::ECS::TaskDefinition"
    Properties:
      Family: "my-app-task"
      RequiresCompatibilities:
        - FARGATE
      NetworkMode: "awsvpc"
      Cpu: "256"
      Memory: "512"
      ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
      ContainerDefinitions:
        - Name: "my-app-container"
          Image: "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo:latest"  ご自身のイメージURLを貼り付けてください
          PortMappings:
            - ContainerPort: 80
              HostPort: 80
              Protocol: "tcp"

  # ECSタスク実行ロール
  ECSTaskExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "ecs-tasks.amazonaws.com"
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: "ecsTaskExecutionPolicy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action:
                  - "ecr:GetAuthorizationToken"
                  - "ecr:GetDownloadUrlForLayer"
                  - "ecr:BatchGetImage"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                  - "s3:GetObject"
                Resource: "*"

  # ECSサービスの作成
  ECSService:
    Type: "AWS::ECS::Service"
    Properties:
      Cluster: !Ref ECSCluster
      TaskDefinition: !Ref ECSTaskDefinition
      DesiredCount: 1
      LaunchType: "FARGATE"
      NetworkConfiguration:
        AwsvpcConfiguration:
          Subnets:
            - !Ref PublicSubnet1
          SecurityGroups:
            - !Ref SecurityGroup
          AssignPublicIp: "ENABLED"

引用元:https://qiita.com/free-honda/items/c7a68a216eef2161c567


CloudFormation → スタックの作成

スクリーンショット 2025-03-28 23.47.05.png

先ほど作成したtest.yamlをアップロードします

スクリーンショット 2025-03-28 23.51.00.png

スタックに名前を付けます

スクリーンショット 2025-03-28 23.53.39.png

承認チェックに✅します

スクリーンショット 2025-03-28 23.55.29.png

最後のページは特に何も変更せずに「送信」をクリックします

スクリーンショット 2025-03-28 23.56.31.png

test.yamlに書いたリソースがどんどん作られていきます。
更新ボタンを押して、スタック名に「CREATE_COMPLETE」ステータスが付いたら完了です。

スクリーンショット 2025-03-28 23.59.04.png

3. タスクに割り振られたIPアドレスでアクセスし「これがFargateか😃」を体感する

ECS → クラスター → クラスターをクリック

スクリーンショット 2025-03-29 0.00.16.png

タスクをクリック

スクリーンショット 2025-03-29 0.01.34.png

パブリックIPアドレスをクリック

スクリーンショット 2025-03-29 0.03.43.png

Fargateにアクセスできました!

スクリーンショット 2025-03-29 0.37.39.png

4. GUIでクラスターを作ってみる

先ほどは自動でクラスターとサービスを作成しましたが、試しに作ってみましょう
まず先ほど作成したクラスターを削除します
タスクからタスクを停止し、クラスターからクラスターを削除

スクリーンショット 2025-03-29 21.41.29.png

スクリーンショット 2025-03-29 21.42.13.png

クラスターの作成をクリック

スクリーンショット 2025-03-29 21.47.56.png

クラスターに名前を付けます

スクリーンショット 2025-03-29 0.11.51.png

クラスターができました

スクリーンショット 2025-03-29 0.13.21.png

サービスを作成します

スクリーンショット 2025-03-29 21.51.19.png

スクリーンショット 2025-03-29 0.19.51.png

ネットワーキングのタブを開いて、VPCやサブネットをdefaultではなく、自分で作成したものに変更しましょう

スクリーンショット 2025-03-29 0.16.35.png

スクリーンショット 2025-03-29 0.18.51.png

「正常にデプロイされました」の表示は出たら完了です

スクリーンショット 2025-03-29 0.35.23.png

5. もう一回タスクに割り振られたIPアドレスでアクセスし「これがFargateか😃」を体感する

ECS → クラスター → クラスターをクリック

スクリーンショット 2025-03-29 0.00.16.png

タスクをクリック

スクリーンショット 2025-03-29 0.01.34.png

パブリックIPアドレスをクリック

スクリーンショット 2025-03-29 0.03.43.png

Fargateにアクセスできました!

スクリーンショット 2025-03-29 0.37.39.png

まとめ

  • 「ECS on Fargate」とは「Fargate載せECS」の意味で、ECSがメイン
  • ECSはクラスター、サービス、タスク・タスク定義で構成される

最後までお付き合いくださりありがとうございます。
今回はECRにDockerイメージをプッシュし、ECSの中のFargateで簡単なWebサイトをデプロイする方法を学び、Fargateを体感しました。
次回はハッカソンで開発したアプリをFargateでデプロイしてみます。

参考文献

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?