継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

データ分析における収集とその活用の取り組みを『Data Engineering Study #2』で聞いた

タダです.

前回「Data Engineering Study #1 」に続き「Data Engineering Study #2 」が開催されたので参加してきました.今回の記事では発表を聞いて感じたことやメモをとった内容をまとめていきます.

forkwell.connpass.com

イベント概要

第1回勉強会では「DWHとBIツール」の選び方について学びました。

これらはデータを扱うためのツールですので、当然「データ」そのものを集めないといけません。実は大容量データの取り扱いには専門的な知識が要求されます。

今回の勉強会では、データを集めるための基盤の話と、集めたデータをビジネス活用しやすい状態に整備する方法の、2つのテーマについて学びます。

基調講演には「前向きデータ整備人」勉強会主催者のしんゆう氏をお招きし、今回のテーマの概論をお話し頂いた後、実際にデータ収集・整備を行われている2社の事例から学んでいきます。

本編動画

当日のツイートまとめ togetter.com

基調講演「事業に貢献するデータ基盤を作ろう・考え方編」

データアーキテクト(データ整備人)を”前向きに”考える会」で知っていたしんゆうさんの発表でした.しんゆうさんといえば,note でも情報発信されています

発表を聞いての所感

発表を聞いて,データ基盤がなぜ必要で「データ整備」の工程でどんなことをしていてこの工程がないとどう苦労するのかを調理でたとえてくださったのですがわかりやすかったです.前回の勉強会でもありましたが,基盤を作ったが使われない事態を回避するためにも「データ整備」の工程が必要なんだと感じました.

発表メモ

  • なぜデータ基盤を作るのか
    • データ基盤の意義をプロセスから考えるとデータ収集はデータから知りたいことのために必要なデータを集める仕組みづくり(=データ基盤)
      • データ基盤はデータ分析プロセスの中の収集フェーズを速やかかつ正確に行うための仕組みのこと
  • 価値のないデータ基盤を作らないためにはどうするか
    • 使われない時に問うべきは利用者のニーズを満たせてなかったのではないかを問う
    • 利用者のニーズはデータで何が知りたいのかをつかむことから始める
  • 基盤と利用のバランスをとる
    • 作ることが目的になったら利用まで繋がらない
      • 基盤構築と基盤の利用との間に必要なプロセスがある
  • 基盤と利用の間の役割
    • 基盤と利用の間の役割として必要なデータを集めて,必要なデータを整理してデータの不備がないかを基盤作る人と相談
      • 基盤と利用までの間のアクションを「データ整備」とする
  • データを整備しないとどうなるか
    • データを整備する人がいないとデータを使ってやりたいことをするために必要な情報が整ってないから都度処理することになり大変

質疑応答

  • 初期フェーズのスタートアップの分析基盤を考える時どんな構成にするか
    • データで何を知りたいかを把握する
      • 基盤を作ることにコストをかけずミニマムな構成で作った方が良い
  • 初学者の勉強方法はあるか
    • 基盤の整備はここ数年くらいのトピックなので知っている人について学ぶのがいい
    • しんゆうさんはどう学んできたか
      • 周りの人を見ながら自分が何をやるべきかを選定する
      • イベントの登壇者に声かけていくのがいいと思う
  • データ整備後の保守運用について
    • いかにエラーチェック体制をとれるか
      • テーブルチェックしてエラーが出たらアラートチェックする等

発表資料

事例紹介1「データ収集の基本とJapanTaxiにおける実践例」

JapanTaxi 社の渡部さんの発表です.個人的に渡部さん著の「ビッグデータ化分析のシステムと開発がこれ一冊でしっかりわかる教科書」を読んだのですが,インフラからデータエンジニアへのキャリアを形成していきたいと思っているので関連トピックをさらえて勉強になりました.そんな渡部さんの発表は第2回のイベントが発表された時から気になっていました.

発表を聞いての所感

当日の Twitter の反応でもそうでしたがデータ収集における教科書のような内容で,収集するデータの種類,ファイルの形式,収集方法,実践例,注意点が詳細に整理されており僕もデータ収集フェーズを担当するようになったら何度もお世話になるだろうと思いました.注意点も含蓄ある内容で多くのご経験からお話しされていてウンウンととても勉強になりました!

発表メモ

  • データ収集はシステム内で赤枠の範囲で考える

  • データソースの種類と収集方法については下記のページで頻度,データソース,収集例,収集方式がまとまっておりわかりやすい

  • データの収集方法は次の通り
    • ファイルで収集する方法
      • 最も多いパターンは CSV と TSV
    • API コールで収集する方法
      • 実行制限がある場合が多いので注意が必要
    • DB から収集する方法(SQL / エクスポート/ダンプ/更新ログ/CDC)
    • エージェントを利用した収集
    • 分散キューを使った収集
  • Japan Taxi でのデータ収集実践例
    • 図解化されているが,データ収集の節で説明した様々な方法を組み合わせ実現している

  • データ収集の注意点
    • ETL 製品はたくさんあるためどのように付き合うか
      • 選定基準を設ける
        • 入出力プラグインの数ではなくプラグインの機能の充実度
        • デバッグできること(エラーが出た時に解決できる可能性があがる)
                * プログラマ向けのカスタマイズ可能なものを選ぶ
                * 合うものがない時は自作する
          
    • データソースの変更対応
      • トップダウンでデータソースの変更連絡を徹底させる
        • 社内でデータ活用の民意を得ている必要があるため,実行できている例は少ない
      • 事業システムの変更を機械的に知るほうが実践しやすい
    • データ収集の優先度を考える
            * データ収集チームが作られた要注意
      
      • 目的がわからない取り組みはやめ,事業インパクトを理解してデータ収集に優先順位をつける

質疑応答

  • 押し付けあいになりやすいデータ整備する泥臭いタスクを組織的に前向きになれるようにどう取り組んでいるか
    • 可能なら利用チームに入って分析する
    • データ分析の目標値を決めていく
  • データマネジメント/ガバナンスについてインフラエンジニアとしてシステムとプロセスの点で留意している点はあるか
    • メタデータをかけてシェアする場所を用意する
      • 情報を一元化して管理がしやすくなる
      • データの持ち主と説明がわかってればデータ管理上わからなくなるぽくないことは少なくなる
    • クエリログをとるのが重要
      • 使われてないテーブルがわかって影響の有無がわかる
  • こういうデータ取りたいけど,結構めんどくさいケースはあるか
    • 利用の事業部が離れていて知り合いがいなかったり,データ利用するのが別会社だったりして誰に話していいかわからない
      • 上記の場合は調整できる人をいれたりして対応する

発表資料

関連書籍

事例紹介2「メルカリJPにおける分析環境の整備」

事例2つ目はメルカリ社の永井さんの発表です.この発表ではデータ収集後,①データの整備で改善になぜ取り組み,改善のサイクルを回して理想と現実を埋める理由と②レガシーデータセットを廃棄する取り組みをお話しされました.

発表を聞いての所感

メルカリ社はデータ基盤の運用上の2つの課題の話でした.データ基盤を作って終わりではなくなんとなく回っているから良いのではなく改善を行なって社員の生産性の向上や自分たちの時間を生み出すことに努めているのだなと思いました.改善を回すのも現状の課題や利用状況を可視化して把握,利用者がどんな利用形態を求めているのかを確認して対応されていたのは参考になりました.

発表メモ

  • なぜ改善を回すか
    • 基盤は BigQuery と LOOKER
    • なぜ改善に取り組むのか -> たくさんのデータ分析の業務があるため,分析環境の改善が生産性の改善につながる
  • 理想形:改善を回し続けられるようにしたい
    • 避けたいことは改善に取り組まない -> 現状維持でじわじわ大変 -> 改善に使える時間が減少
    • やりたいことは改善に取り組む -> 現状維持が楽になり改善に使える時間が増えて十分な余裕を作って攻めの改善もできる
  • 取り組み:レガシーなデータセットを廃止する
    • 2つのデータパイプライン問題
      • 本番の元テーブルから BigQuery の分析用テーブル(新とレガシー)が2つある
      • メンテナンスコストがかさむしテーブル間の数字のズレがあった
    • レガシーなテーブルがなぜ必要かの業務理解とKPIの要件を調べていくことでレガシーシステムの廃止に向けて取り組んだ
      • GMV(流通取引総額)の見方としてどう集計したいかを確認したところ新しいデータパイプラインで賄えそうだとわかった
  • 取り組みのポイント
    • データ基盤はどう集計したいかの要件(指標や業務の内容)によって依存するので基盤だけで問題を考えない
  • 取り組みの範囲を絞り込む
    • テーブル別で参照ユーザー数を見て使っている人の人数によって改善箇所をきめていくとよい(人気のテーブルとそうでないテーブルで利用者数に100倍の差がある

質疑応答

  • データ整備におけるスピードと品質の両立についてどう取り組んでいるか
    • スピードと品質のトレードオフがあると思っていて品質を重視する
    • データは目に見えない依存関係(会議や意思決定など)があると思っていて変更や廃止は容易でなかったりするので品質ばっちりなものを出すと運用負荷が低くなる
  • データ分析基盤のリファクタリングについてタイミングや進め方のコツ
  • データ分析基盤づくりの時の運用や変更のしやすさをユーザとエンジニア間で調整が大変でどのように変更予想や調整しているか
    • なるべく変更を発生しないようにする工夫として不可逆的な変更はなるべく後回しにする

発表資料

まとめ

Data Engineering Study #2 」で聞いた発表ごとに所感と発表メモ,質疑応答の内容をまとめていきました.次回のイベントも公開されており,次は分析基盤の組織にどう浸透させていくかにフォーカスした内容のようです.基盤を使っても使われなかったりすると意味ないのでどう普及させるかを聞けるのかと思うと次回も楽しみですね!

forkwell.connpass.com

関連記事

前回の参加レポート sadayoshi-tada.hatenablog.com

データレイクの基礎から構築と運用の視点を学べる『AWS ではじめるデータレイク』を読んだ

タダです.

データレイクの設計や構築,運用の勉強をしたいと思い「AWS ではじめるデータレイク」を読んだので,書評記事を書いていきます.

公式サイト techiemedia.co.jp

物理本

PDF版 booth.pm

目次

本書は以下の章立てになってます.

  • 序章 データレイクを始めよう
  • 第1章 データレイクの構築
  • 第2章 データレイクの活用
  • 第3章 データレイクの運用
  • 第4章 データレイクのセキュリティ
  • 第5章 ハンズオンの概要 ービジネスデータのデータレイクー
  • 第6章 データを可視化する
  • 第7章 サーバーレスSQLによるデータ分析
  • 第8章 データを変換する
  • 第9章 データを分析する(データウェアハウス)
  • 第10章 システムの概要 ーログデータのデータレイクー
  • 第11章 ログを集める
  • 第12章 ログの保管とカタログ化
  • 第13章 ログを加工する
  • 第14章 ログを分析する

本書の概要

本書は3パートの構成になっています.第一部でデータレイクとはどういった技術のことか,その周辺課題はどんなものがあり,その課題を AWS で解決するならどのサービスを利用・組み合わせれば良いかが解説されます.第二,第三においては,一部で説明された AWS のデータレイクで関係するサービス群をハンズオン形式で使って学ぶパートになっています.ハンズオンパートは GUICLI を使って進行するためアカウントの準備とAWS CLI のセットアップを予め行いましょう.

  1. データレイクとの概念と知識
  2. データレイクの実践(基礎編)
  3. データレイクの実践(応用編)

本書で学べること

本書で学べると感じたことを箇条書きで列挙します.

  • データレイクの技術要素の概要および関連サービスの理解
    • データレイクの技術が登場した背景やデータレイクの検討観点
    • データレイクの全体像およびデータの収集→保存→変換→可視化といった一連のフローおよび AWS のサービス紹介
  • データレイクの運用時の課題の理解
    • データレイクを運用する際に考慮する監視や障害対応,バックアップ,SLA をどう定めるか等の課題とその対処について解説
  • データレイクのセキュリティの検討課題の理解
  • データレイク関連の AWS サービスの利用方法
    • 基礎編では QuickSight,Athena,Glue,Redshift を使ってサンプルデータの解析,可視化,サービス間連携方法を学ぶ
    • 応用編ではサンプル Web システムのログデータを使ってログを収集→保管→加工→分析の工程で各サービスを組み合わせて学ぶことができる
      • 応用編で使うサービスとして, ALB,EC2,AutoScaling,EFS,Aurora,CloudWatch Logs,Kinesis Data Firehose,S3,Glue,Athena,SageMaker,LakeFormation,QuickSight がでてくる

読了後の所感

本書を読んでまず,僕のようなデータレイクを構築したことがないけど AWS のことを知っているレベルからデータレイクも AWS もこれから勉強したい人,AWS でデータレイクを扱っているけど専門書を求めていた人など幅広い読者層のニーズに応える入門書であり実践書だと感じました.

個人的には Glue,Redshift は使用経験が乏しかったので第二部はハンズオンパートは勉強になりましたし,データレイク関連のマネージドサービスの使い方やオプションの説明があるのは利用検討している人に判断材料になりやすい内容だなと思います.また,第三部の応用編では実際のユースケースでありそうなログを使ってデータの収集→保管→加工→分析を行うためにどのサービスを使って,どんな設定をすればいいのかがさらえます.

本書の最後で触れられていますが,本を読んだからといってデータレイクのトピックを網羅したというわけではなく理解を深めるのを助ける別の書籍が紹介されます.僕自身も足りない知識は紹介された本をみて学んでいきたいと思います.

まとめ

AWS ではじめるデータレイク」の書評を書きました.読み終えて再度読み直して行こうと思ったのですが,もう一度とは言わず,何度も読み直すだろうと思うので机の本棚においていつでも見えるようにするくらいには自分にはどハマりの書籍でした!,本書の出版に際して全4回のイベント資料が上がっています.本書の内容が気になる方はこちらの資料を読んで興味がそそられたら是非購入を検討してもらっていいと思いますし,AWS でデータレイクを作ったり運用するのに興味ある人は是非みてもらいたい一冊です.

aws.amazon.com

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

Amazon の監視ダッシュボードの取り組みを学べる『Building dashboards for operational visibility』を読んだ

タダです.

新しい「Amazon Builders’ Library」の記事として「Building dashboards for operational visibility(運用の可視化のためのダッシュボードの構築)」が追加されました.このページを読んで Amazon での監視ダッシュボード構築・運用の取り組みを学んでいきます.

aws.amazon.com

記事目次および著者

記事の目次としては以下の通りです

  1. Amazon でのダッシュボード
  2. ダッシュボードの種類
  3. ダッシュボードのデザイン
  4. ダッシュボードのメンテナンス

著者はJohn O’Shea さんです.CloudWatch および Amazon 内部の監視と監視サービスを担当されているようです.

Amazon での監視ダッシュボード構築・運用の取り組み

記事内では Amazon がどんな種類のダッシュボードを持っているか,どんな風にダッシュボードをデザインし,運用しているのかを知ることができます.簡単にまとめていきます.

どんな種類のダッシュボードを持っているか

Amazon ではクラウドサービスの状態を常に把握する課題に対処するためにダッシュボードを作っていて,ダッシュボードでは時系列でのメトリック,ログ,トレース情報,アラームデータを表示しています.ダッシュボードは普段のオペレーションの中だけでなく毎週の運用レビュー会議でも使われ,利害関係者と確認するほどに重要なツールです.

そんなダッシュボードは用途ごとに存在しており,記事内の画像を引用させていただいていますが,用途ごとに図解化されておりわかりやすいです.

  • 顧客向けダッシュボード
  • 顧客体験のダッシュボード
    • 最も使われており,サービス自体,AWS SDK メトリック,CloudWatch Synthetics Canary,自動修復システムのデータが表示される
    • サービス全体の正常性と目標の順守に関するメトリックを効率的に提示
  • システムレベルのダッシュボード
    • API の監視データが表示され3つのカテゴリに分類される
      • 入力関連の監視データ: キュー/ストリームから受信またはリクエストされたリクエストの数およびリクエストのバイトサイズのパーセンタイル,認証/承認の失敗数が含まれる
      • 処理関連の監視データ: マルチモーダルビジネスロジックパス/ブランチ実行カウント,バックエンドマイクロサービスリクエストカウント/失敗/レイテンシパーセンタイル,障害およびエラーログ出力,リクエストトレースデータが含まれる
      • 出力関連の監視データ: レスポンスタイプカウント(顧客によるエラー/障害応答の内訳付き),レスポンスサイズ、および最初の書き込み時間の書き込みバイトとレスポンスタイムの書き込みのパーセンタイルが含まれる
  • サービスインスタンスダッシュボード
  • サービス監査ダッシュボード
    • Availabity Zone やリージョンレベルでのサービスに関するインスタンス群の監視データが表示される
  • キャパシティプランニングおよびその予測ダッシュボード
    • キャパシティプランニングと予測のためのダッシュボード
  • 依存関係のダッシュボード
    • マイクロサービスの依存関係(プロキシやロードバランサー,データストア,キュー,およびストリーム)を見れる
    • セキュリティ証明書の有効期限やその他の依存関係の割り当ての使用状況など他の重要なメトリックを追跡するためにも使用できる
  • マイクロサービスのダッシュボード
  • インフラのダッシュボード
    • EC2,ECS,EKS,Lambda などのメトリックを表示

f:id:sadayoshi_tada:20200813145424p:plain ※Building dashboards for operational visibilityの記事内の画像より引用

どんなデザインをしているか

ダッシュボードを設計する時にはダッシュボードの利用者起点で設計します.データのレイアウト設計原則としてダッシュボードは上から下にレンダリングされ,ユーザーは最初にレンダリングされたグラフを最も重要であると解釈し,最も重要なデータをダッシュボードの上部に配置することを推奨しています*.他にも次のようなデザインの考慮点があります.

  • グラフの凡例が表示されているグラフデータを垂直方向または水平方向に圧迫しないようにする
  • グラフで検索クエリを使用している時はメトリックの結果が通常より大きく表示するようにする
  • GUI のスクロールバーに気づかない人もいるかもしれないので,最小表示解像度のグラフをレイアウトする
  • タイムゾーンUTCに設定して表示する
  • ダッシュボードにはデータの表示間隔とメトリックの期間を調整できるようにする
  • ダッシュボードに多くのデータピントを表示させない
  • 必要に応じて、アラームステータス、単純な数値、および/または時系列グラフウィジェットを使用

どう運用しているのか

ほとんどのシステムは時間の経過に伴うスケーリングに対応して進化を続けて行く一方で,ダッシュボード IaC プロセスに従ってダッシュボードを維持・管理しています.このプロセスによりダッシュボードがバージョン管理システムで維持され,開発者とオペレーターがサービスに使用するのと同じツールを使用して変更がダッシュボードにデプロイされます.

予期しないイベントの事後分析し,チームはダッシュボード(および自動アラーム)の改善によりイベントを先取りしたり,根本原因をより早く特定や平均復旧時間を短縮したりできるかどうかを確認します.その際に「ダッシュボードは顧客への影響を明確に示し,オペレーターが最終的な根本原因を特定し,復旧までの時間を測定するのを助けたか」と自問します.これらの質問に対する回答が「いいえ」の場合,事後分析でこれらのダッシュボードを調整します.

まとめ

Building dashboards for operational visibility」を読んでその学びをまとめました.Amazon ではダッシュボードの使い手が作業するシーンをイメージしてダッシュボードのデザインをしはじめ,使いやすくすることに努めているのはデータを可視化する時に大事な視点だなと感じます.また,運用していく中で振り返りをしていく時に自分たちが提供したダッシュボードが役に立ったかを自問し,改善するプロセスも継続的な改善上必要なことだと思いました.自分自身データのダッシュボードを作成・維持管理することはしたことはないものの関わった時の指標にして行きたいと感じました.監視ダッシュボードに関われている人やこれから関わっていく人,データの可視化に興味がある人は是非一読してみてはと思った内容でした.

関連記事

kdnakt.hatenablog.com

sadayoshi-tada.hatenablog.com

kdnakt.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

『AWS Copilot』で ECS の CI/CD パイプラインをサクッと作る

タダです.

AWS Copilot」のコマンドでcopilot pipelineからはじまるコマンドがあります.このコマンドでは,GitHub にコードをプッシュした時に CodeBuild,CodePipeline によるリリースパイプラインを作ることができます.この記事では,copilot pipelineコマンドを使ってパイプラインの作成とパイプラインでの ECS アプリケーションのデプロイをやってみます.なお,バージョンはv0.2.0で動作確認してます.

» copilot version
version: v0.2.0, built for darwin

パイプラインの構造

AWS Copilot」で作られるパイプラインの構造は3つあります.

  1. デフォルトですと, master ブランチへのプッシュをトリガーにして GitHub からソースコードを取得するステージ
  2. コンテナイメージがビルドされ,ECR リポジトリにイメージを格納するステージ
  3. ECR アプリケーションのデプロイステージ

パイプラインに関するドキュメント github.com

なお,GitHub と CodePipeline の連携は GitHub のアクセストークンを介して行います.発行していない場合は下記ドキュメントを参考にrepoおよびadmin:repo_hookの権限を与えてアクセストークンを準備しておいてください.

docs.aws.amazon.com

ローカルでのセットアップ

まずは,ローカルでパイプライン作成に必要なセットアップを行います.予めデプロイしたいサービスは準備しているディレクトリまで移動し,copilot pipeline initコマンドを実行します.いくつかの質問にウィザードに沿って回答します.この工程では①アプリケーションをデプロイするステージの指定,②CodePipeline と連携する GitHub リポジトリの指定,③GitHub のアクセストークンを Secret Manager へ保存,④パイプライン構成のための各種ファイル生成が行われています.

» copilot pipeline init                                          
Would you like to add an environment to your pipeline? Yes
Which environment would you like to add to your pipeline? test
Which GitHub repository would you like to use for your service? git@github.com:tasogare0919/copilot-sandbox
Please enter your GitHub Personal Access Token for your repository copilot-sandbox: 
✔ Created the secret github-token-sample-app-copilot-sandbox for pipeline source stage!
✔ Wrote the pipeline manifest for copilot-sandbox at 'copilot/pipeline.yml'
The manifest contains configurations for your CodePipeline resources, such as your pipeline stages and build steps.
✔ Wrote the buildspec for the pipeline's build stage at 'copilot/buildspec.yml'
The buildspec contains the commands to build and push your container images to your ECR repositories.

Recommended follow-up actions:
- Commit and push the generated buildspec and manifest file.
- Update the build phase of your buildspec to unit test your services before pushing the images.
- Update your pipeline manifest to add additional stages.
- Run `copilot pipeline update` to deploy your pipeline for the repository.

copilot pipeline initコマンド実行によりcopilotディレクトリ配下にbuildspec.ymlpipeline.ymlファイルが生成されます.

» tree                
.
├── copilot
│   ├── buildspec.yml
│   └── pipeline.yml

各ファイルの中身をみてみます.pipeline.ymlはパイプラインのためのマニフェストファイルです.マニフェストファイルでは大きく3つのセクションがあり,パイプライン名を指定している箇所・リピジトリに関する情報の箇所・デプロイステージの箇所です.ファイルの中身は変更できますが,更新する場合はcopilot pipeline updateを行います.

# This YAML file defines the relationship and deployment ordering of your environments.
# The name of the pipeline
name: pipeline-sample-app-tasogare0919-copilot-sandbox

# The version of the schema used in this template
version: 1

# This section defines the source artifacts.
source:
  # The name of the provider that is used to store the source artifacts.
  provider: GitHub
  # Additional properties that further specifies the exact location
  # the artifacts should be sourced from. For example, the GitHub provider
  # has the following properties: repository, branch.
  properties:
    access_token_secret: github-token-sample-app-copilot-sandbox
    branch: master
    repository: https://github.com/tasogare0919/copilot-sandbox

# The deployment section defines the order the pipeline will deploy
# to your environments.
stages:
    - # The name of the environment to deploy to.
      name: test
      # Optional: use test commands to validate this stage of your build.
      # test_commands: [echo 'running tests', make test]

buildspec.ymlは CodeBuild でのビルド実行に関する定義ファイルです.ECR へのコンテナイメージビルドと格納を行なっています.

# Buildspec runs in the build stage of your pipeline.
version: 0.2
phases:
  install:
    runtime-versions:
      docker: 18
      ruby: 2.6
    commands:
      - echo "cd into $CODEBUILD_SRC_DIR"
      - cd $CODEBUILD_SRC_DIR
      # Download the copilot linux binary.
      - wget https://ecs-cli-v2-release.s3.amazonaws.com/copilot-linux-v0.2.0
      - mv ./copilot-linux-v0.2.0 ./copilot-linux
      - chmod +x ./copilot-linux
  build:
    commands:
      - echo "Run your tests"
      # - make test
  post_build:
    commands:
      - ls -l
      - export COLOR="false"
      # Find all the local services in the workspace.
      - svcs=$(./copilot-linux svc ls --local --json | jq '.services[].name' | sed 's/"//g')
      # Find all the environments.
      - envs=$(./copilot-linux env ls --json | jq '.environments[].name' | sed 's/"//g')
      # Generate the cloudformation templates.
      # The tag is the build ID but we replaced the colon ':' with a dash '-'.
      - tag=$(sed 's/:/-/g' <<<"$CODEBUILD_BUILD_ID")
      - >
        for env in $envs; do
          for svc in $svcs; do
          ./copilot-linux svc package -n $svc -e $env --output-dir './infrastructure' --tag $tag;
          done;
        done;
      - ls -lah ./infrastructure
      # If addons exists, upload addons templates to each S3 bucket and write template URL to template config files.
      - |
        for svc in $svcs; do
          ADDONSFILE=./infrastructure/$svc.addons.stack.yml
          if [ -f "$ADDONSFILE" ]; then
            tmp=$(mktemp)
            timestamp=$(date +%s)
            aws s3 cp "$ADDONSFILE" "s3://xxxx/manual/$timestamp/$svc.addons.stack.yml";
            jq --arg a "https://xxxxs3-ap-northeast-1.amazonaws.com/manual/$timestamp/$svc.addons.stack.yml" '.Parameters.AddonsTemplateURL = $a' ./infrastructure/$svc-test.params.json > "$tmp" && mv "$tmp" ./infrastructure/$svc-test.params.json
          fi
        done;
      # Build images
      # - For each manifest file:
      #   - Read the path to the Dockerfile by translating the YAML file into JSON.
      #   - Run docker build.
      #   - For each environment:
      #     - Retrieve the ECR repository.
      #     - Login and push the image.
      - >
        for svc in $svcs; do
          for df_rel_path in $(cat $CODEBUILD_SRC_DIR/copilot/$svc/manifest.yml | ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load(ARGF))' | jq '.image.build' | sed 's/"//g'); do
          df_path=$CODEBUILD_SRC_DIR/$df_rel_path
          df_dir_path=$(dirname "$df_path")
          docker build -t $svc:$tag -f $df_path $df_dir_path;
          image_id=$(docker images -q $svc:$tag);
            for env in $envs; do
            repo=$(cat $CODEBUILD_SRC_DIR/infrastructure/$svc-$env.params.json | jq '.Parameters.ContainerImage' | sed 's/"//g');
            region=$(echo $repo | cut -d'.' -f4);
            $(aws ecr get-login --no-include-email --region $region);
            docker tag $image_id $repo;
            docker push $repo;
            done;
          done;
        done;
artifacts:
  files:
    - "infrastructure/*"

ローカルでのセットアップが完了なので次はパイプラインの作成に移るのですが,予めこれらのファイルを GitHub リポジトリにを上げておきます.

AWS 環境にパイプラインの作成及び実行

パイプラインの作成及び更新にはcopilot pipeline updateで行います.コマンド実行後,CloudFormation スタックが作成されて CodePipeline と CodeBuild が作成されます.

» copilot pipeline update
✔ Successfully added pipeline resources to your application: sample-app
✔ Successfully created a new pipeline: pipeline-sample-app-tasogare0919-copilot-sandbox

f:id:sadayoshi_tada:20200807075903p:plain

スタックが作成された後に,パイプラインが動作します.僕はcopillot pipeline update実行前にコードを GitHub リポジトリにプッシュし忘れていたので一度処理が失敗しましたが,コードが上がっていればパイプラインは全ての処理をパスしました.

f:id:sadayoshi_tada:20200807080041p:plain

なお,AWS マネジメントコンソールでも確認する以外にもcopilot pipeline showcopilot pipeline statusでもパイプラインの実行状況を確認できます.

» copilot pipeline show  
About

  Name              pipeline-sample-app-tasogare0919-copilot-sandbox
  Region            ap-northeast-1
  AccountID         XXXXXXXXXXXX
  Created At        40 minutes ago
  Updated At        40 minutes ago

Stages

  Name              Category            Provider            Details
  ----              ----                ----                ----
  Source            Source              GitHub              Repository: tasogare0919/copilot-sandbox
  Build             Build               CodeBuild           BuildProject: pipeline-sample-app-tasogare0919-copilot-sandbox-BuildProject
  DeployTo-test     Deploy              CloudFormation      StackName: sample-app-test-front-end

» copilot pipeline status
Pipeline Status

Stage                              Transition          Status
-----                              ----------          ------
Source                             ENABLED             Succeeded
└── SourceCodeFor-sample-app                           Succeeded
Build                              ENABLED             Succeeded
└── Build                                              Succeeded
DeployTo-test                      ENABLED             Succeeded
└── CreateOrUpdate-front-end-test                      Succeeded

Last Deployment

  Updated At    38 minutes ago

自動テストステージの追加

パイプラインでは,デプロイした ECS アプリケーションに対してテストを入れていくことも考えられます.「AWS Copilot」でも自動テストのステージを追加できます.以下の定義では,make testコマンドを実行するだけのものですが,独自のテストコマンドを定義できます.この状態でcopilot pipeline updateを実行すると,テスト用の CodeBuild プロジェクトとデプロイパイプラインにテスト処理が追加されます.

# This YAML file defines the relationship and deployment ordering of your environments.

# The name of the pipeline
name: pipeline-sample-app-tasogare0919-copilot-sandbox

# The version of the schema used in this template
version: 1

# This section defines the source artifacts.
source:
  # The name of the provider that is used to store the source artifacts.
  provider: GitHub
  # Additional properties that further specifies the exact location
  # the artifacts should be sourced from. For example, the GitHub provider
  # has the following properties: repository, branch.
  properties:
    access_token_secret: github-token-sample-app-copilot-sandbox
    branch: master
    repository: https://github.com/tasogare0919/copilot-sandbox

# The deployment section defines the order the pipeline will deploy
# to your environments.
stages:
    - # The name of the environment to deploy to.
      name: test
      # Optional: use test commands to validate this stage of your build.
      test_commands: <= 更新
        - echo 'running tests' <= 更新
        - make test <= 更新
        - echo 'tests passed' <= 更新

AWS 環境のパイプラインを削除

作成したパイプラインの削除するにはcopilot pipeline deleteで行います.Secret Manager の情報も消えます.

» copilot pipeline delete
Are you sure you want to delete pipeline pipeline-sample-app-tasogare0919-copilot-sandbox from application sample-app? Yes
Are you sure you want to delete the source secret github-token-sample-app-copilot-sandbox associated with pipeline pipeline-sample-app-tasogare0919-copilot-sandbox? Yes
✔ Deleted secret github-token-sample-app-copilot-sandbox.
✔ Deleted pipeline pipeline-sample-app-tasogare0919-copilot-sandbox from application sample-app.

まとめ

AWS Copilot」での CI/CD パイプラインを行うコマンドとどのようにデプロイをしていくかを見てきました.ドキュメントにも記載があったのですが,リリースプロセスの構成をできるだけ簡単にしたいというメッセージの通りで体感としてもパイプラインの作成とデプロイがコマンド数回で実現できてしまうため簡単でした.リリースの戦略や方針にもよると思いますが,気になる方は試しに使ってみて検討してみてほしいです!

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

『AWS Coplilot CLI』の v0.2.0 でサポートされたストレージリソースのデプロイを実践する

タダです.

AWS Coplilot CLI」がv0.2.0になった時に追加されたcopilot storage initコマンドがあります.このコマンドで S3 もしくは DynamoDB を ECS のアプリケーションと関連づけられ,デプロイする時も一緒に展開されます.今回はストレージリソースを追加するコマンドでどんなことができるのかを観つつ,実際に AWS 上にリソースを作成してみます.

github.com

copilot storage init でリソースを足してみる

copilot storage initで S3 と DynamoDB をリソースを足してデプロイして動作を確認してみます.

S3 をストレージリソースに指定する場合

copilot storage initcopilot-sandbox-bucketという S3 バケットを作り,front-endというサービスに関連づけるようにコマンドを実行しました.すると,front-endサービスのディレクトリ配下にaddonsディレクトリが追加されました.

» copilot storage init -n copilot-sandbox-bucket -t S3 -s front-end
✔ Wrote CloudFormation template for S3 Bucket copilot-sandbox-bucket at front-end/addons/copilot-sandbox-bucket.yml
The Cloudformation template is a nested stack which fully describes your resource,
the IAM policy necessary for an ECS task to access that resource, and outputs
which are injected as environment variables into the Copilot service this addon is associated with.

Recommended follow-up actions:
- Update your service code to leverage the injected environment variable `COPILOTSANDBOXBUCKET_NAME`
- Run `copilot svc deploy --name front-end` to deploy your storage resources to your environments.

ツリーで出すと以下のディレクトリ構造です.

» tree                                
.
└── front-end
    ├── addons
    │   └── copilot-sandbox-bucket.yml
    └── manifest.yml

2 directories, 2 files

addons ディレクトリにできた CloudFormation の中身

addonsの中にできた CloudFormation テンプレートもみてみましょう.S3 とバケットポリシー と IAM ポリシーが作られるようになっています.S3 バケット名はアプリケーション名-環境名-サービス名-copilot-sandbox-bucketに作られるよう定義されているので,今回はアプリケーション名をs3-test-app.サービス名をfront-end,環境名はtestにしているので,s3-test-app-test-front-end-copilot-sandbox-bucketというバケットが作られるはずです.

Parameters:
  App:
    Type: String
    Description: Your application's name.
  Env:
    Type: String
    Description: The environment name your service, job, or workflow is being deployed to.
  Name:
    Type: String
    Description: The name of the service, job, or workflow being deployed.
Resources:
  copilotsandboxbucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    Properties:
      AccessControl: Private
      BucketEncryption:
        ServerSideEncryptionConfiguration:
        - ServerSideEncryptionByDefault:
            SSEAlgorithm: AES256
      BucketName: !Sub '${App}-${Env}-${Name}-copilot-sandbox-bucket'
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true

  copilotsandboxbucketBucketPolicy:
    Type: AWS::S3::BucketPolicy
    DeletionPolicy: Retain
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: ForceHTTPS
            Effect: Deny
            Principal: '*'
            Action: 's3:*'
            Resource: 
              - !Sub ${ copilotsandboxbucket.Arn}/*
              - !Sub ${ copilotsandboxbucket.Arn}
            Condition: 
              Bool:
                "aws:SecureTransport": false
      Bucket: !Ref copilotsandboxbucket

  copilotsandboxbucketAccessPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: !Sub
        - Grants CRUD access to the S3 bucket ${Bucket}
        - { Bucket: !Ref copilotsandboxbucket }
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: S3ObjectActions
            Effect: Allow
            Action:
              - s3:GetObject
              - s3:PutObject
              - s3:PutObjectACL
              - s3:PutObjectTagging
              - s3:DeleteObject
              - s3:RestoreObject
            Resource: !Sub ${ copilotsandboxbucket.Arn}/*
          - Sid: S3ListAction
            Effect: Allow
            Action: s3:ListBucket
            Resource: !Sub ${ copilotsandboxbucket.Arn}

Outputs:
  copilotsandboxbucketName:
    Description: "The name of a user-defined bucket."
    Value: !Ref copilotsandboxbucket
  copilotsandboxbucketAccessPolicy:
    Description: "The IAM::ManagedPolicy to attach to the task role"
    Value: !Ref copilotsandboxbucketAccessPolicy

デプロイの実践

ECS と一緒に S3 が作成されるかを見るために試しにデプロイします.front-endサービスでtestステージとしてデプロイします.

» copilot svc deploy -n front-end -e test
Sending build context to Docker daemon  97.28kB
Step 1/3 : FROM nginx
 ---> 2622e6cca7eb
Step 2/3 : EXPOSE 80
 ---> Using cache
 ---> 26762c0d19ed
Step 3/3 : COPY index.html /usr/share/nginx/html
 ---> Using cache
 ---> 418ae089702d
Successfully built 418ae089702d
Successfully tagged XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/s3-test-app/front-end:594bd85
Login Succeeded
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/s3-test-app/front-end]
f2ed02c7c10a: Pushed 
f978b9ed3f26: Pushed 
9040af41bb66: Pushed 
7c7d7f446182: Pushed 
d4cf327d8ef5: Pushed 
13cb14c2acd3: Pushed 
594bd85: digest: sha256:234bf1c50d5b5b0f27abaec5be3e2b33cf1f81f0caa3f3a5c015cb0610e79004 size: 1570


✔ Deployed front-end, you can access it at http://s3-te-Publi-1LSK6S09DLXSM-500018808.ap-northeast-1.elb.amazonaws.com.

ECS クラスターと一緒にs3-test-app-test-front-end-copilot-sandbox-bucketが作成されていました. f:id:sadayoshi_tada:20200803131803p:plain f:id:sadayoshi_tada:20200803131813p:plain

削除する時の注意点として S3 バケットは削除されません.CloudFormation テンプレート(本記事でいう copilot-sandbox-bucket.yml )で DeletionPolicy: Retain が定義されているためです.開発中に何度も作って潰してを繰り返すこともあると思うのでその時はDeletionPolicy:Deleteを設定することを検討しましょう. docs.aws.amazon.com

DynamoDB をストレージリソースに指定する場合

copilot storage initcopilot-sandbox-tableという DynamoDB のテーブルを作り,Email というパーティションキーと UserId というソートキーを設定して,front-endというサービスに関連づけるようにコマンドを実行しました.S3 の時と同様に,front-endサービスのディレクトリ配下にaddonsディレクトリが追加されました.

 » copilot storage init -n copilot-sandbox-table -t DynamoDB -s front-end --partition-key Email:S --sort-key UserId:N --no-lsi
✔ Wrote CloudFormation template for DynamoDB Table copilot-sandbox-table at copilot/front-end/addons/copilot-sandbox-table.yml
The Cloudformation template is a nested stack which fully describes your resource,
the IAM policy necessary for an ECS task to access that resource, and outputs
which are injected as environment variables into the Copilot service this addon
is associated with.

Recommended follow-up actions:
- Update your service code to leverage the injected environment variable `COPILOTSANDBOXTABLE_NAME`
- Run `copilot svc deploy --name front-end` to deploy your storage resources to your environments.

ツリーで出すと以下のディレクトリ構造です.

» tree                                
.
└── front-end
    ├── addons
    │   └── copilot-sandbox-table.yml
    └── manifest.yml

2 directories, 2 files

addons ディレクトリにできた CloudFormation の中身

addonsの中にできた CloudFormation テンプレートもみてみましょう.ざっとみると,DynamoDB と IAM ポリシーが作られるようになっています.DynamoDB のテーブル名はアプリケーション名-環境名-サービス名-copilot-sandbox-tableに作られるよう定義されているので,今回はアプリケーション名をdynamo-test-app.サービス名をfront-end,環境名はtestにしているので,dynamo-test-app-test-front-end-copilot-sandbox-bucketというバケットが作られるはずです.

Parameters:
  App:
    Type: String
    Description: Your application's name.
  Env:
    Type: String
    Description: The environment name your service, job, or workflow is being deployed to.
  Name:
    Type: String
    Description: The name of the service, job, or workflow being deployed.
Resources:
  copilotsandboxtable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: !Sub ${App}-${Env}-${Name}-copilot-sandbox-table
      AttributeDefinitions:
        - AttributeName: Email
          AttributeType: "S"
        - AttributeName: UserId
          AttributeType: "N"
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: Email
          KeyType: HASH
        - AttributeName: UserId
          KeyType: RANGE

  copilotsandboxtableAccessPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: !Sub
        - Grants CRUD access to the Dynamo DB table ${Table}
        - { Table: !Ref copilotsandboxtable }
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: DDBActions
            Effect: Allow
            Action:
              - dynamodb:BatchGet*
              - dynamodb:DescribeStream
              - dynamodb:DescribeTable
              - dynamodb:Get*
              - dynamodb:Query
              - dynamodb:Scan
              - dynamodb:BatchWrite*
              - dynamodb:Create*
              - dynamodb:Delete*
              - dynamodb:Update*
              - dynamodb:PutItem
            Resource: !Sub ${ copilotsandboxtable.Arn}
          - Sid: DDBLSIActions
            Action:
              - dynamodb:Query
              - dynamodb:Scan
            Effect: Allow
            Resource: !Sub ${ copilotsandboxtable.Arn}/Index/*

Outputs:
  copilotsandboxtableName:
    Description: "The name of this DynamoDB."
    Value: !Ref copilotsandboxtable
  copilotsandboxtableAccessPolicy:
    Description: "The IAM::ManagedPolicy to attach to the task role."
    Value: !Ref copilotsandboxtableAccessPolicy

デプロイの実践

DynamoDB のリソースが作られるかを確認するためにデプロイします.front-endサービスでtestステージとしてデプロイします.

» copilot svc deploy -n front-end -e test
Sending build context to Docker daemon  97.28kB
Step 1/3 : FROM nginx
 ---> 2622e6cca7eb
Step 2/3 : EXPOSE 80
 ---> Using cache
 ---> 26762c0d19ed
Step 3/3 : COPY index.html /usr/share/nginx/html
 ---> Using cache
 ---> 418ae089702d
Successfully built 418ae089702d
Successfully tagged XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/dynamo-test-app/front-end:594bd85
Login Succeeded
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/dynamo-test-app/front-end]
f2ed02c7c10a: Pushed 
f978b9ed3f26: Pushed 
9040af41bb66: Pushed 
7c7d7f446182: Pushed 
d4cf327d8ef5: Pushed 
13cb14c2acd3: Pushed 
594bd85: digest: sha256:234bf1c50d5b5b0f27abaec5be3e2b33cf1f81f0caa3f3a5c015cb0610e79004 size: 1570


✔ Deployed front-end, you can access it at http://dynam-Publi-1J6Y56CHUQZF1-2062355131.ap-northeast-1.elb.amazonaws.com.

ECS クラスターと一緒にdynamo-test-app-test-front-end-copilot-sandbox-tableが作成されていました. f:id:sadayoshi_tada:20200803120639p:plain f:id:sadayoshi_tada:20200803121612p:plain

まとめ

ver0.2.0で追加されたcopilot storage initコマンドでできることと実際にリソースの作成を試してみました.サービスで指定した ECS リソース以外にも S3 や DynamoDB を利用したアーキテクチャを採用したい時にこのコマンドが役立つと思います.次はcopilot pipeline のコマンドについて記事を書きたいと思います.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com