[レポート] AWS FargateとECSにおけるCI/CDのベストプラクティス #CON333 #reinvent

この記事はCON333 Best practices for CI/CD using AWS Fargate and Amazon ECSのレポートです。 Amazonにおけるデプロイパイプラインを例にCI/CDのベストプラクティスについて紹介します。
2019.12.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

この記事はCON333 Best practices for CI/CD using AWS Fargate and Amazon ECSのレポートです。 動画はこちらで公開されています。

セッション概要

CI/CD techniques enable teams to increase agility and quickly release a high-quality product. In this talk, we walk you through the best practices for building CI/CD workflows to enable you to manage your containerized applications. We cover infrastructure as code application models with the AWS Cloud Development Kit, and we show you how to set up CI/CD release pipelines with AWS CodePipeline and AWS CodeBuild. Finally, we discuss automating safer deployments using AWS CodeDeploy.

スピーカー

  • Clare Liguori - Principal Engineer, Amazon Web Services
  • Hsing-Hui Hsu, Amazon Web Services

CI/CDにおけるベストプラクティス

  1. 自動化されたリリース
  2. 安全なデプロイ
  3. 繰り返し変更可能なインフラ

1. 自動化されたリリース

  • Amazonでは 12ヶ月で1億9000万回、1秒に6回デプロイが行われている
  • もちろん1億9000万人ものエンジニアがいるわけではないので自動化が行われている
  • Amazonにおけるデプロイのパイプライン
    • Source(アプリのコード、インフラコード) -> Build -> Artifacts -> Preproduction -> Production
    • preproductoinはalpha, beta, gammaの3環境が存在しそれぞれで異なる自動テストを行う
      • Alpha 自動テスト(almost brokenらしい)
      • Beta 自動結合テスト、負荷テスト、パフォーマンス、ブラウザテスト
      • Gamma 自動結合テスト, synthetic, smoke test
    • Productionへのリリースは段階的に行う, リージョン内の1%, 10%→1リージョン全て→他リージョン
  • このようなパイプラインを構築するには次のようなツールを使う
    • AWS CodePipeline
    • GitHub Action
    • Jenkins
    • Spinnaker

CodePipelineでのパイプラインの構築

  • ソース: 最新のコードをpullしてリリースをトリガーする
    • Git上のブランチを指定(CodeCommit, GitHubをサポート)
    • S3
    • Amazon ECR(Docker tag)
  • ビルド: AWS CodeBuild for containers
    • フルマネージドなビルドサービス
    • Docker イメージのビルド、プッシュ、バリデーションが行える
    • 全ての公式CodeBuilderイメージにはDocker CLI, AWS CLIが組み込まれている
    • Amazon ECRへのプッシュ用のロールも設定できる
    • 新機能
    • Amazon ECR immutable image tags
    • Amazon ECR Image scanning
  • テスト: テスト環境へデプロイ
    • アプリのイメージ以外にもサイドカーのイメージをECRに登録してデプロイを自動化できる
    • ECR上の特定のタグ(e.g. release)が更新された起動するパイプラインを作成する
  • プロダクション: プロダクションへのデプロイ

安全なデプロイ

Amazonでのデプロイにおける安全バー

  1. アラームとテストでの検証での自動的なロールバック
  2. 素早いロールバック
  3. "Bake" after deployment; あるデプロイが完全に完了して異常がないのを確認するための期間を設ける
  4. 段階的なデプロイ

CodeDeploy

  • EC2、Lambda, ECSサービスへのデプロイの自動化
  • ダウンタイムなしでのデプロイ
  • エラーを検知してロールバック
  • トラフィック制御によって顧客への影響を限定化できる

CodeDeploy ECSでのblue-green deployment

  • タスク(tasks)とALBターゲットグループを使ってblue green deploymentが行える
  • Lambdaで記述するテストかCloudWatch Alarmをトリガーとしてロールバック
    • テストはLambda関数で記述してappspecで指定する
    • デプロイグループの設定でCloud Watch Alarmを指定する
  • 切り替えの流れ
    • テスト用のリスナーに紐づくターゲットグループ(Green)と新しいタスクでテストする
    • テストが成功したらプロダクション用のリスナー(Blue)を新しいタスクに向ける
    • 元のプロダクションtaskは起動したままなのでエラー時には迅速にロールバックできる
  • "Bake time" はデプロイグループの設定で指定する(terminationwaitTimeInMinutes)

繰り返し変更可能なインフラ

  • 手作業による複数環境の構築は設定ミスを招く可能性がある
  • CloudFormationを使ってインフラ設定を自動化する
  • CloudFormationテンプレートファイルをアプリと同じリポジトリで管理する
    • ビルドステップで作成されたdockerイメージタグをテンプレートのタスク定義に埋め込む
    • デプロイ時にCloudformationを実行してインフラを変更する
    • テスト、プロダクションの両方で変更後のインフラ上でテストが実行される
    • 動作しているアプリとインフラの両方のトレースができる
  • CloudFormationのYAMLテンプレートは冗長になりがちなのでCDKの使用をおすすめ
  • 好みの言語で記述でき、記述量もYAMLよりも少ない
  • 同じ構成のリソースを複数作成するのも容易

DEMO

reinvent-triviaのバックエンドをblue-green deploymentを行い、エラー時の自動ロールバックをデモしていました。

パイプラインなどを含めたコードはGitHubで公開されています

最後に

コンテナでのCI/CDパイプラインについては今までなんとなくイメージはあったのですが、コードやデモを交えた説明を聞くことで具体的なイメージを持つことができました。