Category: Developer Tools*


AWS Cloud9 – クラウド開発環境

プログラミングを始める時に最初に学ぶことは、どんな職人でも同様ですが、道具についてです。メモ帳は役に立たないでしょう。強力なエディタとテスティング パイプラインがあなたの生産性に大きく貢献します。私はまだ最初にVimの使い方を学んだ時のことを覚えています。それを使ってシステムと複雑なプログラムをZip化しました。すべてのコンパイラと依存関係を新しいマシンにセットアップすることが、どれほど大変だったか覚えていますか?新しいデベロッパーをプロジェクトに参加させるためにバージョンをマッチさせ、構成ファイルを取り繕い、ドキュメントを書くのに、どれほどのサイクルを浪費したことか。

本日(11/30)コーディング、実行、デバッグを可能にする統合開発環境(IDE)をWebブラウザ上で実現するのAWS Cloud9をローンチしました。Cloud9は多くの人気のある開発言語(Javascript、Python、PHP、その他)のための主要なツールをパッケージ化しているので、様々なコンパイラやツールなどをインストールする必要はありません。Cloud9はまたサーバーレスアプリケーションとのシームレスなエクスペリエンスを提供しておりローカルとリモートの間でテストやデバッグを素早くスイッチできます。ポピュラーなオープンソースのAce Editorとc9.io IDE(昨年買収しました)をベースに、AWS Cloud9は非常にパワフルなペアプログラミング機能と共にクラウド開発におけるコラボレーションが容易になるように設計されています。Cloud9は、このBlog記事でカバーしているものよりも多くの機能を提供していますが、ここではクイックにエディタ機能、AWSとのインテグレーション、コラボレーション機能の3つのコンポーネントに分解して掘り下げていきます。

(more…)

サードパーティソース管理の可視性向上のためのAWS CodePipelineのカスタムソースアクションの使用

以前の「GitとAWS CodePipelineの統合」の記事では、Amazon API GatewayAWS LambdaAmazon S3を使用して、サードパーティのGitリポジトリとAWS CodePipelineを統合する方法の1つを示しました。 このアプローチでは、GitリポジトリをCodePipelineと迅速に統合できますが、多くの利用者がCI/CDパイプラインで使用するソースのメタデータをCodePipelineに提供することはできません。

この記事では、ソースリポジトリから、より多くのメタデータをCodePipelineに提供するための異なる戦略を提供する、CodePipelineカスタムソースアクションについて説明します。最も一般的なソース メタデータは、コミット識別子とコミットメッセージです。Commit識別子は、ソフトウェアライフサイクル全体の変更を追跡するために頻繁に使用されますが、コミットメッセージは人間が判読可能で簡潔な記述を提供します。カスタムソースアクションを使用すると、CodePipelineがCodeCommitやGitHubと統合するのと同じ方法で、任意のソースリポジトリと統合することができ、コミット識別子とコミットメッセージにアクセスできます。

この記事では、API GatewayとLambdaをセットアップしてパイプラインをトリガし、パイプラインをカスタムソースアクションで構成し、カスタムソースアクションからジョブを処理するワーカーを構築します。このアーキテクチャを使用すると、VPCでホストされているか、またはオンプレミスに構築されておりVPCからアクセス可能なソースプロバイダにアクセスできます。 (more…)

AWS CodeCommitのプルリクエストを使用してコードレビューをリクエストし、コードについて議論する

シニアクラウドアーキテクトのMichael Edge氏のCodeCommitのプルリクエストに関する素晴らしいブログに感謝します。

~~~~~~~~~~~~~
AWS CodeCommitは、プライベートGitリポジトリを安全にホスティングするフルマネージドなサービスです。CodeCommitは今ではプルリクエストをサポートするようになりました。これによってリポジトリのユーザは、コードの変更に対するレビュー、コメント、対話的なイテレーションが可能になります。チームメンバー間のコラボレーションツールとして使用されるプルリクエストは、CodeCommitリポジトリに対する変更の可能性を、リポジトリにそれらの変更をマージする前に確認するのに役立ちます。各プルリクエストは、次のように単純なライフサイクルを通じて実行されます:

  • マージされる新機能は、featureブランチに1つ以上のコミットとして追加されます。コミットは、宛先のブランチにマージされません。
  • プルリクエストが通常は2つのブランチの差異から作成されます。
  • チームメンバーはプルリクエストをレビューし、コメントします。プルリクエストは、追加のコミットで更新される可能性があります。これにはコメントに対応して行われる変更や宛先ブランチとの差分から発生する変更が含まれます。
  • チームメンバーがプルリクエストに満足すれば、それは宛先ブランチにマージされます。 コミットは、プルリクエストに追加されるのと同じ順序で宛先ブランチに適用されます。

(more…)

AWS CodePipeline, AWS CodeBuild, AWS Lambdaを使ったサーバーレス自動UIテスト

Webアプリケーションのユーザーインターフェイスをテストすることは、開発ライフサイクルの重要なパートです。 この記事では、 AWS CodePipeline, AWS CodeBuild, AWS Lambdaなどのサーバーレス技術を利用してUIテストを自動化する方法を説明します。

S3でホストされているUIテスト用のWebサイトを構築しました。Seleniumを使用して、Chrome、Firefox、PhantomJS、およびWebDriver Wire Protocolの実装であるGhost DriverのヘッドレスWebKitブラウザで、クロスブラウザのUIテストを実行します。 テストが実行されているブラウザに基づいて、Pythonを使ってChromeDriver、FirefoxDriver、またはPhatomJSDriverのテストケースを作成しています。

この記事で紹介するAWS CloudFormationテンプレート、S3でホストされているテストおよびステータスWebサイト、AWS CodeBuildビルドスペックファイル、AWS Lambdaファンクション、テストを行うPythonスクリプトなどのリソースは、 serverless-automated-ui-testing GitHubリポジトリで公開しています。

 

S3にホストされるテストWebサイト: AWS CodeBuildはカスタムコンテナをサポートしているため、FirefoxとChromeブラウザのプレビルドを含むSelenium/standalone-FirefoxとSelenium/standalone-Chromeコンテナをそれぞれ使用できます。 Xvfbは、ディスプレイハードウェアなしで仮想メモリ内でグラフィカルオペレーションを実行します。 XvfbはインストールフェーズでCodeBuildコンテナにインストールされます。

 

Chrome and Firefoxテスト用のビルドスペック
ChromeとFirefoxのテストのビルドスペックには、複数のフェーズがあります:

  • 環境変数セクションには、ビルドプロジェクトの作成時またはビルドのトリガー時にオーバーライドされる一連のデフォルト変数が含まれます。
  • インストールフェーズの一部として、XvfbやSeleniumなどの必須パッケージがyumを使用してインストールされます。
  • pre_buildフェーズでは、テスト実行のためにテストベッドが準備されます。
  • ビルドフェーズでは、適切なDISPLAYが設定され、テストが実行されます。
version: 0.2

env:
  variables:
    BROWSER: "chrome"
    WebURL: "https://sampletestweb.s3-eu-west-1.amazonaws.com/website/index.html"
    ArtifactBucket: "codebuild-demo-artifact-repository"
    MODULES: "mod1"
    ModuleTable: "test-modules"
    StatusTable: "blog-test-status"

phases:
  install:
    commands:
      - apt-get update
      - apt-get -y upgrade
      - apt-get install xvfb python python-pip build-essential -y
      - pip install --upgrade pip
      - pip install selenium
      - pip install awscli
      - pip install requests
      - pip install boto3
      - cp xvfb.init /etc/init.d/xvfb
      - chmod +x /etc/init.d/xvfb
      - update-rc.d xvfb defaults
      - service xvfb start
      - export PATH="$PATH:`pwd`/webdrivers"
  pre_build:
    commands:
      - python prepare_test.py
  build:
    commands:
      - export DISPLAY=:5
      - cd tests
      - echo "Executing simple test..."
      - python testsuite.py

Ghost Driverはヘッドレスで動作するため、AWS Lambdaで実行できます。 Fire-and-forgetモデルに合わせて、CodeBuildを使ってPhantomJS Lambdaファンクションを作成し、Lambdaのテスト実行を並行して起動します。Lambdaで多くのテストを並行して実行できることは強力な機能です。

 

PhantomJS用のビルドスペック

PhantomJSテストのビルドスペックにも、複数のフェーズが含まれています。テスト実行にAWS Lambdaを使用しているため、前の例と少し異なります。

  • 環境変数セクションには、ビルドプロジェクトの作成時またはビルドのトリガー時にオーバーライドされる一連のデフォルト変数が含まれます。
  • インストールフェーズの一部として、SeleniumやAWS CLIなどの必須パッケージがyumを使用してインストールされます。
  • pre_buildフェーズでは、テスト実行のためにテストベッドが準備されます。
  • ビルドフェーズでは、PhantomJS Lambdaファンクションの作成に使用されるzipファイルが作成され、Lambdaファンクションでテストが実行されます。
version: 0.2

env:
  variables:
    BROWSER: "phantomjs"
    WebURL: "https://sampletestweb.s3-eu-west-1.amazonaws.com/website/index.html"
    ArtifactBucket: "codebuild-demo-artifact-repository"
    MODULES: "mod1"
    ModuleTable: "test-modules"
    StatusTable: "blog-test-status"
    LambdaRole: "arn:aws:iam::account-id:role/role-name"

phases:
  install:
    commands:
      - apt-get update
      - apt-get -y upgrade
      - apt-get install python python-pip build-essential -y
      - apt-get install zip unzip -y
      - pip install --upgrade pip
      - pip install selenium
      - pip install awscli
      - pip install requests
      - pip install boto3
  pre_build:
    commands:
      - python prepare_test.py
  build:
    commands:
      - cd lambda_function
      - echo "Packaging Lambda Function..."
      - zip -r /tmp/lambda_function.zip ./*
      - func_name=`echo $CODEBUILD_BUILD_ID | awk -F ':' '{print $1}'`-phantomjs
      - echo "Creating Lambda Function..."
      - chmod 777 phantomjs
      - |
         func_list=`aws lambda list-functions | grep FunctionName | awk -F':' '{print $2}' | tr -d ', "'`
         if echo "$func_list" | grep -qw $func_name
         then
             echo "Lambda function already exists."
         else
             aws lambda create-function --function-name $func_name --runtime "python2.7" --role $LambdaRole --handler "testsuite.lambda_handler" --zip-file fileb:///tmp/lambda_function.zip --timeout 150 --memory-size 1024 --environment Variables="{WebURL=$WebURL, StatusTable=$StatusTable}" --tags Name=$func_name
         fi
      - export PhantomJSFunction=$func_name
      - cd ../tests/
      - python testsuite.py

各ケースに属するテストケースとテストモジュールのリストは、Amazon DynamoDBテーブルに格納されています。

CodeBuildプロジェクトに引数として渡されたモジュールのリストに基づいて、CodeBuildはそのテーブルからテストケースを取得し実行します。テストの実行状況と結果は別のAmazon DynamoDBテーブルに保存されます。 DynamoDBのステータステーブルからテストステータスを読み取り、表示します。
AWS CodeBuildとAWS Lambdaはテストを個別のタスクとして実行します。 AWS CodePipelineは、継続的デリバリーと並列実行によるテストの最適化を可能にするという点で、重要な役割を果たします。

AWS CodePipelineには、以下の4つのステージを持ったパイプラインが作られます:

  • Source (AWS CodeCommit)
  • UI testing (AWS Lambdaと AWS CodeBuild)
  • Approval (手動承認)
  • Production (AWS Lambda)

次の図に、パイプラインステージ、各ステージのアクション、およびステージ間の遷移を示します。

AWS CodePipelineで実装されるデザインは、次のようになります。


CodePipelineはソースリポジトリの変更を自動的に検出し、パイプラインの実行をトリガします。

UITestステージには、2つの並列アクションがあります:

  • DeployTestWebsiteは、S3にテストウェブサイトを展開するためのLambdaファンクションを呼び出します。
  • DeployStatusPageは別のLambdaファンクションを呼び出して、ステータスWebサイトをS3に並列にデプロイします。

次に、CodeBuildプロジェクトを起動する3つの並行アクションがあります:

  • TestOnChromeは、Chrome上でSeleniumテストを実行するためのコンテナを起動します。
  • TestOnFirefoxは、FirefoxでSeleniumテストを実行する別のコンテナを起動します。
  • TestOnPhantomJSはLambdaファンクションを作成し、テストケースごとに個別のLambdaファンクションを呼び出して、テストケースを並列実行します。

次の図のように、ステータスWebサイトでテスト実行のステータスを監視できます:

UIテストが正常に完了すると、パイプラインはApprovalステージに進み、通知が構成済みのSNSトピックに送信されます。指名されたチームメンバーは、テストのステータスを確認し、デプロイを承認または拒否します。承認されると、パイプラインはProductionステージに進み、そこでLambdaファンクションを呼び出し、ウェブサイトをプロダクションS3バケットに配備します。

は、CloudFormationテンプレートを使用して、継続的デリバリーパイプラインを設定しました。 GitHubから入手できるautomated-ui-testing.yamlテンプレートを利用して全機能のパイプラインを設定することが可能です。
テンプレートを使用してパイプラインを作成するときは、次の項目を指定します:

  • AWS CodeCommitリポジトリ
  • 承認通知を送信するSNSトピック
  • 成果物が格納されるS3バケット名


スタック名は、S3バケット名の一部になるため、S3バケット命名規則に従ってください。

スタックが正常に作成されると、次のようにテストWebサイトとステータスWebサイトのURLが[Outputs]セクションに表示されます:

 

まとめ

この記事では、AWS CodePipeline、AWS CodeBuild、AWS Lambda、および手動承認プロセスを使用してサーバーレス自動UIテスト用の継続的デリバリーパイプラインを作成する方法をご紹介しました。 Amazon EC2インスタンスまたはAWS Elastic Beanstalk上で実行されるWebサイトも同様の方法でテストできます。


著者紹介

Prakash PalanisamyはAmazon Web ServicesのSolutions Architectです。 Serverless、DevOps、Alexaを担当する他、Project Eulerでの問題解決をおこなっています。彼はまた、教育ドキュメンタリーを見て楽しんでいます。

(翻訳はSA千葉が担当しました。原文はこちら)

 

AWSと.NET Core 2.0

昨日、.NET Core 2.0がリリースされ(訳注:このブログ記事の原文は2017/8/15に発行されています)、AWSでは .NET Coreプラットフォームに追加された新機能と完成度にとても興奮しています。今後数か月以内に、AWSサービスをアップデートして、.NET Core 2.0のファーストクラスのサポートを提供します。 2つの簡単な方法ですぐにAWS上で.NET Core 2.0を使い始めることができます。

 

AWS Elastic Beanstalkの利用

Elastic Beanstalkを使用すると、Webアプリケーションを簡単に展開できます。現在、.NET Frameworkおよび.NET Core 1.1がサポートされています。 Elastic Beanstalkプラットフォームは、すぐに.NET Core 2.0をサポートするように更新されるでしょう。 それまではデプロイメントパッケージをカスタマイズして、デプロイ中のインスタンスに.NET Core 2.0をインストールするようにBeanstalkに指示することができます。

ASP.NET CoreアプリケーションがBeanstalkにデプロイされると、AWS-windows-deployment-manifest.jsonというJSONマニフェストがツールキットによって作成され、Beanstalkにアプリケーションのデプロイ方法を指示します。 以前のブログ記事では、このマニフェストのカスタマイズ方法について説明しました。 この機能を使用して、デプロイ前にPowerShellスクリプトを実行して.NET Core 2.0をインストールすることができます。

最初のステップとして、ASP.NET Core 2.0プロジェクトにaws-windows-deployment-manifest.jsonというファイルを追加します。 aws-windows-deployment-manifest.jsonのプロパティウィンドウで、[Copy to Output Directory]フィールドを必ず[Copy Always]に設定してください。 このファイルは、通常、ツールキットによって生成されますが、ツールキットがファイルがすでに存在することが判明した場合は、代わりにデプロイメントウィザードで指定された設定で既存のファイルを変更します。

 

次に、下の内容をコピーしてaws-windows-deployment-manifest.jsonに貼り付けます。 これはASP.NET Coreアプリケーションをデプロイし、デプロイの前に./Scripts/installnetcore20.ps1 PowerShellスクリプトを実行することを示しています。

 

{
  "manifestVersion": 1,
  "deployments": {

    "aspNetCoreWeb": [
      {
        "name": "app",
        "parameters": {
          "appBundle": ".",
          "iisPath": "/",
          "iisWebSite": "Default Web Site"
        },
        "scripts": {
          "preInstall": {
            "file": "./Scripts/installnetcore20.ps1"
          }
        }
      }
    ]
  }
}

PowerShellスクリプトを追加するためのマニフェストを追加しました。 ASP.NET Coreプロジェクトに./Scripts/installnetcore20.ps1ファイルを追加します。 再度、[Copy to Output Directory]フィールドを[Copy Always]に設定して、デプロイメントパッケージに追加されていることを確認してください。 以下のスクリプトは、.NET Core 2.0インストーラをダウンロードし、インストーラを実行します。

 

$localPath = 'C:\dotnet-sdk-2.0.0-win-x64.exe'

if(!(Test-Path $localPath))
{
    Invoke-WebRequest -Uri 'https://download.microsoft.com/download/0/F/D/0FD852A4-7EA1-4E2A-983A-0484AC19B92C/dotnet-sdk-2.0.0-win-x64.exe' -OutFile $localPath
    & $localPath /quiet /log c:\InstallNetCore20.log
}

 

このスクリプトでは、Microsoftの公式リンクから.NET Core 2.0をダウンロードしています。 デプロイ中のダウンロードを高速化し、リンクの変更の影響を受けないようにするために、.NET Core 2.0インストレーションをElastic Beanstalk環境と同じリージョンにあるAmazon S3バケットにコピーすることをお勧めします。

デプロイメントマニフェストのカスタマイズにより、ASP .NET Core 2.0アプリケーションをElastic Beanstalkに簡単にデプロイできます。

 

Dockerベース サービスの利用

Amazon EC2 Container ServiceやAWS CodeBuildなどのDockerコンテナを実行するDockerベースのサービスについては、Docker Hubに発行されたDockerイメージを使用してすぐに開始できます。 たとえばコンソールでAWS CodeBuildプロジェクトを設定するときに、Docker HubからカスタムのDockerイメージを指定することができます。

 


.NET Core Dockerイメージの詳細については、GitHubリポジトリを参照してください。 AWSでDockerコンテナを実行する方法の詳細については、「Amazon ECS入門」を参照してください。

 

AWS SDK for .NET

.NET Core 2.0は.NET Standard 2.0をサポートしています。つまり、.NET Standard 2.0とそれ以下を対象とするNuGetパッケージは.NET Core 2.0でサポートされています。 AWS SDK for .NETは.NET Standard 1.3をターゲットとしています。このことはつまり、.NET Core 1.xまたは.NET Core 2.0の両方で利用できることを意味しています。

 

結論

.NET Core 2.0とAWSについて最新の情報を入手するには、AWS .NET開発ブログをフォローし、Twitterで私たちのツイートを見つけてください

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

AWS CodePipelineを利用したネストされたAWS CloudFormationスタックの継続的デリバリー

CodePipeline の更新 – CloudFormation スタックの継続的デリバリーワークフローの構築で、 Jeff BarrはInfrastructure as Codeについてと、AWS CodePipelineを継続的デリバリーに使用する方法について説明しています。 本ブログ記事では、ソースリポジトリとしてAWS CodeCommitを、ビルドおよびテストツールとしてAWS CodeBuildを使用した、AWS CodePipelineを使ったネストされたCloudFormationスタックの継続的デリバリーについて説明します。手動承認プロセスに従ってCloudFormationチェンジセットを使用してスタックをデプロイします。

AWS CodePipelineでは、次の4つのステージでパイプラインを作成します。

  • Source (AWS CodeCommit)
  • Build and Test (AWS CodeBuild および AWS CloudFormation)
  • Staging (AWS CloudFormation および 手動承認)
  • Production (AWS CloudFormation および 手動承認)

次の図に、パイプラインのステージと、各ステージのアクション、およびステージ間の遷移を示します。

CloudFormationテンプレート、テストスクリプト、およびビルドスペックファイルは、AWS CodeCommitリポジトリに格納されています。これらのファイルは、AWS CodePipelineのパイプラインのSourceステージで使用されます。

AWS::CloudFormation::Stackリソースタイプは、親スタックから子スタックを作成するために使用されます。 CloudFormationスタックリソースでは、S3バケットに格納される子スタックのテンプレートを必要とします。テンプレートファイルの場所は、リソース定義のPropertiesセクションにURLとして指定されます。

次のテンプレートは、3つの子スタックを作成します。

  • Security (IAM, セキュリティグループ)
  • Database (RDSインスタンス)
  • Web stacks (Auto ScalingグループのEC2インスタンス, ELB)

Description: Master stack which creates all required nested stacks

Parameters:
  TemplatePath:
    Type: String
    Description: S3Bucket Path where the templates are stored
  VPCID:
    Type: "AWS::EC2::VPC::Id"
    Description: Enter a valid VPC Id
  PrivateSubnet1:
    Type: "AWS::EC2::Subnet::Id"
    Description: Enter a valid SubnetId of private subnet in AZ1
  PrivateSubnet2:
    Type: "AWS::EC2::Subnet::Id"
    Description: Enter a valid SubnetId of private subnet in AZ2
  PublicSubnet1:
    Type: "AWS::EC2::Subnet::Id"
    Description: Enter a valid SubnetId of public subnet in AZ1
  PublicSubnet2:
    Type: "AWS::EC2::Subnet::Id"
    Description: Enter a valid SubnetId of public subnet in AZ2
  S3BucketName:
    Type: String
    Description: Name of the S3 bucket to allow access to the Web Server IAM Role.
  KeyPair:
    Type: "AWS::EC2::KeyPair::KeyName"
    Description: Enter a valid KeyPair Name
  AMIId:
    Type: "AWS::EC2::Image::Id"
    Description: Enter a valid AMI ID to launch the instance
  WebInstanceType:
    Type: String
    Description: Enter one of the possible instance type for web server
    AllowedValues:
      - t2.large
      - m4.large
      - m4.xlarge
      - c4.large
  WebMinSize:
    Type: String
    Description: Minimum number of instances in auto scaling group
  WebMaxSize:
    Type: String
    Description: Maximum number of instances in auto scaling group
  DBSubnetGroup:
    Type: String
    Description: Enter a valid DB Subnet Group
  DBUsername:
    Type: String
    Description: Enter a valid Database master username
    MinLength: 1
    MaxLength: 16
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
  DBPassword:
    Type: String
    Description: Enter a valid Database master password
    NoEcho: true
    MinLength: 1
    MaxLength: 41
    AllowedPattern: "[a-zA-Z0-9]*"
  DBInstanceType:
    Type: String
    Description: Enter one of the possible instance type for database
    AllowedValues:
      - db.t2.micro
      - db.t2.small
      - db.t2.medium
      - db.t2.large
  Environment:
    Type: String
    Description: Select the appropriate environment
    AllowedValues:
      - dev
      - test
      - uat
      - prod

Resources:
  SecurityStack:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      TemplateURL:
        Fn::Sub: "https://s3.amazonaws.com/${TemplatePath}/security-stack.yml"
      Parameters:
        S3BucketName:
          Ref: S3BucketName
        VPCID:
          Ref: VPCID
        Environment:
          Ref: Environment
      Tags:
        - Key: Name
          Value: SecurityStack

  DatabaseStack:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      TemplateURL:
        Fn::Sub: "https://s3.amazonaws.com/${TemplatePath}/database-stack.yml"
      Parameters:
        DBSubnetGroup:
          Ref: DBSubnetGroup
        DBUsername:
          Ref: DBUsername
        DBPassword:
          Ref: DBPassword
        DBServerSecurityGroup:
          Fn::GetAtt: SecurityStack.Outputs.DBServerSG
        DBInstanceType:
          Ref: DBInstanceType
        Environment:
          Ref: Environment
      Tags:
        - Key: Name
          Value:   DatabaseStack

  ServerStack:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      TemplateURL:
        Fn::Sub: "https://s3.amazonaws.com/${TemplatePath}/server-stack.yml"
      Parameters:
        VPCID:
          Ref: VPCID
        PrivateSubnet1:
          Ref: PrivateSubnet1
        PrivateSubnet2:
          Ref: PrivateSubnet2
        PublicSubnet1:
          Ref: PublicSubnet1
        PublicSubnet2:
          Ref: PublicSubnet2
        KeyPair:
          Ref: KeyPair
        AMIId:
          Ref: AMIId
        WebSG:
          Fn::GetAtt: SecurityStack.Outputs.WebSG
        ELBSG:
          Fn::GetAtt: SecurityStack.Outputs.ELBSG
        DBClientSG:
          Fn::GetAtt: SecurityStack.Outputs.DBClientSG
        WebIAMProfile:
          Fn::GetAtt: SecurityStack.Outputs.WebIAMProfile
        WebInstanceType:
          Ref: WebInstanceType
        WebMinSize:
          Ref: WebMinSize
        WebMaxSize:
          Ref: WebMaxSize
        Environment:
          Ref: Environment
      Tags:
        - Key: Name
          Value: ServerStack

Outputs:
  WebELBURL:
    Description: "URL endpoint of web ELB"
    Value:
      Fn::GetAtt: ServerStack.Outputs.WebELBURL

Validateステージでは、AWS CodeBuildはAWS CodeCommitソースリポジトリの変更をチェックします。 ValidateTemplate APIを使用してCloudFormationテンプレートを検証し、子テンプレートと設定ファイルをS3バケットの適切な場所にコピーします。

次のAWS CodeBuildビルドスペックでは、TEMPLATE_FILES環境変数にリストされているCloudFormationテンプレートが検証され、AWS CodeBuildプロジェクトの環境変数TEMPLATE_BUCKETに指定されたS3バケットにコピーされます。 オプションとして、TEMPLATE_PREFIX環境変数を使用して、バケット内のパスを指定することもできます。これにより、構成ファイルの子テンプレートファイルの場所が更新されます。テンプレートファイルの場所は、親スタックのパラメータとして渡されます。

version: 0.1

environment_variables:
  plaintext:
    CHILD_TEMPLATES: |
      security-stack.yml
      server-stack.yml
      database-stack.yml
    TEMPLATE_FILES: |
      master-stack.yml
      security-stack.yml
      server-stack.yml
      database-stack.yml
    CONFIG_FILES: |
      config-prod.json
      config-test.json
      config-uat.json

phases:
  install:
    commands:
      npm install jsonlint -g
  pre_build:
    commands:
      - echo "Validating CFN templates"
      - |
        for cfn_template in $TEMPLATE_FILES; do
          echo "Validating CloudFormation template file $cfn_template"
          aws cloudformation validate-template --template-body file://$cfn_template
        done
      - |
        for conf in $CONFIG_FILES; do
          echo "Validating CFN parameters config file $conf"
          jsonlint -q $conf
        done
  build:
    commands:
      - echo "Copying child stack templates to S3"
      - |
        for child_template in $CHILD_TEMPLATES; do
          if [ "X$TEMPLATE_PREFIX" = "X" ]; then
            aws s3 cp "$child_template" "s3://$TEMPLATE_BUCKET/$child_template"
          else
            aws s3 cp "$child_template" "s3://$TEMPLATE_BUCKET/$TEMPLATE_PREFIX/$child_template"
          fi
        done
      - echo "Updating template configurtion files to use the appropriate values"
      - |
        for conf in $CONFIG_FILES; do
          if [ "X$TEMPLATE_PREFIX" = "X" ]; then
            echo "Replacing \"TEMPLATE_PATH_PLACEHOLDER\" for \"$TEMPLATE_BUCKET\" in $conf"
            sed -i -e "s/TEMPLATE_PATH_PLACEHOLDER/$TEMPLATE_BUCKET/" $conf
          else
            echo "Replacing \"TEMPLATE_PATH_PLACEHOLDER\" for \"$TEMPLATE_BUCKET/$TEMPLATE_PREFIX\" in $conf"
            sed -i -e "s/TEMPLATE_PATH_PLACEHOLDER/$TEMPLATE_BUCKET\/$TEMPLATE_PREFIX/" $conf
          fi
        done

artifacts:
  files:
    - master-stack.yml
    - config-*.json

テンプレートファイルがS3にコピーされると、CloudFormationはテストスタックを作成し、テストアクションとしてAWS CodeBuildをトリガーします。

AWS CodeBuildのビルドスペックでは、ネストされたCloudFormationスタックを使用して作成されたリソースが、CONFIG_FILEで指定された仕様に準拠しているかどうかをチェックするためのPythonスクリプト、validate-env.pyが実行されます。

version: 0.1

environment_variables:
  plaintext:
    CONFIG_FILE: env-details.yml

phases:
  install:
    commands:
      - pip install --upgrade pip
      - pip install boto3 --upgrade
      - pip install pyyaml --upgrade
      - pip install yamllint --upgrade
  pre_build:
    commands:
      - echo "Validating config file $CONFIG_FILE"
      - yamllint $CONFIG_FILE
  build:
    commands:
      - echo "Validating resources..."
      - python validate-env.py
      - exit $?

テストアクションが正常に完了すると、CloudFormationはテストスタックを削除し、パイプラインのUAT(訳者注:User Acceptance Test/ユーザ受け入れテスト)ステージに進みます。

このステージでは、CloudFormationはUATスタックに対して変更セットを作成し、変更セットを実行します。これにより、UAT環境が更新され、受け入れテストが可能になります。プロセスは手動承認アクションに進みます。 QAチームがUAT環境を検証して承認をおこなった後、プロセスはパイプラインのProductionステージに移行します。

このステージでは、CloudFormationはネストされた本番スタックの変更セットを作成し、プロセスは手動承認ステップに進みます。(通常は指定されたエグゼクティブによって)承認されると、変更セットが実行され、Productionデプロイメントが完了します。
 

継続的デリバリーパイプラインの設定

 
CloudFormationテンプレートを使用して、継続的デリバリーパイプラインを設定します。 GitHubから入手できるcodepipeline-cfn-codebuild.ymlテンプレートは、フル機能のパイプラインを設定します。

このテンプレートを使用してパイプラインを作成するときは、次の項目を指定します。

  • AWS CodeCommitリポジトリ
  • 承認通知を送信するSNSトピック
  • アーティファクトが格納されるS3バケット名

CFNTemplateRepoNameには、CloudFormationテンプレート、設定ファイル、およびビルドスペックファイルが格納されているAWS CodeCommitリポジトリを指定します。

私のリポジトリには以下のファイルが含まれています:

継続的デリバリーパイプラインは、Create Stackをクリックするとすぐに配備されます。作成後、パイプラインは各ステージを実行します。 UATおよびProductionステージの手動承認により、パイプラインは継続的デリバリーを可能にします。


 

ネストされたスタックの変更の実装

 
ネストしたスタック内の子スタックを変更するには(たとえば、パラメータ値を更新する、またはリソースを追加または変更するなど)、親スタックを更新します。変更は適切なテンプレートファイルまたは設定ファイルで行い、AWS CodeCommitリポジトリにチェックインする必要があります。これにより、次のデプロイプロセスがトリガーされます:

 

まとめ

 
この記事では、AWS CodePipeline、AWS CloudFormation、AWS CodeBuild、および手動承認プロセスを使用して、Infrastructure as Codeとアプリケーションデプロイメントの両方で継続的デリバリーパイプラインを作成する方法を示しました。

AWS CodePipelineの詳細については、AWS CodePipelineのドキュメントを参照してください。数回のクリックで始めることができます。 すべてのCloudFormationテンプレート、AWS CodeBuildビルドスペックファイル、および検証を実行するPythonスクリプトは、codepipeline-nested-cfn GitHubリポジトリに公開しています。


著者紹介

 
Prakash PalanisamyはAmazon Web ServicesのSolutions Architectです。 Serverless、DevOps、Alexaを担当する他、Project Eulerでの問題解決をおこなっています。彼はまた、教育ドキュメンタリーを見て楽しんでいます。

(翻訳はSA千葉が担当しました。原文はこちら)

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 福井が担当しました。原文はこちらです。)

 

異なるAWS CodeBuildビルドスペックファイルを使用した、同じソースからの複数ビルド作成

2017年6月、 AWS CodeBuildプロジェクトで別のビルドスペックファイル名または場所を指定できるようになりました
この記事では、異なるビルドスペックファイルを同じリポジトリで使用して、異なるビルドを作成する方法を説明します。この投稿のソースコードは我々のGitHubリポジトリにあります。
 

前提要件

AWS CLIをインストールして設定しておく必要があります。

ソリューションの概要

共有ライブラリを作成するために使用されるCプログラム(cbsamplelib.c)と、そのライブラリを使用するための別のユーティリティプログラム(cbsampleutil.c)を作成しました。 Makefileを使ってこれらのファイルをコンパイルします。

このサンプルアプリケーションをRPMとDEBパッケージに入れてエンドユーザーが簡単に展開できるようにする必要があります。 RPM用のビルドスペックファイルを作成しました。ビルドスペックで設定されたこのコードとRPMスペックファイル(cbsample.rpmspec)をコンパイルしてRPMパッケージを作成するには、makeを使用します。同様に、DEB用のビルドスペックファイルも作成しました。このビルドスペックで構成されたコントロールファイル(cbsample.control)に基づいてDEBパッケージが作成されます。

 

RPMビルドプロジェクト:

次のビルドスペックファイル(buildspec-rpm.yml)は、ビルドスペックバージョン0.2を使用します。ドキュメントで説明されているように、このバージョンは環境変数の構文が異なります。このビルドスペックには、複数のフェーズがあります。

  • installフェーズの一部として、yumを使用して必要なパッケージがインストールされます
  • pre_buildフェーズでは、必要なディレクトリが作成され、RPMビルドスペックファイルを含む必要なファイルが適切な場所にコピーされます
  • buildフェーズでは、コードがコンパイルされ、RPMスペックに基づいてRPMパッケージが作成されます

artifactセクションで定義されているように、RPMファイルはビルドアーティファクトとしてアップロードされます。

version: 0.2 

env: 
  variables: 
    build_version: "0.1" 
	
phases: 
  install: 
    commands: 
      - yum install rpm-build make gcc glibc -y 
  pre_build: 
    commands: 
      - curr_working_dir=`pwd` 
      - mkdir -p ./{RPMS,SRPMS,BUILD,SOURCES,SPECS,tmp} 
      - filename="cbsample-$build_version" 
      - echo $filename 
      - mkdir -p $filename 
      - cp ./*.c ./*.h Makefile $filename 
      - tar -zcvf /root/$filename.tar.gz $filename 
      - cp /root/$filename.tar.gz ./SOURCES/ 
      - cp cbsample.rpmspec ./SPECS/ 
  build: 
    commands: 
      - echo "Triggering RPM build" 
      - rpmbuild --define "_topdir `pwd`" -ba SPECS/cbsample.rpmspec 
      - cd $curr_working_dir 
	  
artifacts: 
  files: 
    - RPMS/x86_64/cbsample*.rpm 
  discard-paths: yes 

cb-centos-project.jsonをリファレンスとして使用して、CLIコマンドの入力JSONファイルを作成します。このプロジェクトでは、codebuild-multispecというAWS CodeCommitリポジトリと、buildspec-rpm.ymlという名前のビルドスペックファイルを使用します。 RPMパッケージを作成するには、カスタムイメージ名を指定する必要があります。私はDocker Hubの最新のCentOS 7イメージを使用しています。CodeBuildServiceRoleという名前のIAMロールを使用しています。これには、CodeBuildServiceRole.jsonで定義されたものと同様の権限が含まれています。 (必要に応じて、ポリシー内のリソースフィールドを変更する必要があります。)

{ 
    "name": "rpm-build-project", 
    "description": "Project which will build RPM from the source.", 
    "source": { 
        "type": "CODECOMMIT", 
        "location": "https://git-codecommit.eu-west-1.amazonaws.com/v1/repos/codebuild-multispec", 
        "buildspec": "buildspec-rpm.yml" 
    }, 
    "artifacts": { 
        "type": "S3", 
        "location": "codebuild-demo-artifact-repository" 
    }, 
    "environment": { 
        "type": "LINUX_CONTAINER", 
        "image": "centos:7", 
        "computeType": "BUILD_GENERAL1_SMALL" 
    }, 
    "serviceRole": "arn:aws:iam::012345678912:role/service-role/CodeBuildServiceRole", 
    "timeoutInMinutes": 15, 
    "encryptionKey": "arn:aws:kms:eu-west-1:012345678912:alias/aws/s3", 
    "tags": [ 
        { 
            "key": "Name", 
            "value": "RPM Demo Build" 
        } 
    ] 
}

cli-input-jsonファイルが準備できたら、次のコマンドを実行してビルドプロジェクトを作成します。

$ aws codebuild create-project --name CodeBuild-RPM-Demo --cli-input-json file://cb-centos-project.json 
{ 
	"project": { 
		"name": "CodeBuild-RPM-Demo", 
		"serviceRole": "arn:aws:iam::012345678912:role/service-role/CodeBuildServiceRole", 
		"tags": [ 
			{ 
				"value": "RPM Demo Build", 
				"key": "Name" 
			} 
		], 
		"artifacts": { 
			"namespaceType": "NONE", 
			"packaging": "NONE", 
			"type": "S3", 
			"location": "codebuild-demo-artifact-repository", 
			"name": "CodeBuild-RPM-Demo" 
		}, 
		"lastModified": 1500559811.13, 
		"timeoutInMinutes": 15, 
		"created": 1500559811.13, 
		"environment": { 
			"computeType": "BUILD_GENERAL1_SMALL", 
			"privilegedMode": false, 
			"image": "centos:7", 
			"type": "LINUX_CONTAINER", 
			"environmentVariables": [] 
		}, 
		"source": { 
			"buildspec": "buildspec-rpm.yml", 
			"type": "CODECOMMIT", 
			"location": "https://git-codecommit.eu-west-1.amazonaws.com/v1/repos/codebuild-multispec" 
		}, 
		"encryptionKey": "arn:aws:kms:eu-west-1:012345678912:alias/aws/s3", 
		"arn": "arn:aws:codebuild:eu-west-1:012345678912:project/CodeBuild-RPM-Demo", 
		"description": "Project which will build RPM from the source." 
	} 
}

プロジェクトが作成されたら、次のコマンドを実行してビルドを開始します。ビルドが開始されたら、ビルドIDを取得します。ビルドIDを使用してビルドのステータスを取得することができます。

$ aws codebuild start-build --project-name CodeBuild-RPM-Demo 
{ 
    "build": { 
        "buildComplete": false,  
        "initiator": "prakash",  
        "artifacts": { 
            "location": "arn:aws:s3:::codebuild-demo-artifact-repository/CodeBuild-RPM-Demo" 
        },  
        "projectName": "CodeBuild-RPM-Demo",  
        "timeoutInMinutes": 15,  
        "buildStatus": "IN_PROGRESS",  
        "environment": { 
            "computeType": "BUILD_GENERAL1_SMALL",  
            "privilegedMode": false,  
            "image": "centos:7",  
            "type": "LINUX_CONTAINER",  
            "environmentVariables": [] 
        },  
        "source": { 
            "buildspec": "buildspec-rpm.yml",  
            "type": "CODECOMMIT",  
            "location": "https://git-codecommit.eu-west-1.amazonaws.com/v1/repos/codebuild-multispec" 
        },  
        "currentPhase": "SUBMITTED",  
        "startTime": 1500560156.761,  
        "id": "CodeBuild-RPM-Demo:57a36755-4d37-4b08-9c11-1468e1682abc",  
        "arn": "arn:aws:codebuild:eu-west-1: 012345678912:build/CodeBuild-RPM-Demo:57a36755-4d37-4b08-9c11-1468e1682abc" 
    } 
} 

$ aws codebuild list-builds-for-project --project-name CodeBuild-RPM-Demo 
{ 
    "ids": [ 
        "CodeBuild-RPM-Demo:57a36755-4d37-4b08-9c11-1468e1682abc" 
    ] 
} 

$ aws codebuild batch-get-builds --ids CodeBuild-RPM-Demo:57a36755-4d37-4b08-9c11-1468e1682abc 
{ 
    "buildsNotFound": [],  
    "builds": [ 
        { 
            "buildComplete": true,  
            "phases": [ 
                { 
                    "phaseStatus": "SUCCEEDED",  
                    "endTime": 1500560157.164,  
                    "phaseType": "SUBMITTED",  
                    "durationInSeconds": 0,  
                    "startTime": 1500560156.761 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "PROVISIONING",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 24,  
                    "startTime": 1500560157.164,  
                    "endTime": 1500560182.066 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "DOWNLOAD_SOURCE",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 15,  
                    "startTime": 1500560182.066,  
                    "endTime": 1500560197.906 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "INSTALL",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 19,  
                    "startTime": 1500560197.906,  
                    "endTime": 1500560217.515 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "PRE_BUILD",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 0,  
                    "startTime": 1500560217.515,  
                    "endTime": 1500560217.662 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "BUILD",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 0,  
                    "startTime": 1500560217.662,  
                    "endTime": 1500560217.995 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "POST_BUILD",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 0,  
                    "startTime": 1500560217.995,  
                    "endTime": 1500560218.074 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "UPLOAD_ARTIFACTS",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 0,  
                    "startTime": 1500560218.074,  
                    "endTime": 1500560218.542 
                },  
                { 
                    "contexts": [],  
                    "phaseType": "FINALIZING",  
                    "phaseStatus": "SUCCEEDED",  
                    "durationInSeconds": 4,  
                    "startTime": 1500560218.542,  
                    "endTime": 1500560223.128 
                },  
                { 
                    "phaseType": "COMPLETED",  
                    "startTime": 1500560223.128 
                } 
            ],  
            "logs": { 
                "groupName": "/aws/codebuild/CodeBuild-RPM-Demo",  
                "deepLink": "https://console.aws.amazon.com/cloudwatch/home?region=eu-west-1#logEvent:group=/aws/codebuild/CodeBuild-RPM-Demo;stream=57a36755-4d37-4b08-9c11-1468e1682abc",  
                "streamName": "57a36755-4d37-4b08-9c11-1468e1682abc" 
            },  
            "artifacts": { 
                "location": "arn:aws:s3:::codebuild-demo-artifact-repository/CodeBuild-RPM-Demo" 
            },  
            "projectName": "CodeBuild-RPM-Demo",  
            "timeoutInMinutes": 15,  
            "initiator": "prakash",  
            "buildStatus": "SUCCEEDED",  
            "environment": { 
                "computeType": "BUILD_GENERAL1_SMALL",  
                "privilegedMode": false,  
                "image": "centos:7",  
                "type": "LINUX_CONTAINER",  
                "environmentVariables": [] 
            },  
            "source": { 
                "buildspec": "buildspec-rpm.yml",  
                "type": "CODECOMMIT",  
                "location": "https://git-codecommit.eu-west-1.amazonaws.com/v1/repos/codebuild-multispec" 
            },  
            "currentPhase": "COMPLETED",  
            "startTime": 1500560156.761,  
            "endTime": 1500560223.128,  
            "id": "CodeBuild-RPM-Demo:57a36755-4d37-4b08-9c11-1468e1682abc",  
            "arn": "arn:aws:codebuild:eu-west-1:012345678912:build/CodeBuild-RPM-Demo:57a36755-4d37-4b08-9c11-1468e1682abc" 
        } 
    ] 
}

DEB ビルドプロジェクト:

このプロジェクトでは、buildspec-deb.ymlというビルドスペックファイルを使用します。 RPMビルドプロジェクトと同様に、このビルドスペックには複数のフェーズが含まれています。ここでは、Debianコントロールファイルを使用してDEB形式のパッケージを作成します。ビルドが成功すると、ビルド成果物としてDEBパッケージがアップロードされます。

version: 0.2 

env: 
  variables: 
    build_version: "0.1" 

phases: 
  install: 
    commands: 
      - apt-get install gcc make -y 
  pre_build: 
    commands: 
      - mkdir -p ./cbsample-$build_version/DEBIAN 
      - mkdir -p ./cbsample-$build_version/usr/lib 
      - mkdir -p ./cbsample-$build_version/usr/include 
      - mkdir -p ./cbsample-$build_version/usr/bin 
      - cp -f cbsample.control ./cbsample-$build_version/DEBIAN/control 
  build: 
    commands: 
      - echo "Building the application" 
      - make 
      - cp libcbsamplelib.so ./cbsample-$build_version/usr/lib 
      - cp cbsamplelib.h ./cbsample-$build_version/usr/include 
      - cp cbsampleutil ./cbsample-$build_version/usr/bin 
      - chmod +x ./cbsample-$build_version/usr/bin/cbsampleutil 
      - dpkg-deb --build ./cbsample-$build_version 

artifacts: 
  files: 
    - cbsample-*.deb

ここでは、cb-ubuntu-project.jsonをリファレンスとして使用して、CLI入力JSONファイルを作成します。このプロジェクトは同じAWS CodeCommitリポジトリ(codebuild-multispec)を使用しますが、同じリポジトリ内の別のbuildspecファイル(buildspec-deb.yml)を使用します。デフォルトのCodeBuildイメージを使用してDEBパッケージを作成します。同じIAMロール(CodeBuildServiceRole)を使用します。

{ 
    "name": "deb-build-project", 
    "description": "Project which will build DEB from the source.", 
    "source": { 
        "type": "CODECOMMIT", 
        "location": "https://git-codecommit.eu-west-1.amazonaws.com/v1/repos/codebuild-multispec", 
        "buildspec": "buildspec-deb.yml" 
    }, 
    "artifacts": { 
        "type": "S3", 
        "location": "codebuild-demo-artifact-repository" 
    }, 
    "environment": { 
        "type": "LINUX_CONTAINER", 
        "image": "aws/codebuild/ubuntu-base:14.04", 
        "computeType": "BUILD_GENERAL1_SMALL" 
    }, 
    "serviceRole": "arn:aws:iam::012345678912:role/service-role/CodeBuildServiceRole", 
    "timeoutInMinutes": 15, 
    "encryptionKey": "arn:aws:kms:eu-west-1:012345678912:alias/aws/s3", 
    "tags": [ 
        { 
            "key": "Name", 
            "value": "Debian Demo Build" 
        } 
    ] 
}

CLI入力JSONファイルを使用して、プロジェクトを作成し、ビルドを開始し、プロジェクトのステータスを確認します。

$ aws codebuild create-project --name CodeBuild-DEB-Demo --cli-input-json file://cb-ubuntu-project.json 

$ aws codebuild list-builds-for-project --project-name CodeBuild-DEB-Demo 

$ aws codebuild batch-get-builds --ids CodeBuild-DEB-Demo:e535c4b0-7067-4fbe-8060-9bb9de203789

RPMおよびDEBビルドが正常に完了したら、ビルドパッケージのアーティファクトセクションで設定されているS3バケットを確認します。ビルドプロジェクトでは、ビルドプロジェクトの名前でディレクトリを作成し、内部にアーティファクトをコピーします。

$ aws s3 ls s3://codebuild-demo-artifact-repository/CodeBuild-RPM-Demo/ 
2017-07-20 16:16:59       8108 cbsample-0.1-1.el7.centos.x86_64.rpm 

$ aws s3 ls s3://codebuild-demo-artifact-repository/CodeBuild-DEB-Demo/ 
2017-07-20 16:37:22       5420 cbsample-0.1.deb

ビルド開始時のBuildspecのオーバーライド:

ビルドを開始するときに既存のプロジェクトのビルドスペックファイルをオーバーライドすることもできます。 RPM全体ではなくlibs RPMパッケージを作成する場合は、buildspec-libs-rpm.ymlという名前のビルドスペックファイルを使用します。このビルドスペックファイルは、以前のRPMビルドと似ています。唯一の違いは、別のRPMスペックファイルを使用してlibs RPMを作成することです。

version: 0.2 
env: 
  variables: 
    build_version: "0.1" 

phases: 
  install: 
    commands: 
      - yum install rpm-build make gcc glibc -y 
  pre_build: 
    commands: 
      - curr_working_dir=`pwd` 
      - mkdir -p ./{RPMS,SRPMS,BUILD,SOURCES,SPECS,tmp} 
      - filename="cbsample-libs-$build_version" 
      - echo $filename 
      - mkdir -p $filename 
      - cp ./*.c ./*.h Makefile $filename 
      - tar -zcvf /root/$filename.tar.gz $filename 
      - cp /root/$filename.tar.gz ./SOURCES/ 
      - cp cbsample-libs.rpmspec ./SPECS/ 
  build: 
    commands: 
      - echo "Triggering RPM build" 
      - rpmbuild --define "_topdir `pwd`" -ba SPECS/cbsample-libs.rpmspec 
      - cd $curr_working_dir 

artifacts: 
  files: 
    - RPMS/x86_64/cbsample-libs*.rpm 
  discard-paths: yes

先ほど作成したのと同じRPMビルドプロジェクトを使用して、新しいビルドを開始し、 `-buildspec-override`パラメータの値をbuildspec-libs-rpm.ymlに設定します。

$ aws codebuild start-build --project-name CodeBuild-RPM-Demo --buildspec-override buildspec-libs-rpm.yml 
{ 
    "build": { 
        "buildComplete": false,  
        "initiator": "prakash",  
        "artifacts": { 
            "location": "arn:aws:s3:::codebuild-demo-artifact-repository/CodeBuild-RPM-Demo" 
        },  
        "projectName": "CodeBuild-RPM-Demo",  
        "timeoutInMinutes": 15,  
        "buildStatus": "IN_PROGRESS",  
        "environment": { 
            "computeType": "BUILD_GENERAL1_SMALL",  
            "privilegedMode": false,  
            "image": "centos:7",  
            "type": "LINUX_CONTAINER",  
            "environmentVariables": [] 
        },  
        "source": { 
            "buildspec": "buildspec-libs-rpm.yml",  
            "type": "CODECOMMIT",  
            "location": "https://git-codecommit.eu-west-1.amazonaws.com/v1/repos/codebuild-multispec" 
        },  
        "currentPhase": "SUBMITTED",  
        "startTime": 1500562366.239,  
        "id": "CodeBuild-RPM-Demo:82d05f8a-b161-401c-82f0-83cb41eba567",  
        "arn": "arn:aws:codebuild:eu-west-1:012345678912:build/CodeBuild-RPM-Demo:82d05f8a-b161-401c-82f0-83cb41eba567" 
    } 
}

ビルドが正常に完了したら、CodeBuild-RPM-Demoビルドプロジェクトフォルダの下にあるアーティファクトS3バケットにパッケージが表示されているかどうかを確認します。

$ aws s3 ls s3://codebuild-demo-artifact-repository/CodeBuild-RPM-Demo/ 
2017-07-20 16:16:59       8108 cbsample-0.1-1.el7.centos.x86_64.rpm 
2017-07-20 16:53:54       5320 cbsample-libs-0.1-1.el7.centos.x86_64.rpm

まとめ

この記事では、同じソースリポジトリ内の複数のbuildspecファイルを使用して、複数のAWS CodeBuildビルドプロジェクトを実行する方法を紹介しました。また、ビルドを開始するときに別のビルドスペックファイルを提供する方法も示しました。
AWS CodeBuildの詳細については、AWS CodeBuildのドキュメントを参照してください。ステップバイステップガイドを使用して、AWS CodeBuildを使い始めることができます。
 
(翻訳はSA千葉が担当しました。原文はこちら)

AWS CodeBuild と HashiCorp Packer を用いた AMI ビルダーの構築方法

独自の アマゾン マシン イメージ を作成し維持することは、運用とセキュリティにおけるベストプラクティスです。インフラストラクチャをコードとして維持することもまたベストプラクティスの1つです。そのため、Amazon EC2 インスタンスを素早く起動するために AMI を作成し設定する、といったことをスクリプト化するための自動化ツールを利用することには価値があります。

公開する2つの記事の最初にあたるこの記事では、AWS においてプログラマブルに AMI を作成するために AWS CodeBuild を使用します。AMI 生成の一部として、OS のパッチを適用し、バナーステートメントを設定し、よく使うソフトのいくつかをインストールし、将来的な Amazon EC2 ベースのデプロイメントへの基盤を形成します。

(more…)

AWS X-Ray で AWS Lambda をサポート

本日、AWS X-RayAWS Lambda サポート の一般提供開始を発表しました。Jeff が GA で投稿したブログですでにご存知の方もいるかと思いますが (「Jeff の GA POST (Jeff’s GA POST)」)、X-Ray は分散アプリケーションの実行やパフォーマンス動作を分析する AWS サービスです。

複数の独立したコンポーネントを異なるサービスで実行するマイクロサービスベースのアプリケーションでは、従来の問題をデバッグする方法がうまく機能しません。アプリケーションでレイテンシーを分けることで、X-Ray はエラーや処理の低下、タイムアウトを迅速に診断することができます。それでは、シンプルな Lambda ベースのアプリケーションを構築し分析する方法をお見せしながら、独自のアプリケーションで X-Ray を使用する方法をご説明します。

今すぐ開始したい場合は、関数の設定ページで追跡を有効にすれば既存の Lambda 関数で簡単に X-Ray を使い始めることができます。

または AWS Command Line Interface (CLI) で関数の tracing-config を更新してください (必ず --function-name も忘れずに):

$ aws lambda update-function-configuration --tracing-config '{"Mode": "Active"}'

トレースモードをオンにすると、Lambda は関数を追跡しようとします (アップストリームサービスによって追跡されないよう明示的に指示されていない限り)。オフの状態では、アップストリームサービスによって追跡するよう明示的に指示されている場合のみ関数が追跡されます。トレーシングモードをオンにすると追跡の生成が始まり、アプリケーションとその間のコネクション (辺) におけるリソースのビジュアル表現が見られるようになります。

X-Ray デーモンは Lambda 関数のいくつかのリソースを使用することがあります。メモリ制限に近付いている場合、Lambda はメモリ不足エラーを回避するために X-Ray デーモンを終了しようとします。では、複数のサービスを使用する簡単なアプリケーションを構築して新しい統合を試してみましょう。


20 代が持つスマートフォンということで、 pictures 自分のスマホは自撮りの写真でいっぱいです (10000+!)。ということで、この機会に写真をすべて分析してみることにしました。Java 8 ランタイムを使用して、Amazon Simple Storage Service (S3) バケットにアップロードした新しい画像に反応するシンプルな Lambda 関数を作成します。写真には Amazon Rekognition を使用し、検出したラベルを Amazon DynamoDB に保存します。

サービスマップ

まず、X-Ray のボキャブラリーをいくつか確認しておきましょう: サブセグメントセグメントトレースです。 分かりましたか? サービスグラフを生成するために X-Ray が処理するトレースをサブセグメントとセグメントが構成している、ということを覚えておけば X-Ray を理解しやすいと思います

サービスグラフは見やすいビジュアル表現を提供します (様々なリクエストへの応答を別の色で表示)。アプリケーションロジックを実行しているコンピューティングリソースは、実行している作業に関するデータをセグメント形式で送信します。サブセグメントを作成すれば、データに関する注釈を追加したり、コードのタイミングをより細かく設定することができます。アプリケーションを経由するリクエストのパスは、トレースを使用して追跡されます。トレースでは、1 つのリクエストで生成されたセグメントをすべて収集します。つまり、S3 からの Lambda イベントを DynamoDB まで簡単に追跡することができるので、エラーやレイテンシーがどこで発生しているか把握することができます。

では、S3 バケットを作成してみましょう。このバケットの名称は selfies-bucketにします。DynamoDB テーブルは selfies-table、あとは Lambda 関数です。ObjectCreated で S3 バケットの Lambda 関数にトリガーを追加します。Lambda 関数コードは実にシンプルです。こちらでご覧ください。コードの変更なしに、JAR の aws-xray-sdk と aws-xray-sdk-recorder-aws-sdk-instrumentor パッケージを含むことで Java 関数で X-Ray を有効にすることができます。アップロードした写真をいくつかトリガーして X-Ray のトレースを見てみましょう。

データが取れました!トレースの 1 つをクリックすれば呼び出しの詳細情報を見ることができます。

最初の AWS::Lambda セグメントでは、関数のドウェル時間、実行待機時間、試行された実行数を見ることができます。次の AWS::Lambda::Function セグメントにはいくつかのサブセグメントが見られます。

  • 初期設定のサブセグメントには関数ハンドラが実行する前の時間すべてが含まれます。
  • アウトバウンドサービスコール
  • 任意のカスタムセグメント (簡単に追加可能)

どうやら DyamoDB 側で問題が発生しているようです。エラーアイコンをクリックすれば、より詳しい情報と例外のスタックトレースを見ることができます。書き込みキャパシティーユニットが不足しているので、DynamoDB に調整されたことが分かります。数回のクリックまたは簡単な API コールで追加できます。そうするとサービスマップに表示される緑が増えていきます。

X-Ray SDK は X-Ray へのデータ放出をとても簡単にしますが、トークに X-Ray デーモンを使用する必要はありません。Python を使用している場合は fleece という rackspace からライブラリを確認できます。X-Ray サービスは興味深いものをたくさん備えています。詳細については「未定義 ()」ドキュメントをご覧ください

個人的に @awscloudninja ボットで使用していますが、これはとても優れていると思います。ただし、これは公式のライブラリではなく AWS がサポートしていない点にご留意ください。時間節約、デバッグや操作に対する労力においても便利なので、個人的には今後のプロジェクトすべてで X-Ray を使う予定です。皆さんがどのように構築するのか楽しみにしています。使えそうなトリックやハックを見つけたら、ぜひお知らせください!

– Randall