Amazon ECS と AWS Fargate 上の .NET ワークロード

モジュール 3

モジュール 3: ハンズオンラボ: Amazon ECS と AWS Fargate 上の .NET ワークロード

 ハンズオンラボ

ラボの目標

このハンズオンラボでは、ASP.NET ウェブサイトと .NET Web API で構成される「Weather」という名前の ECS サービスを作成します。API は Amazon DynamoDB テーブルを使用して気象データを取得します。API は ECS サービスにデプロイされ、ウェブサイトは別の ECS サービスにデプロイされます。このラボは、Windows PC、macOS、Linux コンピュータ、またはクラウド内の Cloud9 環境で実行できます。

このラボには次の 12 のステップがあります。

  1. AWS 環境を設定する
  2. お客様の開発環境を設定する
  3. Amazon DynamoDB テーブルを作成する
  4. WeatherAPI プロジェクトを作成する
  5. WeatherAPI をローカルでテストする
  6. ECS に WeatherAPI をデプロイする
  7. ECS タスクロールと Test API を更新する
  8. WeatherSite プロジェクトを作成する
  9. WeatherSite をローカルでテストする
  10. WeatherSite を ECS にデプロイする
  11. アップデートをデプロイする
  12. シャットダウンする

 所要時間

90 分

実装

ステップ 1: AWS 環境をセットアップする

このステップでは、AWS 環境を設定します。

既に AWS Fargate を使用して開発し、Amazon ECS にデプロイしていて、AWS Deploy Tool for .NET CLI がインストールされている場合は、スキップしてステップ 3 に進むことができます。

 1.AWS アカウントを取得する

既存の AWS アカウントを使用するか、AWS アカウントを作成します。 本稼働アカウントは使用しないでください。

 2.AWS リージョンを選択する

AWS コンソールにサインインし、AWS Fargate 上の Amazon ECS をサポートし、さらに DynamoDB をサポートしている AWS リージョンでお使いになるものを選択します。

3.開発環境を作成する

このラボでローカルマシンを使用する場合、ステップ 2 に進んでください。

Cloud9 を使用している場合は、以下の操作を続けてください。

オプション: この AWS Quick Start に従って、必要な開発ツールのほとんどを使用して Cloud9 環境の作成を自動化できます。

そうしない場合は、以下に進んでください。

    A. AWS コンソールで、[Cloud9] に移動し、[Create environment] (環境の作成) をクリックします。

    B. 環境に「FargateLab」という名前を付け、[Next step] [次のステップ] をクリックします。

    C. 設定ページで、無料利用枠の対象となるインスタンスタイプをデフォルトのままにして、[Next step] (次のステップ) をクリックします。

    D. [Create environment] (環境の作成) をクリックします。

    E. 環境が作成されるのを待ちます。これには数分かかります。

: t2.micro インスタンスタイプがリージョンで使用できないために環境の作成に失敗した場合は、環境を削除して上記の手順を繰り返します。今度は別のスモールインスタンスタイプを選択します。インスタンスタイプが無料利用枠に含まれていない場合は、ラボ期間中に請求される料金に注意してください。

作業内容を確認する

これで、以下のようになっているはずです。

✓ AWS アカウントを持っている

✓ AWS マネジメントコンソールにサインインする方法を知っている

✓ 作業するリージョンを選択した

✓ 利用可能なローカルマシンまたは Cloud9 環境がある

ステップ 2: 開発環境を設定する

このステップでは、ソフトウェアをインストールして開発環境をセットアップします。既にインストール済みの項目はスキップしてください。

1.AWS CLI をインストールする

AWS コマンドラインインターフェイス (CLI) をインストールします。

2.AWS CLI を設定する

AWS アカウントのユーザーにリンクされるように AWS CLI を設定します

コマンド/ターミナルウィンドウで aws configure コマンドを使用してリージョンを設定します。

3.ユーザーのアクセス許可を設定する

次のように、アプリケーションを ECS にデプロイするために必要な許可を AWS ユーザーに付与します。

   A. AWS コンソールで IAM に移動します。

B. [Users] (ユーザー) に移動し、AWS ユーザーをクリックします。

C. [Add permissions] (許可を追加) をクリックし、[Attach existing policies directly] (既存のポリシーを直接アタッチ) をクリックします

D. 以下の各ポリシーを検索してチェックボックスを選択します。

  • PowerUserAccess
  • AWSCloudFormationFullAccess
  • AmazonECS_FullAccessAmazonEC2ContainerRegistryFullAccess
  • AmazonSSMFullAccess
  • IAMFullAccess

4..NET 6 SDK をインストールする

.NET 6 SDK をインストールします。 お使いのオペレーティングシステム用の SDK をダウンロードしてインストールします。

ローカルマシンを使用している場合は、お使いのオペレーティングシステム用の .NET 6 SDK をダウンロードしてインストールします。

Cloud9 を使用している場合は、[Install Required Tools] (必要なツールのインストール) でこれらのコマンドを実行できます。

sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

sudo yum -y update

sudo yum install dotnet-sdk-6.0

5.AWS Deploy Tool for .NET CLI をインストールする

次のコマンドを使用して、AWS Deploy Tool for .NET CLI をインストールします。

dotnet tool install -g aws.deploy.tools

6.Cloud9 を使用している場合は、ステップ 3 に進む

Cloud9 を使用している場合は、スキップしてステップ 3 に進んでください。

ローカルマシンを使用している場合は、以下の操作を続けてください。

7.IDE をインストールする

Microsoft Visual Studio 2022 (Windows)、Visual Studio Code (Linux、macOS、Windows)、または JetBrains Rider (Linux、macOS、Windows) などの IDE をインストールします。.NET ウェブ開発用のオプションや拡張機能を C# でインストールしたことを確認してください。

8.AWS Toolkit for Visual Studio をインストールする

オプション: Visual Studio を使用している場合は、AWS Toolkit for Visual をインストールして設定します。これにより、IDE 内から AWS デプロイを確認できます。

9.Docker デスクトップをインストールする

Docker Desktop をインストールします。Docker Desktop は実行中である必要があります。既に Docker を使用している場合は、バージョン 17.05 以降の Docker エンジンが必要であることに注意してください。

作業内容を確認する

これで、以下のようになっているはずです。

✓ 前提条件となるすべてのソフトウェアがインストールされている

✓ AWS ユーザーとリージョンのために AWS CLI を設定した

ステップ 3: DynamoDB テーブルを作成する

このステップでは、「Weather」という名前の DynamoDB テーブルを作成し、いくつかのデータレコードを作成します。

 1.AWS コンソールで DynamoDB テーブルを作成する

AWS コンソールで、Amazon DynamoDB に移動し、[Create table] (テーブルを作成) をクリックします。

    A. テーブル名: Weather
    B. パーティションキー: Location
    C. ソートキー: Timestamp
    D. [Create table] (テーブルを作成) をクリックします

 2.テーブルに項目を追加する

Weather」テーブル名をクリックして詳細ページに移動し、[Explore table items] (テーブルアイテムの検索) をクリックします。次の項目を追加します。

A.[Create item] (項目を作成) と [JSON view] (JSON ビュー) をクリックします。下に JSON を入力し (ダラス、朝)、[Create Item] (項目を作成) をクリックします。

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T06:00:00"
  },
  "Summary": {
    "S": "Hot"
  },
  "TempC": {
    "N": "33"
  },
  "TempF": {
    "N": "92"
  }
}

B.同様に、次の JSON で 2 番目の項目 (ダラス、昼) を追加します。

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T12:00:00"
  },
  "Summary": {
    "S": "Scorching"
  },
  "TempC": {
    "N": "43"
  },
  "TempF": {
    "N": "109"
  }
}

C.次の JSON で 3 番目の項目 (ダラス、夜) を追加します。

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T18:00:00"
  },
  "Summary": {
    "S": "Hot"
  },
  "TempC": {
    "N": "36"
  },
  "TempF": {
    "N": "97"
  }
}

D次の JSON で 4 番目の項目 (ミネソタ、朝) を追加します。

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T06:00:00"
  },
  "Summary": {
    "S": "Cool"
  },
  "TempC": {
    "N": "13"
  },
  "TempF": {
    "N": "56"
  }
}

E.次の JSON で 5 番目の項目 (ミネソタ、昼) を追加します。

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T12:00:00"
  },
  "Summary": {
    "S": "Balmy"
  },
  "TempC": {
    "N": "22"
  },
  "TempF": {
    "N": "72"
  }
}

F.次の JSON で 6 番目の項目 (ミネソタ、夜) を追加します。

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T18:00:00"
  },
  "Summary": {
    "S": "Balmy"
  },
  "TempC": {
    "N": "19"
  },
  "TempF": {
    "N": "67"
  }
}

作業内容を確認する

これで、以下のようになっているはずです。

✓「Weather」という名前の DynamoDB テーブルに、6 つの項目が追加されています。

ステップ 4: WeatherAPI プロジェクトを作成する

このステップでは、dotnet new コマンドを使用して .NET Web API プロジェクトを作成し、そのコードを更新して DynamoDB テーブルからデータを取得します。

1.CD コマンドで開発フォルダに移動する

コマンド/ターミナルウィンドウ開いて、CD コマンドで開発フォルダに移動します。

2..NET WebAPI プロジェクトを作成する

A.以下の dotnet new コマンドを実行して、WeatherAPI という名前の新しい Web API プロジェクトを作成します。

    dotnet new webapi -n WeatherAPI

B.CD コマンドでプロジェクトフォルダに移動します。

C. DynamoDB SDK パッケージを追加します。以下の dotnet add package コマンドを実行して、プロジェクトに AWSSDK.DynamoDBv2 パッケージを追加します。Amazon DynamoDB サービスとやり取りするには、このライブラリが必要です。    

dotnet add package AWSSDK.DynamoDBv2

3.IDE でプロジェクトを開く

IDE で WeatherAPI プロジェクトを開きます。

4.リージョンを選択する

IDE に AWS Toolkit がインストールされている場合は、AWS Explorer のリージョンをステップ 1 で選択したリージョンに設定します。

5.HTTPS リダイレクトを設定する

コードエディタで Program.cs を開き、次のステートメントを削除するか、コメントアウトします。

// app.UseHttpsRedirection();

6.プロジェクトをデバッグする

生成されたプロジェクトは、.NET サンプルでよく使用される WeatherForecast API です。

A.試してみるには、1) IDE で F5 キーを押すか、2) コマンドラインから dotnet run を実行して、パスの末尾に /swagger/index.html を付けてエンドポイントアドレスを参照します。

B.開いたブラウザタブに、Swagger インターフェイスが表示されます。このサービスには、模擬気象データ JSON を返す /WeatherForecast アクションがあることに注意してください。テストするには、[Get] (取得)、[Try it Out] (試してみる)、[Execute] (実行) をクリックします。JSON レスポンスをメモしておきます。ローカル SSL 証明書を受け入れたかどうかによって、ブラウザに HTTPS に関する「Not secure」というインジケータが表示される場合と表示されない場合があります。

C.プログラムの実行を停止します。

7.ポートを設定する

当社の Web API はポート 8080 (HTTP) と 8443 (SSL) で実行されます。コードエディタで Properties/launchSettings.json を開きます。17 行目で、applicationUrl の値を次のように変更します。

"applicationUrl": "https://localhost:8443;http://localhost:8080",

8.データ構造をコーディングする

WeatherForecast.cs を開いて、以下のコードに置き換えます。このレコード構造は、ステップ 3 で作成した DynamoDB 項目と一致します。

namespace WeatherAPI;

public class WeatherForecast
{
    public string? Location { get; set; }

    public DateTime Date { get; set; }

    public int TemperatureC { get; set; }

    public int TemperatureF { get; set; }

    public string? Summary { get; set; }
}

9.Controller をコーディングする

Controllers フォルダの WeatherForecastController.cs を開き、以下のコードに置き換えます。12 行目で、RegionEndpoint を作業中のリージョンに設定します。このコードでは、サービスのルートパスにヘルスチェックメソッドを実装し、/WeatherForecast に WeatherForecast メソッドを実装しています。

/WeatherForecast メソッドはロケーションパラメータを受け取り、そのデータを DynamoDB Weather テーブルから取得します。テーブルスキャンを実行して、パーティションキーがロケーションと一致するレコードを検索します。一致する DynamoDB 項目は WeatherForecast オブジェクトのリストに保存されます。結果は JSON レコードの配列として返されます。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace WeatherAPI.Controllers;

[ApiController]
[Route("")]
public class WeatherForecastController : ControllerBase
{
    static readonly RegionEndpoint region = RegionEndpoint.USWest2;

    private readonly ILogger _logger;

    public WeatherForecastController(ILogger logger)
    {
        _logger = logger;
    }

    [HttpGet("")]
    public string GetHealthcheck()
    {
        return "Healthcheck: Healthy";
    }

    [HttpGet("WeatherForecast")]
    public async Task<WeatherForecast[]> GetWeatherForecast(string location = "Dallas")
    {
        List<WeatherForecast> forecasts = new List<WeatherForecast>();

        try
        {
            _logger.LogInformation($"00 enter GET, location = {location}");

            var client = new AmazonDynamoDBClient(region);
            Table table = Table.LoadTable(client, "Weather");

            var filter = new ScanFilter();
            filter.AddCondition("Location", ScanOperator.Equal, location);

            var scanConfig = new ScanOperationConfig()
            {
                Filter = filter,
                Select = SelectValues.SpecificAttributes,
                AttributesToGet = new List<String> { "Location", "Timestamp", "TempC", "TempF", "Summary" }
            };

            _logger.LogInformation($"10 table.Scan");

            Search search = table.Scan(scanConfig);
            List<Document> matches;
            do
            {
                _logger.LogInformation($"20 table.GetNextSetAsync");
                matches = await search.GetNextSetAsync();
                foreach (var match in matches)
                {
                    forecasts.Add(new WeatherForecast
                    {
                        Location = Convert.ToString(match["Location"]),
                        Date = Convert.ToDateTime(match["Timestamp"]),
                        TemperatureC = Convert.ToInt32(match["TempC"]),
                        TemperatureF = Convert.ToInt32(match["TempF"]),
                        Summary = Convert.ToString(match["Summary"])
                    });
                }
            } while (!search.IsDone);

            _logger.LogInformation($"30 exited results loop");

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "90 Exception");
        }

        _logger.LogInformation($"99 returning {forecasts.Count} results");

        return forecasts.ToArray();
    }
}

10.変更を保存して構築する

変更を保存し、プロジェクトが構築されていることを確認します。

作業内容を確認する

これで、以下のようになっているはずです。

✓ WeatherAPI プロジェクトがある

✓ AWSDK.DynamoDBv2 NuGet パッケージがインストールされた

✓ HTTPS リダイレクトが Program.cs でコメントアウトされた

✓ WeatherForecastController.cs が更新され、DynamoDB 天気テーブルをクエリするルートヘルスチェックメソッドと WeatherForecast メソッドが追加された

✓ 作業中のリージョンに WeatherForecastController.cs リージョン変数が設定された

ステップ 5: WeatherAPI をローカルでテストする

このステップでは、Web API をローカルでテストし、DynamoDB からのデータ取得を確認します。

 1.プロジェクトをデバッグする

IDE で F5 キーを押し、アプリケーションが構築されてブラウザで起動するのを待ちます。証明書が無効であるというセキュリティリスク警告が表示される場合があります。Swagger ページに、2 つのメソッドと WeatherForecast スキーマが表示されるようになりました。

 2.ヘルスチェックアクションをテストする

ブラウザで、URL から Swagger パスを削除してサービスルートにアクセスすると、ヘルスチェックメッセージが表示されるはずです。

 3.ダラスの天気予報アクションをテストする

URL パスを /WeatherForecast?location=Dallas に設定して、ロケーション値の大文字と小文字がテーブルデータと一致していることを確認します。ステップ 1 で DynamoDB テーブルに作成した値を含む天気予報データ JSON が表示されます。

4.ミネアポリスの天気予報アクションをテストする

URL パスを /WeatherForecast?location=Dallas に設定して、ロケーション値の大文字と小文字がテーブルデータと一致していることを確認します。ステップ 1 で DynamoDB テーブルに作成した値を含む天気予報データ JSON が表示されます。

5.無効なロケーションをテストする

別のロケーション名を試してみると、テーブルにそのロケーションのデータがないため、空の応答が表示されます。

6.デバッグを停止する

プログラムの実行を停止します。

作業内容を確認する

これで、以下のようになっているはずです。

✓ WeatherAPI プロジェクトをローカルでテストした。

✓ WeatherAPI が DynamoDB テーブルからデータを取得できることを確認した

ステップ 6: ECS に WeatherAPI をデプロイする

このステップでは、AWS Deploy Tool for .NET を使用して WeatherAPI プロジェクトをコンテナ化し、Amazon ECS にデプロイします。

1.AWS Deploy Tool for .NET を実行する

A.コマンド/ターミナルウィンドウで、CD コマンドで WeatherAPI フォルダに移動します。

B.dotnet aws deploy を実行します。

dotnet aws deploy

:オプションリストと順序は、dotnet aws deploy を実行するたびに異なる可能性があります。

C.既存の AWS デプロイターゲットを選択するように求められたら、[Deploy to a new Cloud Application] (新しいクラウドアプリケーションへのデプロイ) を選択します。

DFargate を使用して ASP.NET Core App から Amazon ECS への選択肢を選択します。

E.新しい CloudFormation スタックの名前については、Enter キーを押して WeatherAPI のデフォルト名を受け入れます。

2.設定を編集する

現在の設定が表示されたら、「more」と入力すると詳細設定が表示されます。番号が振られた設定リストが表示されます。「9」と入力して Elastic Load Balancer を選択し、プロンプトに次のように応答します。

A.新しいロードバランサーを作成する: y

B.登録解除の遅延: 180

C.ヘルスチェックパス: /

Dヘルスチェックタイムアウト: 5

E.ヘルスチェックの間隔: 120

F.正常なしきい値数: 2

G.異常なしきい値数: 2

3.デプロイする

A.Enter を押してデプロイを開始します。デプロイすると、ロードバランサーと 3 つの ECS タスクが作成され、新しいロールが作成されます。

B.サービスがコンテナ化されてデプロイされるまでお待ちください。これには数分かかります。完了したら、出力の最後にあるデプロイの詳細をメモします。

C. アプリケーションエンドポイントに詳細を記録します。サービスをテストするにはエンドポイントが必要です。

4.Dockerfile を確認する

プロジェクトフォルダに、Dockerfile ファイルが追加されています。AWS デプロイツールがこれを作成し、Docker を使用してプロジェクトをコンテナ化しました。

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WeatherAPI.csproj", ""]
RUN dotnet restore "WeatherAPI.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "WeatherAPI.csproj" -c Release -o /app/build

FROM build AS publish
RUN apt-get update -yq \
&& apt-get install curl gnupg -yq \
&& curl -sL https://deb.nodesource.com/setup_14.x | bash \
&& apt-get install nodejs -yq
RUN dotnet publish "WeatherAPI.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WeatherAPI.dll"]

5.ECS コンソールでレビューする

AWS コンソールに何がデプロイされているかを調べます。

A.AWS コンソールで ECS に移動します。

B.左側のペインから [Clusters] (クラスター) を選択すると、WeatherAPI クラスターが一覧表示されるはずです。1 つのサービスと実行中のタスクが 3 つあるクラスターが表示されます。(図 1)

C.WeatherAPI クラスター名をクリックすると、その詳細が表示されます。タブを開いて、何がデプロイされているかを確認します。[Tasks] (タスク) タブに、起動タイプ FARGATE の 3 つの実行中のタスクが表示されます。(図 2)

6.ECS エンドポイントをテストする

別のブラウザタブで、前述のステップ 6-3c で記録したエンドポイント URL にアクセスします。Healthy というヘルスチェックのレスポンスが表示されるはずです。これにより、ECS がホストするサービスが応答していることがわかります。

作業内容を確認する

これで、以下のようになっているはずです。

✓ AWS Deploy Tool for .NET CLI を使用して、プロジェクトをコンテナ化し、ECS にデプロイしました。

✓ ECS コンソールでのデプロイを確認しました。

✓ ベースエンドポイント URL がヘルスチェックを返すことを確認しました。

ステップ 7: ECS タスクロールを更新して API をテストする

WeatherAPI サービスはデプロイされて応答していますが、まだ DynamoDB テーブルへのアクセス許可がありません。このステップでは、DynamoDB アクセス用の IAM ポリシーを作成し、ECS タスクロールの許可を更新し、ECS サービスをテストします。

1.API をテストして欠落している許可をメモする

API をテストし、欠落している許可をメモします。ブラウザで、パスの末尾に /WeatherForecast?location=Dallas を付けてエンドポイント URL にアクセスします。データは返されません。これは、WeatherAPI サービスを実行している ECS タスクロールには、DynamoDB Weather テーブルへのアクセス許可がないためです。

2.DynamoDB アクセス用の IAM ポリシーを作成する

以下の手順に従い、Weather DynamoDB テーブルへのアクセスを許可する IAM ポリシーを作成します。

A.AWS コンソールで IAM に移動します。

B.左側のペインから [Policies] (ポリシー) を選択し、[Create policy] (ポリシーを作成) をクリックします。

C.ポリシーを作成し、以下の JSON を入力します。[account] は 12 桁の AWS アカウント番号に、[region] はお使いのリージョンに置き換えてください (例: us-west-2)。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "arn:aws:dynamodb:[region]:[account]:table/Weather"
        }
    ]
}

D[Next: Tags] ([次へ: タグ])、[Next: Review] ([次へ: 確認]) の順にクリックします。 ポリシーに「ddb-Weather」という名前を付け、[Create policy] (ポリシーを作成) をクリックします。

3.タスクロールを変更する

ECS サービスには、Weather DynamoDB テーブルへのアクセス許可がまだありません。ロールを更新して次の 2 つのポリシーを追加します。

A.AWS ECS コンソールで、WeatherAPI クラスターをクリックして詳細を表示します。

B.[WeatherAPI-service] をクリックすると、サービスの詳細が表示されます。

C.[Configuration and tasks] (設定とタスク) タブを選択し、[Task definition] (タスク定義) リンクをクリックします。

D[Task role] (タスクロール) リンクをクリックします。これにより、IAM コンソールのロール定義が表示されます。

E.[Add permission] (許可を追加)、[Attach policies] (ポリシーをアタッチ] の順にクリックします。

F.ddb-weather 許可を見つけて選択します

G.AmazonDynamoDBFullAccess 許可を見つけて選択します。

H.[Attach policies] (ポリシーをアタッチ) をクリックします。

4.API を再度テストする

ステップ 2 で結果が返されなかったページを更新します。今回は、JSON データが返されたことがわかります。ロールの更新により、DynamoDB テーブルにアクセスできるようになりました。

作業内容を確認する

これで、以下のようになっているはずです。

✓ WeatherAPI ECS サービスをテストしました。

✓ 「ddb-weather」という名前のポリシーを作成しました。

✓ DynamoDB に 2 つの許可がアタッチされた ECS タスクロールを更新しました。

✓ WeatherAPI ECS サービスを再度テストしたところ、データが返されました。

ステップ 8: WeatherSite プロジェクトを作成する

このステップでは、dotnet new コマンドを使用して.NET Web プロジェクトを作成し、そのコードを更新して API からデータを取得します。

1.ウェブプロジェクトを生成する

A.コマンド/ターミナルウィンドウ開いて、CD コマンドで開発フォルダに移動します。ステップ 4-1 で使用したのと同じフォルダを使用できます。

B.以下の dotnet new コマンドを実行して、WeatherAPI という名前の新しい Web API プロジェクトを作成します。

dotnet new webapp -n WeatherSite

C.CD コマンドで WeatherSite プロジェクトフォルダに移動します。

2.IDE でプロジェクトを開く

お使いの IDE で WeatherSite プロジェクトを開きます。

3.HTTPS リダイレクトを設定する

コードエディタで Program.cs を開き、次のステートメントを削除するか、コメントアウトします。

// app.UseHttpsRedirection();

4.プロジェクトをデバッグする

生成されたプロジェクトは、.NET サンプルでよく使用される単純なウェブアプリケーションです。

A.試してみるには、1) IDE で F5 キーを押すか、2) コマンドラインから dotnet run を実行してエンドポイントアドレスを参照します。

B.開いたブラウザタブに、ウェルカムメッセージを含むシンプルなページが表示されます。

C.プログラムの実行を停止します。

5.WeatherAPI 構成設定を追加する

コードエディタで appsettings.json を開き、以下のコードに置き換えます。[service-address] は WeatherAPI ECS サービスのエンドポイントアドレスに置き換えます。WeatherAPI サービスのアドレスには、末尾にスラッシュを付けないでください。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AppSettings": {
    "WeatherAPI": "http://[service-address]"
  }
}

6. 天気記録構造をコーディングする

以下のコードを使用して、ファイル WeatherForecast.cs をプロジェクトに追加します。このレコード構造は、Weather API によって返される項目と一致します。

namespace WeatherSite;

public class WeatherForecast
{
    public string? Location { get; set; }

    public DateTime Date { get; set; }

    public int TemperatureC { get; set; }

    public int TemperatureF { get; set; }

    public string? Summary { get; set; }
}

7.サービスクライアントをコーディングする

コードエディタで Pages/index.cshtml.cs を開き、以下のコードに置き換えます。これは Razor ページ Index.cshtml のコードビハインドファイルです。

WeatherAPI サービスの URL は appSettings.json の設定から読み込まれます。/WeatherForecast ルートはロケーションパラメータを受け取り、そのデータを DynamoDB Weather テーブルから取得します。結果は JSON レコードの配列として返されます。

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace WeatherSite.Pages;

public class IndexModel : PageModel
{
 [BindProperty(SupportsGet = true)]
 public string Location { get; set; } = "Dallas";

 public string Message { get; private set; } = "";
 public IEnumerable? Items { get; private set; }

 private readonly IConfiguration _configuration;
 private static readonly HttpClient _httpClient = new();

 public IndexModel(IConfiguration configuration)
 {
  _configuration = configuration;
 }

 public async Task OnGet()
 {
  try
  {
   var requestUri = $"{_configuration["AppSettings:WeatherAPI"]}/WeatherForecast?location={Location}";

   Items = await _httpClient.GetFromJsonAsync>(requestUri);
   Message = $"{Items?.Count()} forecast records found";
  }
  catch (HttpRequestException ex)
  {
   Message = ex.Message;
  }
 }
}

8.ページをコーディングする

コードエディタで Pages/Index.cshtml を開き、以下のコードに置き換えます。Razor ページには、コードビハインドモデルの一部の値が @ 表記 (ロケーション、成功/エラーメッセージ、天気予報データのテーブルなど) で表示されます。

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<style>
    .styled-table {
        border-collapse: collapse;
        font-size: 0.9em;
        font-family: sans-serif;
        min-width: 400px;
        box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
        margin-left: auto;
        margin-right: auto;
    }

        .styled-table thead tr {
            background-color: cornflowerblue;
            color: #ffffff;
            text-align: left;
        }

        .styled-table th,
        .styled-table td {
            padding: 12px 15px;
        }

        .styled-table tbody tr {
            border-bottom: 1px solid #dddddd;
        }

            .styled-table tbody tr:nth-of-type(even) {
                background-color: #f3f3f3;
            }

            .styled-table tbody tr:last-of-type {
                border-bottom: 2px solid cornflowerblue;
            }

            .styled-table tbody tr.active-row {
                font-weight: bold;
                color: cornflowerblue;
            }
</style>

<div class="text-center">
                                  <h1 class="display-4">@Model.Location Weather</h1>
                                  <p>Weather Forecast</p>
                                  <p>@Model.Message</p>

                                  <p><a href="/?location=Dallas">Dallas</a></p>
                                  <p><a href="/?location=Minneapolis">Minneapolis</a></p>

    @if (@Model.Items != null)
    {
                                  <table class="styled-table">
                                  <thead>
                                  <tr><th>Location</th><th>Time</th><th>Temp (°C)</th><th>Temp (°F)</th><th>Summary</th>
            </thead>
                                  <tbody>
                @foreach (var forecast in Model.Items)
                {
                                  <tr>
                                  <td>@forecast.Location</td>
                                  <td>@forecast.Date.ToString("yyyy-MM-ddHH:MM")</td>
                                  <td>@forecast.TemperatureC</td>
                                  <td>@forecast.TemperatureF</td>
                                  <td>@forecast.Summary</td>
                    </tr>
                }
            </tbody>
        </table>
    }
</div>

9.保存して構築する

変更を保存し、プロジェクトが構築されていることを確認します。

これで、アーキテクチャのすべてのコンポーネント (データベーステーブル、API、ウェブサイト) が作成されました。

作業内容を確認する

これで、以下のようになっているはずです。

✓ WeatherSite プロジェクトがある

✓ 気象記録構造をコーディングした

✓ メインのウェブページをコーディングした

✓ メインページ用のコードビハインドをコーディングした

ステップ 9: WeatherSite をローカルでテストする

このステップでは、ウェブサイトをローカルでテストし、Weather API バックエンド ECS サービスと通信できることを確認します。

1.プロジェクトをデバッグする

IDE で F5 キーを押し、ウェブアプリケーションが構築されてブラウザで起動するのを待ちます。ウェブサイトには、ダラスの気象データが読み込まれ、表示されるはずです。

2.ミネアポリスのリンクをクリックする

ミネアポリスのリンクをクリックします。ページが更新されて、その都市のデータが表示されます。

3.デバッグを停止する

お使いの IDE で WeatherSite のデバッグを停止します。

4.本稼働ポートを設定する

次に、ウェブサイトの本稼働ポートを設定します。WeatherSite プロジェクトを開いた状態の IDE で、コードエディタで Properties/launchSettings.json を開きます。17 行目で、applicationUrl の値を次のように変更します。

"applicationUrl": "https://localhost:443;http://localhost:80",

5.保存して構築する

変更を保存し、プロジェクトのビルドを確認します。

作業内容を確認する

これで、以下のようになっているはずです。

✓ WeatherSite プロジェクトをローカルでテストした。
✓ 確認したデータを WeatherAPI バックエンド ECS サービスから取得した

ステップ 10: WeatherSite を ECS にデプロイする

このステップでは、WeatherAPI プロジェクトをコンテナ化し、AWS Deploy Tool for .NET CLI を使用して Amazon ECS にデプロイします。これはステップ 6 と似ていますが、今回はフロントエンドウェブサイトをデプロイします。

1.AWS Deploy Tool for .NET を実行する

A.コマンド/ターミナルウィンドウで、CD コマンドを使って WeatherAPI フォルダに移動します。

B.dotnet aws deploy を実行します。

dotnet aws deploy
C.新規または既存のデプロイを選択するように求められたら、 [Deploy to a new Cloud Application] (新しいクラウドアプリケーションにデプロイ) を選択します。

DFargate を使用して ASP.NET Core App から Amazon ECS への選択肢を選択します。

E.新しい CloudFormation スタックの名前については、Enter キーを押して WeatherSite のデフォルト名を受け入れます。

2.設定を編集する

現在の設定が表示されたら、「more」と入力すると詳細設定が表示されます。番号が振られた設定リストが表示されます。「9」と入力して Elastic Load Balancer を選択し、プロンプトに次のように応答します。

A.新しいロードバランサーを作成する: y

B.登録解除の遅延: 180

C.ヘルスチェックパス: /

Dヘルスチェックタイムアウト: 5

E.ヘルスチェックの間隔: 120

F.正常なしきい値数: 2

G.異常なしきい値数: 2

3.デプロイする

A.Enter を押してデプロイを開始します。デプロイすると、ロードバランサーと 3 つの ECS タスクが作成され、新しいロールが作成されます。

B.ウェブサイトがコンテナ化されてデプロイされるまでお待ちください。これには数分かかります。完了したら、出力の最後にあるデプロイの詳細をメモします。

C.アプリケーションエンドポイントに詳細を記録します。 ウェブサイトをテストするにはエンドポイントが必要です。

4.Dockerfile を確認する

プロジェクトフォルダに、Dockerfile ファイルが追加されています。AWS デプロイツールがこのファイルを作成し、それを Docker で使用してプロジェクトをコンテナ化しました。

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WeatherSite.csproj", ""]
RUN dotnet restore "WeatherSite.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "WeatherSite.csproj" -c Release -o /app/build

FROM build AS publish
RUN apt-get update -yq \
    && apt-get install curl gnupg -yq \
    && curl -sL https://deb.nodesource.com/setup_14.x | bash \
    && apt-get install nodejs -yq
RUN dotnet publish "WeatherSite.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WeatherSite.dll"]

5.ECS コンソールでレビューする

A.AWS コンソールで ECS に移動します。

B.左側のペインから [Clusters] (クラスター) を選択します。WeatherSite クラスターがリストされているはずです。実行中のタスクが 3 つあるサービスが表示されるはずです。(図 1)

C.WeatherSite クラスター名をクリックすると、その詳細が表示されます。タブを開いて、何がデプロイされているかを確認します。起動タイプ FARGATE のタスクが 3 つ表示されるはずです。(図 2)

6.ECS エンドポイントをテストする

A.別のブラウザタブで、前述のステップ 10-3c で記録したエンドポイント URL にアクセスします。ウェブサイトが立ち上がり、デフォルトのロケーションはダラスです。

B.[Minneapolis] (ミネアポリス) をクリックして、そのロケールのデータの変更を確認します。

おめでとうございます。これで、AWS Fargate 上の Amazon ECS でホストされる DynamoDB テーブルとウェブサイトと API が作成されました。

作業内容を確認する

これで、以下のようになっているはずです。

✓ ウェブサイトをコンテナ化し、AWS Deploy Tool for .NET CLI を使用して ECSにデプロイしました。

✓ ECS コンソールでのデプロイを確認しました。

✓ ウェブサイトが稼働しており、Weather API サービスにアクセスできることを確認しました。

✓ ウェブサイト、API、DynamoDB テーブルが AWS 上で連携して動作していることを確認しました。

ステップ 11: アップデートをデプロイする

このステップでは、DynamoDB テーブルにさらにデータを追加し、3 つ目のロケーションでウェブサイトを更新し、更新したウェブサイトをデプロイします。また、タスク数を 3 から 2 に変更します。

1.別のロケーションのデータを DynamoDB 天気テーブルに追加する

A.AWS コンソールで、[DynamoDB] > [Tables] (テーブル) の順に移動し、「Weather」テーブルをクリックします。

B.[Explore Table Items] (テーブルアイテムの検索) をクリックします。ステップ 3 の前に行ったように、項目を複製して、シアトルなどの新しいロケーションまたは選択したロケーションにさらに 3 つの項目を追加します。

2.新しいロケーションのためにウェブサイトを更新する

A.お使いの IDE で WeatherSite プロジェクトを開きます

B.コードエディタで Pages/Index.cshtml を開き、ミネアポリスのリンクの後に以下を挿入します。

<p><a href="/?location=Seattle">Seattle</a></p>

C.変更を保存してプロジェクトを構築します。

3.アップデートをデプロイする

A.コマンド/ターミナルウィンドウを開き、CD コマンドで WeatherSite プロジェクトフォルダに移動します。

B.dotnet aws deploy コマンドを実行してアップデートをデプロイします

dotnet aws deploy
C. WeatherSite (CloudFormation Stack) (デフォルト) の選択肢を選択します。

D現在の設定が表示されたら、[1] を選択します。必要なタスク数を 3 から 2 に変更します。

E.Enter キーを押してデプロイを開始します。デプロイには数分かかります。

4.ECS でタスク数の変更を確認する

AWS コンソールで ECS に移動し、[Clusters] (クラスター) を選択します。WeatherSite のタスク数は、以前は 3 でしたが、現在は 2 になっているはずです。

5.更新されたウェブサイトをテストする

A.ブラウザで、ステップ 10-6 で以前に使ったのと同じエンドポイントでウェブサイトにアクセスします。ウェブページに、3 番目のロケーション、シアトルが表示されるようになったことを確認します。(図 1)

B.[Seattle] (シアトル) をクリックし、データの変更を確認します。(図 2)

作業内容を確認する

これで、以下のようになっているはずです。

✓ シアトルの気象データを DynamoDB テーブルに追加しました。

✓ ウェブサイトプロジェクトのメインページをシアトルのロケーションリンクで更新しました。

✓ 更新したウェブサイトをタスク数を減らして ECS にデプロイしました。

✓ ECSでホストされている更新されたウェブサイトをテストしました。

ステップ 12: シャットダウン

ラボで行うことをすべて完了したら、次の手順に従ってリソースの割り当てを解除します。使用しなくなったものに対して AWS 料金が発生することは避けたいものです。

1.WeatherSite のデプロイを削除する

A.コマンド/ターミナルウィンドウで、CD を使って WeatherSite プロジェクトフォルダに移動します。

B.dotnet aws delete-deployment WeatherSite を実行し、削除を確認します。

dotnet aws delete-deployment WeatherAPI

C.完了するまでお待ちください。

DAWS コンソールで ECS に移動し、WeatherSite クラスターがリストに表示されていないことを確認します。

2.WeatherAPI のデプロイを削除する

A.コマンド/ターミナルウィンドウで、CD コマンドを使って WeatherAPI プロジェクトフォルダに移動します。

B.dotnet aws delete-deployment WeatherAPI を実行し、削除を確認します。

dotnet aws delete-deployment WeatherAPI
C.AWS コンソールで、WeatherAPI クラスターがリストに表示されていないことを確認します。

3.DynamoDB Weather テーブルを削除する

AWS コンソールで、DynamoDB に移動します。

A.Weather テーブルを選択し、[Actions] (アクション) ドロップダウンから [Delete] (削除) を選択します。

B. 削除を確認し、完了するまで待ちます。

4.Cloud9 環境を削除する

Cloud9 環境を使用している場合は、

A.AWS コンソールで、Cloud9 に移動します。

B.FargateLab 環境を削除します。

作業内容を確認する

これで、以下のようになっているはずです。

✓ 2 つの ECS デプロイを削除した

✓ AWS コンソールで手動で割り当てたその他すべてのリソースを削除した

まとめ

このラボでは、次のことを達成しました。

  1. DynamoDB テーブルを作成し、気象データを入力しました。
  2. DynamoDB テーブルから気象データを取得する.NET Web API プロジェクトを開発しました。
  3. AWS Deploy Tool for .NET CLI を使用して、WeatherAPI プロジェクトを AWS Fargate 上の Amazon ECS にデプロイしました。
  4. WeatherAPI からデータを取得するウェブサイトを開発しました。
  5. AWS Deploy Tool for .NET CLI を使用して、WeatherSite プロジェクトを AWS Fargate 上の Amazon ECS にデプロイしました。
  6. 気象データとウェブサイトを更新し、更新したウェブサイトを ECS にデプロイしてタスク数を変更しました。
  7. WeatherSite と WeatherAPI のデプロイを削除し、AWS コンソールで Weather DynamoDB テーブルを削除しました。

このページはお役に立ちましたか?