Amazon Web Services ブログ

ASP.NET CoreとAWS CodeStarのDeep Dive

AWS CodeStar チームは最近、2つのASP.NET Coreプロジェクト テンプレートの追加を発表しました。ご存知かもしれませんが、AWS CodeStarは継続的インテグレーションと継続的デプロイメント(CI/CD)パイプラインを開発者に代わって作成し、それによって開発者は貴重な時間をインフラの構築の代わりにアプリケーションの構築に費やすことができます。新しいASP.NET Coreプロジェクトテンプレートを使用することで、.NET開発者は初日からAWSアプリケーションを構築し、展開することができます。Tara Walkerの優れたブログ記事では、AWS CodeStarでASP.NET Core アプリケーションを作成する方法について説明しています。このブログ記事では、AWS CodeStarのASP.NET Coreプロジェクトにテストを追加する方法を学ぶ中で、背後で何が起こっているのかを詳しく見ていきます。

 

Unit Test プロジェクトの追加

私たちの目標は、HelloControllerの機能を実行するシンプルなテストケースを追加することです。私はあなたが全く新しいASP.Net Core Web Service プロジェクトを持っていると仮定しています。もし、まだプロジェクトを持っていない場合は、Taraのブログ記事(上記)をたどってプロジェクトを作成することができます。ASP.NET Core Web Service テンプレートを選択していることを確認してください。ASP.NET Core for AWS CodeStarプロジェクトを作成後、Team Explorer でプロジェクト リポジトリをクローンし、AspNetCoreWebServiceソリューションをロードしたら、残りのブログ記事に沿って後を追えるようになります。Team Explorer でリポジトリをセットアップするためのガイドが必要な場合は、5月のSteve RobertのVisual StudioとCodeCommitのインテグレーションについての発表をご覧ください。

最初に、AspNetCoreWebServiceTestという名前の新しいxUnitプロジェクトをAspNetCoreWebServiceソリューションに追加します。私たちの新しいテストプロジェクトはHelloControllerクラスとJsonResultを参照するので、AspNetCoreWebServiceをプロジェクト参照として追加し、Microsoft.AspNetCore.MvcをNuGet参照として追加する必要があります。それらをテストプロジェクトに追加すると、AspNetCoreWebServiceTest.csprojに次の追加情報が表示されます。

 

<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    ...
</ItemGroup>
...
<ItemGroup>
    <ProjectReference Include="..\AspNetCoreWebService\AspNetCoreWebService.csproj" />
</ItemGroup>

 

これにより、HelloControllerクラスを直接参照し、JsonResultを展開することができます。次のように簡単なテストケースを追加しましょう。

using System;
using Xunit;
using Microsoft.AspNetCore.Mvc;
using AspNetCoreWebService.Controllers;

namespace AspNetCoreWebServiceTest
{
    public class HelloControllerTest
    {
        [Fact]
        public void SimpleTest()
        {
            HelloController controller = new HelloController();
            var response = controller.Get("AWS").Value as Response;
            Assert.Equal(response.output, "Hello AWS!");
        }
    }
}

 

ファイル名、名前空間、クラス名、およびメソッド名を変更したことに注意してください。テストを実行し、テストが合格することを確認します。ソリューション エクスプローラで次のように表示されます。

動作するテストプロジェクトを手に入れたので、アプリケーションをデプロイする前にテストをビルドして実行するようにパイプラインを更新します。

 

AWS CodeBuildジョブの更新

最初にプロジェクトの構築方法を見てみましょう。あなた、もしくはチームのメンバーがリポジトリに変更をプッシュすると、パイプラインは自動的に最新の変更に対してビルドプロセスを開始します。このステップでは、AWS CodeBuildはビルドプロセスを実行するためにリポジトリのルートにあるbuildspec.ymlファイルを使用します。

version: 0.2
phases:
  pre_build:
    commands:
      - echo Restore started on `date`
      - dotnet restore AspNetCoreWebService/AspNetCoreWebService.csproj
  build:
    commands:
      - echo Build started on `date`
      - dotnet publish -c release -o ./build_output AspNetCoreWebService/AspNetCoreWebService.csproj
artifacts:
  files:
    - AspNetCoreWebService/build_output/**/*
    - scripts/**/*
    - appspec.yml

 

AWS CodeBuildジョブは、AWS CodeBuildに.NET Coreイメージを使用します。これには buildspec.ymlで呼び出す.NET Core SDKとCLIが含まれています。このプロジェクトは1つのWebサービスで構成されているため、1つのbuildspec.ymlファイルで十分です。プロジェクトが拡大しビルドプロセスの複雑さが増すにつれて、いずれはシェルスクリプトまたはMSBuildの.projファイルを使用してシンプルにbuildspec.ymlでscript / buildファイルを呼び出すように、ビルドプロセスを外部で駆動したいと思うかもしれません。

 

ここでは dotnet publishコマンドに注目したいと思います。この発行のステップは、すべての依存関係をパッケージ化してホストマシン上ですぐに利用できるようにするために重要です。上記のbuildspec.ymlファイルのartifactsセクションで定義されているように、AWS CodeDeployがホストにアプリケーションを配置するために使用するファイル群が、Amazon S3バケットに格納されます。scripts/**/* には、appsec.ymlが依存するすべてのスクリプトが含まれています。appsec.ymlに慣れていない方や詳細を知りたい方のために次のセクションで説明します。

前のセクションでは、AWS CodeCommitリポジトリにテストプロジェクトを追加しました。今度は、新しいテストプロジェクトをビルドするためにbuildspec.ymlを更新する必要があります。ビルド ステージの一部として、単にdotnet vstestを実行することができますが、このエクササイズではベストプラクティスに従ってビルドとテストのステージを分けて構築します。 buildspec.ymlを修正してテスト バイナリをビルドし、その成果物をAspNetCoreWebServiceTest/test_outputディレクトリに発行しましょう。

pre_build:
    commands:
        ...
        - dotnet restore AspNetCoreWebServiceTest/AspNetCoreWebServiceTest.csproj
post_build:
    commands:
        ...
        - dotnet publish -c release -o ./test_output AspNetCoreWebServiceTest/AspNetCoreWebServiceTest.csproj  
artifacts:
    files:
        ...
        - AspNetCoreWebServiceTest/test_output/**/*

 

アーティファクトとしてAspNetCoreWebServiceTest/test_output/**/* を追加したことに注意してください。実際には、これは発行されたテストバイナリをAmazon S3にアップロードするようにAWS CodeBuildサービスに指示することになります。これにより、次に作成するテスト ジョブでそれらを参照できるようになります。

 

AWS CodePipelineの更新

前のセクションでは、テストを実行するために必要なバイナリをビルドして保存するために、新しいテストプロジェクトを追加し、buildspec.ymlを修正しました。次にテストステージをパイプラインに追加する方法について説明します。まずTestステージとUnitTestアクションをコンソールからパイプラインに追加しましょう。

残りのUIも以下のパラメータで埋めます:

  • Action category: Test
  • Action name: UnitTest
  • Test provider: AWS CodeBuild
  • Create a new build project を選択
  • Project name: <プロジェクト名>-test
  • Operating system: Ubuntu
  • Runtime: .NET Core
  • Version: aws/codebuild/dot-net:core-1
  • Build specificationInsert build Commands を選択
  • Build command: dotnet vstest AspNetCoreWebServiceTest/test_output/AspNetCoreWebServiceTest.dll
  • Role nameCodeStarWorker-<プロジェクト名>-CodeBuild をリストから選択
  • Input artifacts #1 は, <プロジェクト名>-BuildArtifact をリストから選択

 

ここでの重要な情報は、ビルドコマンドです。私たちのテストジョブは前のステージでビルドされたtest.dllに対してdotnet vstestを実行します。あなたのパイプラインはこのようになります。

これでほぼ完成です!「Release Change」を押してこのパイプラインを実行すると、パイプラインのテストステージで Error Code: AccessDeniedException  のメッセージを伴って実行が失敗します。これは、AWS CodeStarサービスに新しいテストステージを実行する権限がないためです。ここではAWS CodeStarプロジェクトへの適切なアクセスを許可する方法を確認しましょう。

 

Role ポリシーの更新

AWS CodeStarプロジェクトでは、さまざまなサービスやワーカーがアプリケーションを同期、ビルド、およびデプロイするための最小限のアクセス許可のポリシーを作成します。新しいAWS CodeBuildジョブを追加したので、新しいリソースへのアクセスをCodeStarWorkerCodePipelinePolicyで許可する必要があります。この変更を行うためにIAMコンソールに移動します。 [Role]タブで、 “codebuild”キーワードを使用して検索します。ロールはCodeStarWorker- <プロジェクト名> -CodePipelineの形式である必要があります。次に、ロールにアタッチされているポリシーを編集します。以下に示します。

変更したい内容は、ポリシー内にAWS CodeBuildアクションに関連付けられている新しいcodebuildリソースである arn:aws:codebuild:us-east-1:532345249509:project/<プロジェクト名>-test を追加することです。

{
    "Action": [
        "codebuild:StartBuild",
        "codebuild:BatchGetBuilds",
        "codebuild:StopBuild"
    ],
    "Resource": [
        "arn:aws:codebuild:us-east-1:532345249509:project/<your project name>"
        "arn:aws:codebuild:us-east-1:532345249509:project/<your project name>-test"
    ],
    "Effect": "Allow"
}

 

以上です。AWS CodeStarプロジェクトは新しいジョブを構築するための適切な権限を持ちました。[Release Change] を押して試してみてください。

 

ASP.NET Core アプリケーションのデプロイメント

ここまでAWS CodeStarがプロジェクトをビルドしテストする方法を見てきました。このセクションでは、デプロイメントプロセスを詳しく見ていきます。AWS CodeStarプロジェクトの作成の一部として、AWS CodeStarサービスはアプリケーションをホストするAmazon EC2インスタンスを作成します。またappspec.ymlの指示に従って、そのインスタンスにデプロイメントプロセスを実行するcode-deploy-agentもインストールされます。appspec.ymlを見てみましょう。

version: 0.0
os: linux
files:
  - source: AspNetCoreWebService/build_output
    destination: /home/ubuntu/aspnetcoreservice
  - source: scripts/virtualhost.conf
    destination: /home/ubuntu/aspnetcoreservice 
hooks:
  ApplicationStop:
    - location: scripts/stop_service
      timeout: 300
      runas: root

  BeforeInstall:
    - location: scripts/remove_application
      timeout: 300
      runas: root

  AfterInstall:
    - location: scripts/install_dotnetcore
      timeout: 500
      runas: root

    - location: scripts/install_httpd
      timeout: 300
      runas: root

  ApplicationStart:
    - location: scripts/start_service
      timeout: 300
      runas: root

 

各スクリプトは、デプロイメントプロセスのさまざまなステージで実行されます:

  • install_dotnetcore – もしまだインストールされていなければ .NET Core をインストールし、最初の実行時にパッケージ キャッシュをアップデートします。これはMicrosoftのUbuntuへの.NET Coreインストールの推奨方法です。
  • install_httpd – HTTPDデーモンとmodsをインストールし、HTTPD設定ファイルを上書きしてリバースプロキシを有効化します。
  • start_service – HTTPDサービスを再起動し、既存のASP.NETアプリケーション/サービス プロセスを再起動します。
  • scripts/stop_service – HTTPDサービスを停止し、既に実行している場合、ASP.NETアプリケーション/サービスを停止します。
  • remove_application – インスタンスからデプロイされているアプリケーションを削除します。

 

インスタンス上のcode-deploy-agentは、アプリケーションのデプロイ時にこれらのフックを実行して、サービスをインストールして開始します。イベントのアクティビティはAWS CodeDeployコンソールで監視でき、EC2インスタンスから詳細なログを取得できます。インスタンスへのSSH接続を開いたら、デプロイメントログを見るために /var/log/aws/codedeploy-agentに移動してください。

 

結論

このブログ記事では、アプリケーションのパイプラインにテストステージを追加する例を使用して、AWS CodeStarのASP.NET Core プロジェクトの構築とデプロイメントを学びました。この記事がAWS CodeStarの下で完全なCI / CDシステムを提供するために、さまざまなコンポーネントとAWSサービスがどのように相互作用するかを理解する助けになることを願っています。詳細については、AWS CodeStarユーザーガイドをご覧ください。AWS CodeStarに固有の問題が発生した場合は、AWS CodeStarのトラブルシューティング ガイドを参照してください。

 

(翻訳はSA 福井が担当しました。原文はこちらです。)