模块 3:AWS App Runner 上的 .NET Web API
动手实验
实验目标
在此动手实验中,您将创建一个使用 DynamoDB 表的 .NET Web API,然后将其容器化并托管于 AWS App Runner 之中。您可以在 Windows PC、macOS 或 Linux 计算机上完成此实验,也可以在云端的 Cloud9 环境中完成此实验。
首先,您将创建一个 DynamoDB 表和访问该表的 .NET 6 Web API 项目。在本地进行测试后,您将使用 Docker 和适用于 .NET CLI 的 AWS 部署工具对软件进行容器化并将其部署到 Amazon Elastic Container Registry(ECR)。然后,您将创建 App Runner 服务,以及与 DynamoDB 通信所需的 AWS Artifact,其中包括一个 IAM 角色、一个 VPC 连接器和一个适用于 DynamoDB 的 VPC 端点。您将在云端测试您的应用程序,并验证该应用程序能否从 DynamoDB 检索数据。您将在 App Runner 控制台中监控应用程序并查看日志。最后,您将更新该项目并将更新推送到 ECR,然后看到 App Runner 自动对其进行部署。最后,您将删除应用程序及其资源。
此实验包含 12 个步骤:
- 设置 AWS
- 设置开发环境
- 创建 DynamoDB 表
- 创建 .NET Web API 项目
- 在本地测试
- 将 Web API 项目发布到 ECR
- 创建 IAM 角色
- 创建 App Runner 服务
- 为 DynamoDB 创建 VPC 端点
- 在云端测试
- 部署更新
- 关闭项目
所需时间
90 分钟
实施
第 1 步:设置 AWS
在此步骤中,您将设置 AWS 环境。
如果您已开始开发并部署到了 AWS App Runner,并且已经安装了适用于 .NET CLI 的 AWS 部署工具,则可以快进到第 3 步。
1.获取 AWS 账户
使用现有的 AWS 账户或创建一个 AWS 账户。请勿使用生产账户。
2.选择 AWS 区域
登录 AWS 管理控制台,然后选择一个支持 AWS App Runner 并支持 DynamoDB 的 AWS 区域,以在其中运行。
3.创建开发环境
如果使用本地计算机进行此实验,请继续执行第 2 步。
如果使用 Cloud9,请继续执行以下操作。
通过 AWS 管理控制台设置 Cloud9 环境:
A. 在 AWS 管理控制台中,导航到 Cloud9 并单击“创建环境”。
B. 将环境命名为 AppRunnerLab。
C. 保留默认设置并单击“创建”。
D. 等待环境完成创建,这需要几分钟时间。如果由于 t2.micro 实例类型在该区域不可用而导致环境创建失败,请重复上述步骤并选择另外一种小型实例类型。如果免费套餐中不包含该实例类型,请注意您需按照特定费率为实验期间对该实例类型的使用付费。
检查您的成果
现在,您应该:
✓ 有一个 AWS 账户
✓ 知道如何登录 AWS 管理控制台
✓ 已选择要运行的区域
✓ 有可用的本地计算机或 Cloud9 环境
第 2 步:设置开发环境
在此步骤中,您将安装软件,以设置开发环境。请跳过已安装项目。
1.安装 AWS CLI
安装 AWS 命令行界面(CLI)。
2.配置 AWS CLI
配置 AWS CLI,使其与 AWS 账户中的用户关联。
在命令/终端窗口中,使用以下命令配置区域:aws configure
3.安装 .NET SDK
安装 .NET 6 SDK。下载并安装适用于您操作系统的 SDK。
如果使用 Cloud9,则可以在“安装所需工具”(第 1 步和第 2 步)下运行这些命令。然后,运行以下命令:./dotnet-install.sh -c LTS。
4.安装适用于 .NET CLI 的 AWS 开发工具
在命令/终端窗口中,使用以下命令安装适用于 .NET CLI 的 AWS 部署工具:
dotnet tool install -g aws.deploy.tools
5.安装 Docker
安装 Docker Desktop。如果您已安装 Docker,请注意,您需要使用的是版本 17.05 或更高版本。
6.安装 IDE
安装 IDE,例如 Microsoft Visual Studio 2022(Windows)、Visual Studio Code(Linux、macOS、Windows)或 JetBrains Rider(Linux、macOS、Windows)。确保您已安装适用于 C# 中的 .NET Web 开发的选项或扩展程序。
检查您的成果
现在,您应该:
✓ 已安装所有必备软件
✓ 已为您的 AWS 用户和区域配置 AWS CLI
第 3 步:创建 DynamoDB 表
在此步骤中,您将创建一个名为 Weather 的 DynamoDB 表,然后再创建一些数据记录。
1.在 AWS 管理控制台中创建 DynamoDB 表
在 AWS 管理控制台中,导航到 Amazon DynamoDB 并单击创建表:
A. 表名称:Weather
B. 分区键:Location
C. 排序键:Timestamp
D. 单击创建表
2.在表中填充项目
单击 Weather 表名称,进入其详细信息页面,然后单击浏览表项目。添加以下项目:
A.单击创建项目和 JSON 视图。输入以下 JSON(Dallas, morning),然后单击创建项目。
{
"Location": {
"S": "Dallas"
},
"Timestamp": {
"S": "2022-07-23T06:00:00"
},
"Summary": {
"S": "Hot"
},
"TempC": {
"N": "33"
},
"TempF": {
"N": "92"
}
}
B.以同样的方式,使用以下 JSON 添加第二个项目(Dallas, mid-day):
{
"Location": {
"S": "Dallas"
},
"Timestamp": {
"S": "2022-07-23T12:00:00"
},
"Summary": {
"S": "Scorching"
},
"TempC": {
"N": "43"
},
"TempF": {
"N": "109"
}
}
C.使用以下 JSON 添加第三个项目(Dallas, evening):
{
"Location": {
"S": "Dallas"
},
"Timestamp": {
"S": "2022-07-23T18:00:00"
},
"Summary": {
"S": "Hot"
},
"TempC": {
"N": "36"
},
"TempF": {
"N": "97"
}
}
D.使用以下 JSON 添加第四个项目(Minneapolis, morning):
{
"Location": {
"S": "Minneapolis"
},
"Timestamp": {
"S": "2022-07-23T06:00:00"
},
"Summary": {
"S": "Cool"
},
"TempC": {
"N": "13"
},
"TempF": {
"N": "56"
}
}
E.使用以下 JSON 添加第五个项目(Minneapolis, mid-day):
{
"Location": {
"S": "Minneapolis"
},
"Timestamp": {
"S": "2022-07-23T12:00:00"
},
"Summary": {
"S": "Balmy"
},
"TempC": {
"N": "22"
},
"TempF": {
"N": "72"
}
}
F.使用以下 JSON 添加第六个项目(Minneapolis, evening):
{
"Location": {
"S": "Minneapolis"
},
"Timestamp": {
"S": "2022-07-23T18:00:00"
},
"Summary": {
"S": "Balmy"
},
"TempC": {
"N": "19"
},
"TempF": {
"N": "67"
}
}
检查您的成果
现在,您应该:
✓ 有一个名为 Weather 的 DynamoDB 表,并且表中填充了 6 个项目。
第 4 步:创建 .NET Web API 项目
在此步骤中,您将使用 dotnet new 命令创建一个 Web API 项目,并更新其代码以从 DynamoDB 表中检索数据。
1.将目录更改为开发文件夹
打开命令/终端窗口并将目录更改为开发文件夹。
2.创建 .NET WebAPI 项目
运行以下 dotnet new 命令,创建一个名为 HelloAppRunnerVpc 的新 Web API 项目。
dotnet new webapi -n HelloAppRunnerVpc --framework net6.0
3.在 IDE 中打开项目
在您的 IDE 中打开该 HelloAppRunnerVpc 项目。
如果您已为 IDE 安装了 AWS Toolkit,请将 AWS 各区服务浏览器中的区域设置为您在第 1 步中选择的区域。
4.审核已生成的项目
已生成的项目是 WeatherForecast API,在 .NET 示例中非常常用。
要进行试用,请按 F5 并用 Swagger 对其进行测试。您会看到该服务有一个 /WeatherForecast 操作,可返回模拟天气数据 JSON。
停止运行程序。
5.添加 AWS SDK NuGet 软件包
在命令/终端窗口中,将目录更改为项目文件夹。运行以下 dotnet add package 命令,将 AWS SDK NuGet 软件包 AWSSDK.DynamoDBv2 添加到项目中:
cd HelloAppRunnerVpc
dotnet add package AWSSDK.DynamoDBv2
6.修改 Program.cs
在代码编辑器中打开 Program.cs,然后删除或注释掉此语句,App Runner 不需要使用此语句:
//app.UseHttpsRedirection();
7.对 WeatherForecast 类进行编码
打开 WeatherForecast.cs 并将其替换为以下代码。此类包含从 Weather 表中检索的一个项目:
namespace HelloAppRunnerVpc;
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF { get; set; }
public string? Summary { get; set; }
}
8.对 WeatherForecastController 类进行编码
using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;
using Microsoft.AspNetCore.Mvc;
namespace HelloAppRunnerVpc.Controllers;
[ApiController]
[Route("")]
public class WeatherForecastController : ControllerBase
{
static readonly RegionEndpoint region = RegionEndpoint.USEast1;
private readonly ILogger _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet("")]
public string GetHealthcheck()
{
return "Healthcheck: Healthy";
}
[HttpGet("WeatherForecast")]
public async Task<IEnumerable<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
{
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();
}
}
9.保存更改并进行构建
保存您的更改并确保项目成功构建。
检查您的成果
现在,您应该:
✓ 有一个名为 HelloAppRunnerVpc 的 Web API 项目
✓ 已在 WeatherForecastController.cs 中设置区域
第 5 步:在本地测试
在此步骤中,您将在本地测试 Web API 并确认从 DynamoDB 检索数据。
1.调试项目
在 IDE 中按 F5,然后等待应用程序在浏览器中完成构建并启动。
2.测试运行状况检查操作
在浏览器中,从 URL 中移除 Swagger 路径,以访问服务根目录。然后,您应该会看到一条运行状况检查消息。App Runner 会定期对站点执行 ping 操作,来检查运行状况。
3.测试达拉斯的天气预报操作
将 /WeatherForecast?location=Dallas 添加到 URL 路径的末尾。您应该会看到天气预报数据 JSON,其中包含您在第 1 步中在 DynamoDB 表中创建的值。
4.测试明尼阿波利斯的天气预报操作
将 URL 路径更改为以 /WeatherForecast?location=Minneapolis 结尾。现在您可以看到该城市的数据。
5.测试无效位置的天气预报操作
试试其他位置名称,您会看到一个空响应,因为表中没有相应的数据。
6.停止程序
停止运行程序。
虽然在本地测试时,我们的应用程序可以直接访问 DynamoDB,但在云端却无法直接访问,因为默认情况下,App Runner 仅可访问公共端点。我们必须采取额外步骤,为 App Runner 添加一个 VPC 连接器,并为 DynamoDB 添加一个匹配的 VPC 端点。
检查您的成果
现在,您应该:
✓ 已在本地测试您的 Web API 项目。
✓ 确认已检索到 DynamoDB 数据。
第 6 步:将 Web API 项目发布到 ECR
1.创建 Dockerfile
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 ["HelloAppRunnerVpc.csproj", "."]
RUN dotnet restore "./HelloAppRunnerVpc.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "HelloAppRunnerVpc.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HelloAppRunnerVpc.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HelloAppRunnerVpc.dll"]
2.部署到 ECR
将您的项目作为容器映像部署到 ECR:
a.在命令/终端窗口中,运行以下命令启动部署,并指定您的首选区域。(图 1)
dotnet aws deploy --region us-west-2
b.选择相应选项,将容器映像推送到 Amazon Elastic Container Registry(ECR)
c.在“当前设置”提示符处,输入数字来更改图像标签,并将其设置为最新。(图 2)
d.按 Enter 键确认部署。
3.等待部署
等待部署完成。
4.在 AWS 管理控制台中确认部署
检查您的成果
现在,您应该:
✓ 已使用 Dockerfile 容器化您的项目。
✓ 已将容器映像部署到 Amazon ECR。
第 7 步:创建 IAM 角色
在此步骤中,您将使用 AWS 管理控制台创建一个名为 AppRunnerInstanceDynamoDB 的 IAM 角色。此角色将允许 App Runner EC2 实例访问 DynamoDB 表。
1.为 DynamoDB 表创建访问策略
创建一个允许访问 Weather DynamoDB 表的策略:
a.导航到 Identity and Access Management(IAM)。
b.从左侧窗格中选择“策略”,然后单击“创建策略”。
c.创建策略并输入以下 JSON,将 [account] 替换为您的 12 位 AWS 账号,并将 [region] 替换为您的区域。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": "arn:aws:dynamodb:[region]:[account]:table/Weather"
}
]
}
d.依次单击“下一步:标签”和“下一步:查看”。将策略命名为 ddb-Weather,然后单击“创建策略”。
2.为 EC2 实例创建角色
为 App Runner EC2 实例创建角色:
a.从左侧窗格中选择角色,然后单击创建角色。
b.对于“可信实体类型”,选择“AWS 服务”。(图 1)
c.对于“应用场景”,选择“EC2”并单击“下一步”。(图 1)
d.搜索并选择以下权限:ddb-Weather、AmazonDynamoDBFullAccess 和 AWSAppRunnerFullAccess。然后,单击下一步。(图 2)
e.在“信任关系”选项卡上,单击“编辑信任策略”。将其替换为此 JSON,然后单击“更新策略”。(图 5)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"tasks.apprunner.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
f.将角色命名为 AppRunnerInstanceDynamoDB,然后单击创建角色。(图 3)
检查您的成果
现在,您应该:
✓ 有一个名为 AppRunnerInstanceDynamoDB 并带有 3 个策略的 IAM 角色。
第 8 步:创建 App Runner 服务
在此步骤中,您将创建 App Runner 服务和一个 VPC 连接器。
1.创建服务
在 AWS 管理控制台中,导航到 AWS App Runner,然后单击创建服务。
a.存储库类型:容器注册表。 (图 1)
b.提供程序:Amazon ECR。
c.单击浏览,然后选择您在第 6 步中部署到 ECR 的容器。(图 2)
d.对于“部署设置触发器”,选择自动。
e.对于“ECR 访问角色”,选择创建新服务角色。
f.单击下一步。
2.配置服务
在“配置服务”页面上,
a.服务名称:HelloAppRunnerVpc。
b. b.端口:80。
3.配置实例角色
展开“安全”部分并将实例角色设置为 AppRunnerInstanceDynamoDB。
4.创建 VPC 连接器
展开“网络”部分并创建 VPC 连接器:
a.在“网络”下,选择自定义 VPC。
b.在“VPC 连接器”下,单击新增。
c.VPC 连接器名称:AppRunnerDynamoDB。(图 1)
d.VPC:选择您的默认 VPC。
e.子网:选择所有子网。
f.安全组:选择您的默认安全组。(图 2)
g.单击添加。如果您收到错误消息,显示您的某个子网不支持 App Runner 服务,请将其从子网列表中移除,然后再次单击添加。(图 2)
h.单击下一步,然后单击创建并部署。
5.等待部署
等待部署,这需要几分钟的时间。这是休息的好时机。
6.记录服务 URL
服务部署完成后,您将看到成功创建服务消息。
记录默认域 URL。这是您的服务 URL。
刷新事件日志,您应该会看到服务正在运行的确认消息。
7.浏览到服务 URL
浏览到 URL,您应该会看到您的运行状况检查。我们的服务托管在 App Runner 中,但它尚无法访问 DynamoDB。我们已创建 App Runner VPC 连接器,但我们仍然需要为 DynamoDB 创建相匹配的 VPC 端点。
检查您的成果
现在,您应该:
✓ 有一项名为 HelloAppRunnerVpc、正在运行的 AWS App Runner 服务。
✓ 有服务端点 URL。
✓ 已确认运行状况检查 URL 能在浏览器中正常响应。
第 9 步:为 DynamoDB 创建 VPC 端点
在此步骤中,您将为 DynamoDB 创建 VPC 端点。
1.在 AWS 管理控制台中,导航到 VPC
2.创建端点
从左侧面板中选择“端点”,然后单击创建端点。
a.名称:vpc-endpoint-dynamodb。(图 1)
b. b.服务类别:AWS 服务。
c.服务:在搜索框中输入 DynamoDB,然后选择 com.amazonaws.region.dynamodb。
d.VPC:选择您的默认 VPC。
e.路由表:选择“主路由表”。
f.单击创建端点。(图 2)
检查您的成果
现在,您应该:
✓ 有一个名为 vpc-endpoint-dynamodb、适用于 DynamoDB 的 VPC 端点。
第 10 步:在云端测试
现在,我们已准备好将其整合在一起,并可以在云端测试 Web API 了。
1.访问服务 URL
在浏览器中,访问您在第 6 步中记录的服务 URL。您会看到运行状况检查的响应。
2.测试达拉斯的天气预报操作
将 /WeatherForecast?location=Dallas 添加到路径的末尾。现在,您可以看到您在第 1 步中输入的达拉斯的记录
3.测试明尼阿波利斯的天气预报操作
3.将路径的末尾改为 /WeatherForecast?location=Minneapolis,然后您会看到该市的记录。
恭喜! 您的 Web API 已托管于 AWS App Runner 之中,且该服务正在与 DynamoDB 通信。
检查您的成果
现在,您应该:
✓ 已确认您的 AWS App Runner 服务能够从 DynamoDB 表中检索数据。
第 11 步:部署更新
在此步骤中,您将更新 Web API、推送经过更新的容器,并看到 App Runner 自动将更新后的容器部署到该服务。之所以如此,是因为我们在创建服务时在第 8 步中配置了自动部署。
1.修改服务
2.在本地构建和测试
在本地构建和测试项目,确保其按预期运行。
3.重新部署容器
4.监控服务重新部署
在 AWS App Runner 控制台中,查看您的服务。部署新容器不久后,App Runner 将自动部署更新。
5.测试更新后的服务
等待更新完成后,按照第 10 步中的操作浏览到该服务,对其进行测试。确认您现在可以看到该服务输出的新版本。
检查您的成果
现在,您应该:
✓ 已通过更改完成了对 Web API 项目的更新。
✓ 已向 ECR 部署了更新的容器。
✓ 确认 App Runner 已自动部署更新。
第 12 步:关闭项目
您可以随意对项目进行更改,以测试您的知识掌握情况。
完成项目的所有相关操作后,将其关闭。您一定不希望为自己没有使用的东西付费。
1.删除 App Runner 服务
在 AWS 管理控制台中,导航到 App Runner 并删除 HelloAppRunnerVpc 服务
2.删除 DynamoDB 表
导航到 DynamoDB 并删除 Weather 表
3.删除容器映像
导航到 ECR 并删除 helloapprunnervpc 容器映像。
4.删除 Cloud9 环境
如果使用 Cloud9,请导航到 Cloud9 并删除 AppRunnerLab 环境。
检查您的成果
现在,您应该:
✓ 已删除 App Runner 服务。
✓ 已删除 DynamoDB 表。
✓ 已删除 ECR 容器映像。
摘要
在此实验中,您创建了一个 DynamoDB 表并在其中填充了数据。您使用 dotnet new 命令生成了一个 .NET Web 应用程序项目。您对 Web API 进行编码,使其能够从 DynamoDB 表中检索天气数据。您将容器部署到了 ECR。您创建了一个 App Runner 服务来托管该 Web API。您创建了一个 App Runner VPC 连接器并为 DynamoDB 创建了一个 VPC 端点,以连接这两个可以连接的服务。您对当前托管于 AWS 上的应用程序进行了测试,并看到它可以正常运行。您将更新后的容器部署到了 ECR 并看到它自动部署到了 App Runner 服务。最后,您从 AWS 中取消了应用程序的分配。