Category: AWS CodeBuild


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 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…)

New – AWS CodeStarの紹介 – AWS上のアプリケーションをすばやく開発、構築、デプロイする

それほど遠く無い昔、今日多くのソフトウェア チームがアプリケーション開発で直面している、リリース期限までにソフトウェア プロジェクトを完成させ変化に対応するというような開発チームに私は所属していました。そこには新しいプロジェクト環境のセットアップ、チームメンバーのコラボレーション、各開発ビルドのコード変更、構成、ライブラリの継続的な追跡を行う日常的なタスクなどの課題がありました。 今日、企業がイノベーションと市場投入をより迅速に行うためには、開発チームがソフトウェアの作成、構築、展開をより簡単かつ効率的に行うことが不可欠になっています。

 

残念なことに、多くの組織は、より機敏で動的なソフトウェア開発プロセスを追求する上で、いくつかの重要な課題に直面しています。 ほとんどの新しいソフトウェア プロジェクトが直面する最初の課題は、開発者がコーディングを開始する前に完了しなければならない長いセットアップ プロセスです。 このプロセスには、IDEのセットアップ、適切なコード リポジトリへのアクセスの取得、および/またはビルド、テスト、および運用に必要なインフラストラクチャの識別が含まれます。

 

コラボレーションは、ほとんどの開発チームが直面しうる別の課題です。 プロジェクトのすべてのメンバーに安全な環境を提供するために、チームはさまざまなチームの役割とニーズに応じて別々のプロジェクトとツールを頻繁に設定する必要があります。 さらに、すべてのステークホルダーに、課題の更新、開発の進展、およびソフトウェアの問題の報告に関する情報を提供することは、時間がかかる可能性があります。

 

最後に、ほとんどの企業では、継続的インテグレーションと継続的デリバリに関するベストプラクティスを採用することで、ソフトウェア開発のスピードを高め、市場投入までの時間を短縮したいと考えています。 これらのアジャイル開発戦略を適用するには、企業が方法論についてチームを教育し、これらの新しいプロセスのためのリソースを設定するための時間を費やす必要があります。

 

AWS CodeStar:プレゼンテーション

 

開発チームがソフトウェアを構築する上での課題を緩和し、アプリケーションやソリューションをリリースするペースを向上させるために、AWS CodeStarを紹介します。

 

AWS CodeStarは、開発プロジェクト全体の設定を簡素化することにより、AWS上でアプリケーションの開発、構築、および展開を容易にするために設計されたクラウドサービスです。 AWS CodeStarには、ソフトウェア プロジェクトのコーディング、ビルド、テスト、デプロイ、および実行のためのプロジェクトとリソースのプロビジョニングを可能にする一般的な開発プラットフォーム用のプロジェクト テンプレートが含まれています。

 

AWS CodeStarサービスの主な利点は次の通りです:

  • Amazon EC2AWS Elastic Beanstalk、またはAWS Lambda用のテンプレートを使用して、5つの異なるプログラミング言語を使用して新しいプロジェクトを簡単に作成できます。 JavaScript、Java、Python、Ruby、およびPHPをサポートします。 テンプレートを選択すると、サービスはプロジェクトとアプリケーションに必要な基盤となるAWSサービスをプロビジョニングします。
  • ソフトウェアチーム全体に対するアクセスおよびセキュリティ ポリシー管理の統一されたエクスペリエンスを提供します。プロジェクトは、適切なIAMコントロール ポリシーで自動的に構成され、安全なアプリケーション環境を確保します。
  • コードのコミット、ビルドの結果、デプロイメント アクティビティなど、さまざまなアクティビティを追跡するための事前設定されたプロジェクト管理ダッシュボード。
    素早い立ち上げと実行に役立つ実行可能なサンプルコードは、Visual Studio、Eclipse、またはGitをサポートする任意のコード エディタなどのお好きなIDEで使用できます。
  • AWS CodeCommitAWS CodeBuildAWS CodePipeline、およびAWS CodeDeployを使用して、自動的に構成された各プロジェクトの継続的なデリバリ パイプライン。
  • CodeStarコンソールから課題管理とトラッキングを直接行えるAtlassian JIRA Softwareとの統合

 

AWS CodeStarによって、開発チームはソフトウェアのデプロイとバグ修正のスピードアップだけでなく、開発者が顧客の要望やニーズに一層合ったソフトウェアを構築できるようにするためのアジャイル ソフトウェア開発ワークフローを構築することができます。

 

AWS CodeStarを使用したレスポンシブな開発ワークフローの例を以下に示します:

CodeStarへの旅

 

AWS CodeStarサービスについて少し理解できたので、このサービスを使ってWebアプリケーションプロジェクトを設定しましょう。 まず、AWS CodeStar Consoleに行き、[Start a project]ボタンをクリックします。

適切なIAM権限を設定していない場合、AWS CodeStarはあなたのためにAWSリソースを管理する権限を要求するダイアログボックスを表示します。 [Yes、grant permissions]ボタンをクリックして、AWS CodeStarに他のAWSリソースへの適切な権限を与えます。

ところが、IAMユーザーに正しいポリシーを適用していないため、AWS CodeStarに対する管理者権限がないという警告が表示されました。 AWS CodeStarでプロジェクトを作成する場合は、IMSユーザーにAWSCodeStarFullAccess管理ポリシーを適用するか、すべてのAWSサービスに対して完全な権限を持つIAM管理ユーザーを持っている必要があります。

IAMで前述の権限を追加したので、このサービスを使ってプロジェクトを作成することができます。 単に [Create a new project]ボタンをクリックするだけで、AWS CodeStarサービスのハブに移動します。

この時点でソフトウェア開発のニーズに応じて、さまざまな環境を提供するために、20種類以上のAWS CodeStarプロジェクトテンプレートが用意されています。 各プロジェクトテンプレートは、プロジェクトの展開に使用されるAWSサービス、サポートされているプログラミング言語、実装されている開発ソリューションの種類の説明が記述されています。 AWS CodeStarは現在、Amazon EC2、AWS Lambda、AWS Elastic BeanstalkのAWSサービスをサポートしています。 これらのプロジェクト テンプレートは、あらかじめ設定されたAWS CloudFormationテンプレートを使用して、ボタンをクリックするだけで、マイクロサービス、Alexaスキル、Webアプリケーションなどのソフトウェア開発プロジェクトを作成できます。

私の最初のAWS CodeStarプロジェクトでは、Node.js / AWS Lambdaプロジェクトテンプレートを使用して、Node.jsとAWS Lambdaを使用してサーバーレスWebアプリケーションを構築しましょう。

このテンプレートによってAWS CodeStarがAWS CodeBuild、AWS CloudFormation、Amazon CloudWatchなどのサービスと連携するAWS CodePipelineを含む、開発プロジェクトに必要なすべてのツールとサービスを設定することに気づくでしょう。 新しいAWS CodeStarプロジェクトの名前をTaraWebProjectにして、Create Projectをクリックします。

ここではAWS CodeStarを初めて作成したので、AWS CodeStarのユーザー設定について質問するダイアログが表示されます。 表示名のテキストボックスにTaraと入力し、メールテキストボックスに自分のメールアドレスを追加します。 この情報は、プロジェクトの他のメンバーにどのように表示されるかを示しています。

次に、プロジェクトコードの編集方法を選択します。 Visual Studio IDEを使用してTaraWebProjectプロジェクトコードを編集することに決めました。 Visual Studioでは、プロジェクトコードの編集中にAWS Toolkit for Visual Studio 2015を使用してAWSリソースにアクセスするように設定することがポイントです。 この画面では、AWS CodeStarがプロジェクト用に設定したAWS CodeCommit Gitリポジトリへのリンクも表示されます。

ソフトウェア開発プロジェクトのプロビジョニングとツールのセットアップが完了しました。 私のソフトウェアプロジェクトであるTaraWebProjectのAWS CodeStarダッシュボードを提示されているので、プロジェクトのリソースを管理することができます。 これには、コードのコミット、チームメンバーシップとwiki、継続的なデリバリ パイプライン、Jiraの課題トラッキング、プロジェクトステータス、およびその他の適用可能なプロジェクトリソースなどのリソース管理が含まれます。

AWS CodeStarが本当にすばらしいのは、サーバレスWebアプリケーションの開発を開始できる実用的なサンプルプロジェクトを提供することです。 私の新しいWebアプリケーションのサンプルを見るには、ダッシュボードのApplication endpointsセクションに行き、提供されたリンクをクリックします。

新しいブラウザウィンドウが開き、開発を開始するためにAWS CodeStarが生成したサンプルWebアプリケーションが表示されます。サンプルアプリケーションのクールな機能は、サンプルアプリのバックグラウンドが時刻に基づいて色が変わることです。

サンプルWebサイトの構築に使用したコードを見てみましょう。 コードを表示するには、AWS CodeStarコンソールのTaraWebProjectダッシュボードに戻り、サイドバーメニューからCodeオプションを選択します。

AWS CodeCommitコンソールのtarawebproject Gitリポジトリに移動します。 ここから自分のWebアプリケーションのコード、リポジトリで行われたコミット、コミットやブランチの比較、リポジトリのイベントに応じたトリガーの作成を手動で行うことができます。

これによりAWSでホストされているWebアプリケーションの開発を開始することができます。 AWS CodeStarをVisual Studioに統合したので、コードを変更するためにIDEを使用してWebアプリケーションを更新することができます。これによってプロビジョニングされたコード リポジトリにコミットするたびにTaraWebProjectに含まれるコードを毎回自動的更新できます。

AWS CodeStarのTaraWebProjectダッシュボードには、コードを操作するためにツールをプロジェクト リポジトリに接続していますというメッセージがあります。 Visual StudioをIDEとして既に選択していますが、Connect ToolsボタンをクリックしてこのIDEに接続する手順を確認してみましょう。

再度、どのIDEを選択するかを選択できる画面を参照します。 Visual Studio、Eclipse、またはコマンドライン ツールがプロジェクト コードの編集に使用できます。 開発プロジェクトの作業中はいつでもIDEの選択肢を変更するオプションがあることが重要です。 さらに、HTTPSとSSH経由のGitでAWS CodeCommitリポジトリに接続できます。 各プロトコルの適切なリポジトリURLを取得するには、Code repository URLドロップダウンを選択してHTTPSまたはSSHを選択し、結果のURLをテキストフィールドから単にコピーするだけです。

Visual Studioを選択した後、CodeStarはVisual Studioとの統合に必要な手順に進みます。 これには、Visual Studio用のAWS Toolkitのダウンロード、Team ExplorerをAWS CodeCommitを介してAWS CodeStarに接続すること、および変更をリポジトリにプッシュする方法が含まれます。

Visual StudioをAWS CodeStarプロジェクトに正しく接続したら、AWS CodeStar TaraWebProject CodeStarダッシュボードに戻り、Webアプリケーションで作業しているチームメンバーの管理を開始します。 Setup your teamを選択して、プロジェクトチームページに行くことができます。

私のTaraWebProjectプロジェクトチームページでは、Add team member ボタンを選択し Select userドロップダウンをクリックして、チームメンバーのJeffを追加します。 チームメンバーは自分のアカウントのIAMユーザーでなければならないので、JeffのIAMアカウントを作成するには、Create new IAM userリンクをクリックします。

Create IAM user ダイアログボックスが表示されたら、チームメンバー(この場合はJeff Barr)のIAMユーザー名、表示名、電子メールアドレスを入力します。 Jeffに付与できるプロジェクトロールには、所有者、コントリビュータ、ビューアの3種類があります。 TaraWebProjectアプリケーションでは、Contributor プロジェクト ロールを付与し、Remote accessチェックボックスをオンにしてリモートアクセスできるようにします。 ここでは、[Create]ボタンをクリックしてJeffのIAMユーザーアカウントを作成します。

これにより、新しいIAMユーザーの作成を確認するIAMコンソールが表示されます。 IAMユーザー情報と許可されたアクセス許可を確認した後、[Create user]ボタンをクリックして、TaraWebProject用のJeffのIAMユーザーアカウントの作成を完了します。

Jeffのアカウントを正常に作成したら、Jeffのログイン資格情報を電子メールで送信するか、credentials.csvファイルをダウンロードすることが重要です。これらの資格情報を再度取得することはできません。 現在のログイン資格情報を取得せずにこのページを終了すると、Jeffの新しい資格情報を生成する必要があります。 [Close]ボタンをクリックすると、AWS CodeStarコンソールに戻ります。

JeffBarr-WebDev IAMロールを選択し、[Add]ボタンをクリックすることで、TaraWebProjectのチームメンバーとしてJeffを追加することができます。


私はジェフをAWS CodeStarプロジェクトのチームメンバーとして追加し、Webアプリケーションを構築する際にTaraWebProjectのチームコラボレーションを可能にしました。

私がAWS CodeStarサービスを本当に気に入っているのは、TaraWebProjectダッシュボードから自分のプロジェクトのすべてのアクティビティを監視できるからです。 アプリケーションのアクティビティや最近のコードのコミットを見ることができ、ビルドの結果、コードの変更、展開などのプロジェクトアクションの状態を1つの包括的なダッシュボードで追跡できます。 AWS CodeStarはダッシュボードのApplication activityセクションでAmazon CloudWatchと結びつけ、AWS CodePipelineに連携したContinious Deploymentセクションでビルドとデプロイメントのステータスに関するデータを提供し、Commit HistoryセクションでAWS CodeCommitのの最新のGit コードのコミットを表示します。


まとめ

AWS CodeStarサービスの旅で、AWSサービスを使用してTaraWebProjectソフトウェアプロジェクトのコーディング、ビルド、テスト、デプロイメント用に開発ツールチェーン全体をプロビジョニングしたサーバーレスWebアプリケーションを作成しました。 驚くべきことに、私はアプリケーションをリリースする日々のソフトウェア開発活動を管理するためのAWS CodeStarを使用するメリットについて、まださらっと表面をなめただけです。

AWS CodeStarを使用すると、AWS上でアプリケーションを迅速に開発、構築、および展開できます。 AWS CodeStarは、統一されたユーザーインターフェースを提供し、ソフトウェア開発活動を1か所で簡単に管理できるようにします。 AWS CodeStarでは、さまざまなテンプレートからAWS LambdaAmazon EC2AWS Elastic Beanstalkを使用してプロジェクトを設定することができます。 AWS CodeCommitAWS CodeBuildAWS CodePipeline、およびAWS CodeDeployを使用して、プロジェクト管理ダッシュボード、自動化された継続的デリバリ パイプライン、およびGitコードリポジトリが事前設定されており、開発者は最新のアジャイル ソフトウェア開発のベストプラクティスを実装できます。各AWS CodeStarプロジェクトは、Gitをサポートする一般的なIDEで使用できる実用的なコードサンプルを提供することにより、開発者に開発の最前線を提供します。加えてAWS CodeStarのAtlassian JIRA Softwareとの組み込みの統合機能によって、AWS CodeStarコンソールからダイレクトに連携するプロジェクト管理と課題追跡システムをソフトウェアチームに提供します。

AWS CodeStarサービスを使用して、AWSで新しいソフトウェア プロジェクトを開発することができます。 詳細については、AWS CodeStarの製品ページとAWS CodeStarのユーザーガイドのドキュメントを参照してください。
Tara

 

原文 New- Introducing AWS CodeStar – Quickly Develop, Build, and Deploy Applications on AWS (翻訳;SA 福井 厚)

AWSでの疎結合データセットの適合、検索、分析

あなたは刺激的な仮説を思いつきました。そして今、あなたは、それを証明する(あるいは反論する)ためにできるだけ多くのデータを見つけて分析したいと思っています。適用可能な多くのデータセットがありますが、それらは異なる人によって異なる時間に作成され、共通の標準形式に準拠していません。異なるものを意味する変数に対して同じ名前を、同じものを意味する変数に対して異なる名前を使用しています。異なる測定単位と異なるカテゴリを使用しています。あるものは他のものより多くの変数を持っています。そして、それらはすべてデータ品質の問題を抱えています(例えば、日時が間違っている、地理座標が間違っているなど)。
最初に、これらのデータセットを適合させ、同じことを意味する変数を識別し、これらの変数が同じ名前と単位を持つことを確認する方法が必要です。無効なデータでレコードをクリーンアップまたは削除する必要もあります。
データセットが適合したら、データを検索して、興味のあるデータセットを見つける必要があります。それらのすべてにあなたの仮説に関連するレコードがあるわけではありませんので、いくつかの重要な変数に絞り込んでデータセットを絞り込み、十分に一致するレコードが含まれていることを確認する必要があります。
関心のあるデータセットを特定したら、そのデータにカスタム分析を実行して仮説を証明し、美しいビジュアライゼーションを作成して世界と共有することができます。
このブログ記事では、これらの問題を解決する方法を示すサンプルアプリケーションについて説明します。サンプルアプリケーションをインストールすると、次のようになります。

  • 異なる3つのデータセットを適合させて索引付けし、検索可能にします。
  • 事前分析を行い、関連するデータセットを見つけるために、データセットを検索するための、データ駆動のカスタマイズ可能なUIを提示します。
  • Amazon AthenaAmazon QuickSightとの統合により、カスタム解析やビジュアライゼーションが可能です

(more…)

AWS CodePipeline, AWS CodeBuild, Amazon ECR, AWS CloudFormationを利用したAmazon ECSへの継続的デプロイメント

同僚のJohn PignataがAmazon ECSに対する継続的デプロイメントパイプライン作成方法について素晴らしいブログを書いてくれました。

今日のビジネス環境では、新しいソフトウェアの反復を高速で提供することは競合に対するアドバンテージになります。企業がイノベーションを顧客に提供するスピード、変化する市場に適応するスピードは、ますます成功と失敗の違いを生む重要な要素になっています。

AWSは、企業がアプリケーションやサービスを高速に提供する組織の能力を向上させるDevOpsと呼ばれる文化哲学、実践、ツールの組み合わせを企業が採用できるように設計された一連の柔軟なサービスを提供します。

このポストでは、継続的デプロイメントと呼ばれるデプロイの実行方法について説明し、AWS CodePipeline、 AWS CodeBuild、および AWS CloudFormationを使用してAmazon ECS上のDockerコンテナとして提供されるアプリケーションの自動デプロイメントパイプラインを実装するためのリファレンスアーキテクチャの概要を説明します。

継続的デプロイメントとは?

俊敏性は、ITリソースのトラディショナルな提供方法に比べてクラウドコンピューティングが持つ重要な利点としてよく引用されています。他の部門が新しいサーバーをプロビジョニングするのに数週間か数ヶ月待つ代わりに、開発者はシングルクリックやAPIコールで新しいインスタンスを作成することができ、数分で使用開始することができます。この新たな速度と自律性は、開発者が新しい製品や機能を試し、できるだけ早く顧客に提供するこを可能にします。

製品の市場投入期間を短縮し、コードの品質を向上させ、より信頼性の高い製品やサービスのリリースを実現するために、開発チームはクラウド上でDevOpsの実践を採用しています。 継続的デプロイは、新しいソフトウェアリビジョンが自動的にビルドされ、テストされ、パッケージ化され、本番環境にリリースされる、DevOpsの実践です。

継続的デプロイにより、開発者は完全に自動化されたソフトウェアリリースプロセスを通じて機能や修正を出荷できます。開発者は、数週間や数ヶ月にわたる大規模なリリースをバッチ処理し、手動で展開する代わりに、新しいソフトウェアリビジョンが準備され次第、自動化されたプロセスを使用してアプリケーションのバージョンを1日に何回も配信することができます。クラウドコンピューティングがリソースの調達期間を短縮するのと同様に、継続的デプロイは新しいソフトウェアのリリースサイクルを数週間~数ヶ月から数分間に短縮します。

このスピードと敏捷性を活用することには、次のような多くの利点があります。

  • 新機能やバグ修正を迅速にすることができる :  ソースコードリポジトリに置いてあるコードは、ビジネス価値をもたらしたり、顧客に利益をもたらすものではありません。新しいソフトウェアリビジョンをできるだけ早くリリースすることで、顧客はより迅速に利益を享受できるようになり、チームはより集中的なフィードバックを得ることができます。
  • 変更セットが小さくなる : 大きな変更セットは、問題、バグ、およびその他の退化の根本原因を突き止める際に問題を引き起こします。より小さな変更セットを頻繁にリリースすることで、チームは発生した問題をより簡単に特定して修正することができます。
  • 自働デプロイによりベストプラクティが促進される : ソースコードリポジトリにコミットされた変更は即座に自動プロセスによってデプロイすることができるため、チームはその変更が十分にテストされ、運用環境が厳重に監視されていることを確実にする必要があります。

継続的デプロイはどのように動くのか?

継続的デプロイは、ソフトウェアのリリースに関連する活動を調整する自動化されたパイプラインによって実行され、プロセスの可視性を提供します。プロセスの最中に、リリース可能な成果物が構築され、テストされ、パッケージ化され、本番環境にデプロイされます。リリース可能な成果物には、実行可能ファイル、スクリプトファイルのパッケージ、コンテナ、または最終的にプロダクションに配信されなければならないその他のコンポーネントが含まれます。

AWS CodePipelineは、新しいソフトウェアリビジョンができるたびにコードのビルド、テスト、およびデプロイを実行する継続的デプロイおよび継続的デリバリーのサービスです。 CodePipelineは、コード変更の統合、可視化を行い、ワークフローを介して最終的にユーザーの提供します。このパイプラインは、ソースコードリポジトリからのコード取得、ソースコードのビルド、テスト、および本番環境へのデプロイといったステージを定義し、これらのステージが順番に実行されること、障害が発生した場合には停止することを保証します。

CodePipelineはデリバリパイプラインを強化し、プロセスを統合しますが、ソフトウェア自体をビルドまたはテストする機能はありません。このステージでは、CodePipelineは、フルマネージドのビルドサービスであるAWS CodeBuildなど、いくつかのツールと統合されます。 CodeBuildはソースコードをコンパイルし、テストを実行し、デプロイする準備が整ったソフトウェアパッケージを生成します。このサービスは継続的なデプロイパイプラインの構築とテストに最適です。CodeBuildはDockerコンテナのビルドを含む多くの異なる種類のビルド環境をネイティブサポートしています。

コンテナは、予測可能で再現可能な環境を実現し、ある環境でテストされた変更が正常に展開できるという高いレベルの信頼性を提供するため、ソフトウェア提供の強力なメカニズムです。 AWSは、Dockerコンテナイメージを実行・管理するためのいくつかのサービスを提供しています。 Amazon ECSは、非常に高い拡張性とパフォーマンスを持つコンテナ管理サービスで、Amazon EC2インスタンスのクラスタ上でアプリケーションの実行環境を提供します。  Amazon ECRは、フルマネージドのDockerコンテナレジストリで、開発者は簡単にDockerコンテナイメージの格納、管理、およびデプロイが可能です。

最後に、CodePipelineはデプロイメントを容易にするために、AWS Elastic Beanstalk、AWS CodeDeploy、AWS OpsWorksや、AWS LambdaまたはAWS CloudFormationを使用した独自のカスタムデプロイメントコードやデプロイプロセスなど、いくつかのサービスと統合されます。これらのデプロイアクションを使用してパイプラインの最後に新しく構築された変更を本番環境にプッシュすることができます。

Amazon ECSへの継続的デプロイ

これらのコンポーネントを組み合わせて、Dockerアプリケーションの継続的なデプロイパイプラインをECSに提供するためのリファレンスアーキテクチャを次に示します。

このアーキテクチャーは、CodePipelineを使用してECSおよびECRにコンテナをデプロイし、AWS上でフルマネージドの継続的デプロイパイプラインを構築する方法を示しています。この継続的デプロイのアプローチは、完全にサーバーレスであり、ソフトウェアの統合、ビルド、およびデプロイにマネージドサービスを使用します。

リファレンスアーキテクチャで作成されたパイプラインは、次のようになります。

このポストでは、このリファレンスアーキテクチャの各ステージについて説明します。開発者がランディングページの原稿を変更し、その変更をソースコードリポジトリにプッシュするとどうなるでしょう?

まず、Source ステージでは、ソースコードリポジトリシステムにアクセスするための詳細がパイプラインに設定されます。リファレンスアーキテクチャでは、GitHubリポジトリにホストされているサンプルアプリケーションがあります。 CodePipelineはこのリポジトリをポーリングし、新しいコミットごとに新しいパイプラインを実行開始します。 GitHubに加えて、CodePipelineは、AWS CodeCommitのGitリポジトリやAmazon S3に格納されたバージョン管理されたオブジェクトなどのソースロケーションもサポートしています。新しいビルドはそれぞれソースコードリポジトリから取得され、zipファイルとしてパッケージ化され、S3に格納され、パイプラインの次のステージに送られます。

Sourceステージでは、Amazon S3に格納されているテンプレートも定義されます。これは、アプリケーションのビルドが成功した後に、デプロイメントステージで使用されるデプロイメント環境を定義するテンプレートです。

Build ステージではCodeBuildを使用して、最新のソースコードに基づいて新しいDockerコンテナイメージを作成し、ECRリポジトリにプッシュします。 CodePipelineは、Jenkins、CloudBees、Solano CI、TeamCityなどのサードパーティのビルドシステムとも統合されています。

最後に、DeployステージではCloudFormationを使用して、新しく作成されたDockerコンテナイメージを指す新しいタスク定義リビジョンを作成し、新しいタスク定義リビジョンを使用するためにECSサービスを更新しています。こうすることで、ECSは新しいDockerコンテナをECRから取得し、サービスを再起動することによってデプロイを開始します。

パイプラインのステージがすべてグリーンになったら、Webブラウザでアプリケーションをリロードして、開発者の原稿の変更を本番環境で確認することができます。これは人手での作業は何もしなくても自動的に実行されます。

このパイプラインはすでにプロダクション状態であり、ソースコードリポジトリから新しいコードを取得し、チームがプロダクションにプッシュする将来の変更を出荷する用意ができています。また、拡張可能なので、新しいステップを追加して追加のステージを含めることもできます。たとえば、新しいコードリビジョンが本番環境に安全にデプロイされることを確認するために、テストステージを組み込んでユニットテストと受入テストを実行することができます。デプロイ後、新しいバージョンが稼動したことおよび、本番環境にデプロイされた変更セットの詳細について、電子メールまたはSlackチャンネルでチームにアラートを送るための通知ステップも追加することができます。

最後に

私たちはこのアプローチを使用してあなた方がどのような種類のアプリケーションをユーザーに提供できるのか、またそれが製品開発プロセスにどのような影響を及ぼすのかを見せていただけることを楽しみにしています。クラウドは俊敏性において大きなメリットを発揮し、継続的デプロイなどの技術を実装する能力は、競争上の大きな利点を生み出します。

GitHub上のAWS Labs EC2 Container Service – Reference Architecture: Continuous Deploymentリポジトリには、独自の継続的デプロイパイプラインを起動するために必要なすべてのものを含むAWS CloudFormationテンプレートがあります。

ご質問、ご意見、ご提案がありましたら是非お知らせください!

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