継続は力なり

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

スピーディーなコンテナ環境の構築とアプリケーションデプロイができる『AWS Copilot CLI』

タダです.

現在ベータ版ですが ECS や Fargate でのアプリケーションの作成/リリース/管理するための開発者向けツールである「AWS Copilot CLI」を触ってみました.この記事でツールの概要,ツールの導入,サンプルアプリケーションのデプロイを通じてこのツールで AWS へのコンテナ環境構築とデプロイがシュッとできる感覚が伝われば幸いです✨

ツールの概要

AWS Copilot CLI」(以下 Copilot CLI)は,ECS や Fargate のアプリケーションの作成,リリース,運用する時に DevOps のベストプラクティスと本番環境に対応したインフラストラクチャのパターンを使った支援のためのツールにしていくことが記載されてます.

Our mission is to help customers build, release and operate applications on Amazon ECS with dev-ops best practices and production ready infrastructure patterns.

github.com

特徴としては Dockerfile とアプリケーションのコードさえあればターミナルで完結して10分以内に ECS 上でコードを動かせるようなので,この辺がシュッと環境構築とデプロイを行える所以です.

Got a Dockerfile and some code? Get it up and running on ECS in under 10 minutes, with just one command.Ready to take that app to production? Spin up new environments and a continuous delivery pipeline without having to leave your terminal.

利用シーンとして次のケースが列挙されています.開発からデプロイまで包括的にカバーしており,CI/CD パイプラインにも組み込んで使えるツールです.

関連するすべてのマイクロサービスを1つのアプリケーションにまとめる

リージョンやアカウントを超えたテスト環境と本番環境の設定

本番さながらのスケーラブルなECSサービスとインフラストラクチャのセットアップ

すべてのマイクロサービスの CI/CD パイプラインを設定する

ターミナルからサービスの監視とデバッグ

ecs-cli との関係

同じような CLI ツールに「ecs-cli」があります.違いが何かなと思ったら ECS CLI v2 版として位置づけられているのが「Copilot CLI」のようです.GitHub の ECS CLI v2 のリンクも「Copilot CLI」のリポジトリにリンクされていましたので「ecs-cli」の後継として今後のスタンダードツールになっていくものと想像してます.開発者向けツールであるためDeveloper Experienceにフォーカスしているのが特徴ですね.

The ECS CLI v2 is a brand new CLI focused on the full developer experience of building, deploying and operating your containerized apps. From helping manage all of your infrastructure, to setting up CD Pipelines, the V2 is here to help. The ECS CLI v2 is still in preview and quite different from V1, but we'd love your feedback! For more info on V2, V1 and how these projects are being developed check out our V2 proposal.

github.com

ツールのインストール

それでは「Copilot CLI」をローカルにいれてみます.インストールは macOSLinux の2つの方法がありますが,僕は macOS なのでインストール用のコマンド一発で簡単に導入できました.

» curl -Lo /usr/local/bin/copilot https://github.com/aws/copilot-cli/releases/download/v0.1.0/copilot-darwin-v0.1.0 && chmod +x /usr/local/bin/copilot && copilot --help
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   634  100   634    0     0   1350      0 --:--:-- --:--:-- --:--:--  1348
100 37.9M  100 37.9M    0     0   107k      0  0:06:02  0:06:02 --:--:--  119k
👩<200d>✈️ Launch and manage applications on Amazon ECS and AWS Fargate.

Commands
  Getting Started 🌱
    init        Create a new ECS application.
    docs        Open the copilot docs.

  Develop ✨
    app         Commands for applications.
                Applications are a collection of services and environments.

    env         Commands for environments.
                Environments are deployment stages shared between services.

    svc         Commands for services.
                Services are long-running Amazon ECS services.

  Release 🚀
    pipeline    Commands for pipelines.
                Continuous delivery pipelines to release services.

    deploy      Deploy your service.

  Settings ⚙️
    version     Print the version number.
    completion  Output shell completion code.

Flags
  -h, --help      help for copilot
  -v, --version   version for copilot

Examples
  Displays the help menu for the "init" command.
  `$ copilot init --help`

CLI をインストールできたので,サンプルアプリケーションのデプロイをやってみます.なお,裏で AWS CLI を利用しているため予めaws configureでセットアップしておきましょう.

Copilot CLI を使ったサンプルアプリケーションのデプロイウォークスルー

サンプルアプリケーションはこのリポジトリで公開されていますので,ローカルに pull してきます.静的コンテンツをコンテナに乗せて公開するものになってます.

ローカル環境のセットアップ

まず,copilot initコマンドでローカル環境のセットアップをします.アプリケーション名,サービスのタイプ(フロントエンドかバックエンドか),サービス名,Dockerfile の場所を指定するだけで完了します.

» copilot init
Note: It's best to run this command in the root of your Git repository.
Welcome to the Copilot CLI! We're going to walk you through some questions
to help you get set up with an application on ECS. An application is a collection of
containerized services that operate together.

Application name: sample-app

Service type: Load Balanced Web Service
Service name: front-end

Dockerfile: ./Dockerfile
Ok great, we'll set up a Load Balanced Web Service named front-end in application sample-app listening on port 80.

✔ Created the infrastructure to manage services under application sample-app.

✔ Wrote the manifest for service front-end at copilot/front-end/manifest.yml
Your manifest contains configurations like your container size and port (:80).

✔ Created ECR repositories for service front-end.

この時点でディレクトリとしてcopilot が作られ,配下にmanifest.ymlファイルができました.

 » tree
.
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── copilot
│   └── front-end
│       └── manifest.yml
└── index.html

ドキュメントによるとmanifest.ymlcopilot initcopilot svc init実行した結果を CloudFormation テンプレートに変換したファイルです.CloudFormation テンプレートを書く手間を省けるのと,CloudFormation の記法を気にせず環境構築のコードが出来上がるのは開発者としてだいぶ負担が減るなと思います.

# The manifest for the "front-end" service.
# Read the full specification for the "Load Balanced Web Service" type at:
#  https://github.com/aws/amazon-ecs-cli-v2/wiki/Manifests#load-balanced-web-svc

# Your service name will be used in naming your resources like log groups, ECS services, etc.
name: front-end
# The "architecture" of the service you're running.
type: Load Balanced Web Service

image:
  # Path to your service's Dockerfile.
  build: ./Dockerfile
  # Port exposed through your container to route traffic to it.
  port: 80

http:
  # Requests to this path will be forwarded to your service.
  # To match all requests you can use the "/" path.
  path: '/'
  # You can specify a custom health check path. The default is "/"
  # healthcheck: '/'

# Number of CPU units for the task.
cpu: 256
# Amount of memory in MiB used by the task.
memory: 512
# Number of tasks that should be running in your service.
count: 1

# Optional fields for more advanced use-cases.
#
#variables:                    # Pass environment variables as key value pairs.
#  LOG_LEVEL: info
#
#secrets:                      # Pass secrets from AWS Systems Manager (SSM) Parameter Store.
#  GITHUB_TOKEN: GITHUB_TOKEN  # The key is the name of the environment variable, the value is the name of the SSM parameter.

# You can override any of the values defined above by environment.
#environments:
#  test:
#    count: 2               # Number of tasks to run for the "test" environment.

コンテナの環境構築とサンプルアプリケーションのデプロイ

それでは,コンテナの環境構築とアプリケーションのデプロイをします.なお,記事の構成上分離していますが,copilot initコマンドのウィザードでデプロイができます.

All right, you're all set for local development.
Deploy: Yes

✔ Created the infrastructure for the test environment.
- Virtual private cloud on 2 availability zones to hold your services     [Complete]
- Virtual private cloud on 2 availability zones to hold your services     [Complete]
  - Internet gateway to connect the network to the internet               [Complete]
  - Public subnets for internet facing services                           [Complete]
  - Private subnets for services that can't be reached from the internet  [Complete]
  - Routing tables for services to talk with each other                   [Complete]
- ECS Cluster to hold your services                                       [Complete]
- Application load balancer to distribute traffic                         [Complete]
✔ Linked account XXXXXXXXXXXX(AWSアカウント番号) and region ap-northeast-1 to application sample-app.

✔ Created environment test in region ap-northeast-1 under application sample-app.
Sending build context to Docker daemon  77.82kB
Step 1/3 : FROM nginx
latest: Pulling from library/nginx
8559a31e96f4: Already exists
8d69e59170f7: Pull complete
3f9f1ec1d262: Pull complete
d1f5ff4f210d: Pull complete
1e22bfa8652e: Pull complete
Digest: sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133
Status: Downloaded newer image for nginx:latest
 ---> 2622e6cca7eb
Step 2/3 : EXPOSE 80
 ---> Running in ff4d317656d1
Removing intermediate container ff4d317656d1
 ---> 26762c0d19ed
Step 3/3 : COPY index.html /usr/share/nginx/html
 ---> 418ae089702d
Successfully built 418ae089702d
Successfully tagged XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-app/front-end:f8d65d4
Login Succeeded
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-app/front-end]
f2ed02c7c10a: Pushed
f978b9ed3f26: Pushed
9040af41bb66: Pushed
7c7d7f446182: Pushed
d4cf327d8ef5: Pushed
13cb14c2acd3: Pushed
f8d65d4: digest: sha256:234bf1c50d5b5b0f27abaec5be3e2b33cf1f81f0caa3f3a5c015cb0610e79004 size: 1570


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

http://XXXX.ap-northeast-1.elb.amazonaws.com にアクセスしてみるとコンテンツが表示されました.ここまでターミナルのウィザードに沿って選択肢を選ぶだけで ECS クラスター環境とコンテナを動かし,コンテンツのデプロイがシュッと完了しました.

f:id:sadayoshi_tada:20200701005045p:plain

環境のクリーンアップ

サンプルアプリケーションの実行環境削除もcopilot app delete --env-profiles test=default一発で終わり,CloudFormation スタックを削除する動きをとります.環境作りから削除までターミナルで完結できました.

» copilot app delete --env-profiles test=default
Are you sure you want to delete application sample-app? Yes
✔ Deleted service front-end from environment test.
✔ Deleted service front-end resources from application sample-app.
✔ Deleted service front-end from application sample-app.
✔ Deleted environment test from application sample-app.
✔ Cleaned up deployment resources.
✔ Deleted application resources.
✔ Deleted application configuration.
✔ Deleted local .workspace file.

まとめ

Copilot CLI」でのコンテナ環境構築とアプリケーションデプロイをさらいました.少ないコマンドで環境構築もデプロイもスピーディーに(シュッと)できました.「ecs-cli」の後継ツールとして今後利用される機会が増えていくものと予想されるので,ベータ版の頃から触って関わっていく機会だと思い,僕もこれから使っていきたいです.この記事で「Copilot」を使ってみるきっかけになれば幸いです.

Amazon の継続的デプロイの取り組みを学べる『Automating safe, hands-off deployments』を読んだ

タダです.

新しい「Amazon Builders' Library」の記事が公開されました.オンラインの輪読会で一通り記事は読んだのですが,追加された「Automating safe, hands-off deployments(安全なハンズオフデプロイメントの自動化)」を読んで Amazon での取り組みを学んでいきます.

記事本文 aws.amazon.com

記事目次および著者

記事の大枠としては次のコンテンツがあります.

  • Safe continuous deployments at Amazon
  • Pipeline Phase
    • Source and build
    • Test deployments
    • Production deployments
  • Pipelines as Code
  • Conclusion

著者は Clare Liguori(クレア リグオリ)さんです.コンテナサービスの開発に関わっているエンジニアで,昨年の re:Invent にはキーノートで登壇されていました(21:20秒あたり).

www.youtube.com

安全なハンズオフデプロイメントの自動化の Amazon の取り組みを学ぶ

Amazon での継続的デプロイ戦略

Clare さんは Amazon に入社前デプロイされるまでログやメトリクスをチェックしていて,人手から離れないオペレーションによるデプロイでした.ただ,Amazon ではデプロイに関する監視をしないし,人手がかからないオペレーションを行なっていると入社面接の時に知りました.Amazon のデプロイ戦略はソースコードリポジトリにマージする時のみ開発者が関わるがそれ以外は完全に自動化したデプロイパイプラインになっています.このような戦略を取ったのは元々デプロイに開発者が多数のコストをかけて管理していたのを改善するために会社全体で取り組みを行うことを決めたからです.

Amazon では多い時に1時間に1000回以上もデプロイしている事例が話されていたこともあるし,会社全体で自動化が徹底されていることでこの1000回以上のデプロイを実現できているのだなと思います.

www.publickey1.jp

ascii.jp

どんなパイプライン構成になっているか

では,どんなデプロイパイプラインが作られているからできるのでしょうか.Amazon のパイプラインは4つのフェーズがあり,Source,Build,Test,Prod のフェーズがあります.

Source フェーズ

本番環境への変更はコードレビューから始まり,専用ブランチにマージする前にチームメンバーの承認を得なければならず,レビュー受けていないとデプロイできません.コードレビューではテスト(ユニットテスト/統合テスト/カナリアテスト) があるかどうか,デプロイの監視のための準備,安全にロールバックできるかどうかをチェックします.レビューを受けたのちに個々のパイプラインにデプロイされていきます.

Build フェーズ

コードをコンパイルし,ユニットテストをこのフェーズで行います.ユニットテストは他の AWS サービスなどの依存関係への API 呼び出しをすべてモック環境を作って実行します.

Testフェーズ

パイプラインの中でのテストはアルファテスト,ベータテスト,ガンマテスト,統合テストの4つあります.それぞれの役割は次の通りです.

  • アルファテスト/ベータテスト:機能的な API テストと E2E のテストを実行することによる機能検証を行う
  • ガンマテスト:コードが本番環境に安全にデプロイできることを検証
  • 統合テスト: 本番環境にデプロイする前にサービスの予期せぬ動作や不正確な動作を確認する

Prod フェーズ

Prod フェーズでは本番環境へのデプロイしていきますが,デプロイは全24リージョンおよび76のアベイラビリティーゾーンに展開する必要があるため,デプロイによるリスクを防ぎつつ信頼性も確保していきます.その取り組みを行なっていくにあたり段階的なデプロイを行われてます.つまり,大きく5つのステップを踏んでおり,最初にリクエスト数の少ないリージョンの1つのアベイラビリティーゾーンにデプロイしてリージョン内の影響を確認します.次に,リクエストの多いリージョンの1つのアベイラビリティーゾーンにデプロイしていきます.第3段階で3 つのリージョンに展開,第4段階で最大12 のリージョンに展開,第5段階で残りのリージョンに展開されていきます.

このデプロイにおいてワンボックスデプロイを行なった後にローリングデプロイを行なっているようで,失敗時のロールバックし,他のフェーズで影響を与えないようにしています.この点 Well-Architected Framework にも記載があります.

限定的なデプロイを使用してテストする: 完全なデプロイを行う前に、既存のシステムと並行して限定的なデプロイを実施してテストを行い、望ましい結果が得られるかどうか確認します。例えば、デプロイカナリアテストまたはワンボックスデプロイを使用します。

wa.aws.amazon.com

ロールバックの監視

ロールバックはサービスチームによって定義されたアラームによって行われ,自動的にロールバックしており,リクエスト数/リクエスト待ち時間/失敗数などのメトリクスを取っています.ロールバックは、以前にデプロイしたコンテナイメージ、AWS Lambda関数デプロイメントパッケージ、内部デプロイメントパッケージに環境を切り替えます。内部デプロイメントパッケージはコンテナイメージと似ていますが、パッケージは不変であり、チェックサムを使用して整合性を検証します。 各リージョンの各マイクロサービスには、通常、サービスの顧客に影響を与えるメトリクス(障害率や高遅延など)やシステムの健全性を示すメトリクス(CPU 利用率など)のしきい値でトリガーされる高レベルのアラームが設定されています(以下の例で説明)。この高頻度のアラームは、オンコールエンジニアにページングし、展開が進行中の場合にサービスを自動的にロールバックするために使用されます。多くの場合、オンコール・エンジニアがページングされてエンゲージメントを開始した時点で、ロールバックはすでに進行しています。

Bake time

ワンボックスデプロイの完了後,Bake time が行われます.Bake time では本番デプロイ前にパイプラインがサービスチームで定めたアラームでデプロイ後に発生する影響を監視し続ける時間です.本番前の最終チェックの時間というところでしょうか.Bake time の時間をどれほど確保するかは複数リージョンへの展開によるリスクおよび最終的なリリースへのスピードとのバランスをとっていくそうです.ワンボックスデプロイ後に少なくとも1時間,最初のリージョンへのデプロイ後には12時間,残りのリージョンへのデプロイ後に2~4時間待機していくようにしています.

アラームとタイムウィンドウのブロッカー

パイプラインでは悪影響を及ぼすリスクが高い場合に自動デプロイを停止します。このリスクの評価をブロッカーという仕組みで行います.途中で止まったデプロイも問題解決後開発者によって上書きデプロイができるようになっています.このアジリティの良さも素晴らしいと思います.デプロイには時間を設定して行えるようにもなっており,これはロールバック時に手動でのアクションが必要な場面でオンコールエンジニアが対応するため,夜間や休日を避けて設定されてます.

パイプラインのコード化

Amazon ではこのデプロイパイプラインをコード化しているようです.これでパイプラインの追加があっても対応が可能になり,サービスのスケールと合わせたデプロイ体制が整ったいい取り組みだと感じます.

まとめ

Automating safe, hands-off deployments」で述べられていたのはデプロイの自動化とデプロイに関して開発者が懸念する点を削いで他のタスクに集中してもらうシチュエーションを作っていくためのプロセスだと思います.そのためにデプロイパイプラインで本番デプロイに至るまでのレビュー,ビルド,テストの徹底,自動化された失敗時のロールバック,本番デプロイ時のリスクを軽減するための戦略,デプロイ前の Bake time といった取り組みを記事から学ぶことができました.Amazon も最初から自動的かつハンズオフなデプロイができたわけではなく,継続的な改善による賜物だと思います.自分もデプロイパイプラインに関わった時はこの記事で学んだことをもとにデプロイ戦略を建てられるようになっていきたいです.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

おや? NLB のアクセスログを出力設定しているのに S3 バケットにログが出てないぞ?って時に確認すべきこと

タダです.

小ネタですが,NLB のアクセスログを S3 に出す設定をしているもののログがでてなくてあれ?と思った機会があったので備忘録として記事に残しておきます.

結論

いきなり結論ですが,自分の場合は NLB の仕様で S3 にログが出ていませんでした.その仕様とはアクセスログが出力されるのはロードバランサーTLS リスナーを設定した場合のみであり,TCP リスナーを設定している場合はアクセスログを出力できないということです.

重要

アクセスログが作成されるのは、ロードバランサーTLS リスナーがあり、TLS リクエストに関する情報のみを含む場合のみです。

Network Load Balancer のアクセスログ - Elastic Load Balancing

自分が見ていた環境は 8080 や 3128 ポートを解放していたのですが,いずれも TCP リスナーだったのでログが出なかった...という事態でした.ドキュメントに記載があったけど見落としていました.NLB の役割にもよると思うのですが,NLB でログが出てなくても配下の EC2 で関連のログを CloudWatch Logs に出したり VPC 内のログを VPC フローログとして残すようにしておけば TCP リスナーであっても NLB のアクセスログがなくて困ると言った事態は避けられるかと考えます.

まとめ

NLB のアクセスログが出てない時に確認すべきポイントを書きました.自分は遭遇した時に焦ったので同じ事態に遭遇した人の参考になれば幸いです.

GitHub Actions の使い方を実践的に学べる『GitHub Actions 実践入門』を読んだ

タダです.

GitHub Actions が正式リリースされたので使ってみたいと思い「GitHub Actions 実践入門」を技術書典応援祭で購入しました.本書を読了したので,学べることと所感をまとめていきます.

技術書典応援祭 techbookfest.org

Booth miyajan.booth.pm

目次

本書の章立ては次の通りです.本編として150Pの内容です.

  • 第1章 GitHub Actions の基礎知識
  • 第2章 GitHub Actions の機能解説
  • 第3章 アクション
  • 第4章 サンプルレシピ
  • Appendix A コミュニティ

1章で GitHub Actions 概要,他の CI/CD ツールと比較しながら特徴,料金に触れ,2章以降で GitHub Actions の使い方を解説付きのハンズオン形式で学んでいきます.

本書で学べること

本書を通じて学べることを以下に列挙します.

  • GitHub Actions の構文を書いて,ワークフローを回す経験
  • 次の GitHub Actions の機能
    • ワークフロー内でのデフォルト設定
    • 環境変数
    • 秘密情報の管理
    • イベントのフィルタ
    • ジョブ間の依存関係の制御
    • マトリクスビルドの実践
    • スケジュール実行
    • 条件による実行
    • コンテナ内のジョブ実行/サービス実行
    • GitHub Actions でのキャッシュ機能
    • ビルド完了後の成果物(アーティファクト)の出力方法
    • イベントドリブンのワークフロー実行
    • ログをトリガーにしたコマンド実行
    • デバッグのやり方
    • GitHub Actions 権限制御
    • 自環境でのセルフホストランナー
    • バッジの埋め込み方
    • GitHub Actions の REST API の概要
    • 制限事項
  • オリジナルのアクション(JavaScript と Docker コンテナアクション)作り方,GitHub Marketplace への公開方法
  • 次のユースケース毎の書き方サンプル

読了後の所感

全体を通して,自分は業務では GitHub Actions を扱っておらず今回初めて触ったレベル感でしたが,まずそんな自分にも読み易い内容でした.また,2章は今後 GitHub Actions を使い続ける時に何度も立ち返って参照することになるだろうと思うほどたくさんの機能とその書き方・使い方の解説がされていたので初心者だけでなく中級者や上級者にとっても一読してみるのをお勧めしたい内容でした.更に,GitHub Actions ユースケースは特に使い始めていきたい人にとって具体的なイメージを作るのに有効で,普段の業務フローに組み込む時に役立つのではと思います.公開されているアクションを見ていると AWSGitHub Actions も公開されているので使ってみたいです.

関連リンク

github.com

そして,筆者宮田さんの本書の修正や追記も継続的に行われているのをみて学ぶ側としては本当にありがたい活動だなと感じます.

github.com

まとめ

GitHub Actions 実践入門」で学べること,所感を整理しました.本書は GitHub Actions を使い始めたい人,使い始めてからも2,4章は参照することは多くなると思うので既に使っている人も視野を広げる意味で一読するのをオススメします. 商業版の本も先週(2020/6/19)に発売されたばかりなので(出版おめでとうございます!)こちらも要チェックです 👀

www.kaizenprogrammer.com

www.amazon.co.jp

CloudFormation テンプレートがルールに準拠しているかをチェックする CLI ツール『CloudFormation Guard』

タダです.

現在プレビューですが,「CloudFormation Guard」というコマンドラインツールが使えるようになりました.このツールは CloudForamtion テンプレートが定めたポリシーと照らして設定値として正しいのかをチェックします.

公式ブログ aws.amazon.com

GitHubリポジトリ github.com

CloudFormation Guard」 は3つのツールが提供されています.

  • CloudFormation Guard : 宣言型構文を使ったポリシーに適合しているかのチェック CLI ツール(cfn-guard)
  • CloudFormation Guard Lambda : Lambda での「CloudFormation Guard」チェックツール(cfn-guard-lambda)
  • CloudFormation Guard Rulegen : 既存のテンプレートから 「CloudFormation Guard」のルールを生成するツール(cfn-guard-rulegen)

この記事でcfn-guardの導入とチュートリアルを通してcfn-guardをどう使うのかついて学んだことをまとめていきます.

cfn-guard の初期セットアップ

cfn-guard の導入には Rust を入れておく必要があります.自分は macOS なので下記コマンドで Rust を導入しました.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

info: downloading installer

Welcome to Rust!
~中略~
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1
~中略~
Rust is installed now. Great!

To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH
environment variable. Next time you log in this will be done
automatically.

To configure your current shell run source $HOME/.cargo/env
» rustc --version
rustc 1.44.0 (49cae5576 2020-06-01)

参考情報

www.rust-lang.org

次に,リポジトリをクローンしてcfn-guardディレクトリに移動後ビルドを行ないます.これでcfn-guardコマンドを使えるようにします.

github.com

» make
cargo build --release; cp target/release/cfn-guard ./bin
~中略~   
Compiling cfn-guard v0.5.0 (/Users/tada/aws-tools/cloudformation-guard/cfn-guard)
    Finished release [optimized] target(s) in 10m 08s

bin 配下にパスを通してあげれば使えるようになります.

cfn-guard --help
CloudFormation Guard 0.5.0
Check CloudFormation templates against rules

USAGE:
    cfn-guard [FLAGS] --rule_set <RULE_SET_FILE> --template <TEMPLATE_FILE>

FLAGS:
    -h, --help             Prints help information
    -s, --strict-checks    Fail resources if they're missing the property that a rule checks
    -v                     Sets the level of verbosity - add v's to increase output
    -V, --version          Prints version information
    -w, --warn_only        Show results but return an exit code of 0 regardless of rule violations

OPTIONS:
    -r, --rule_set <RULE_SET_FILE>    Rules to check the template against
    -t, --template <TEMPLATE_FILE>    CloudFormation Template

cfn-guard のチュートリアルで使い方を学ぶ

リポジトリExamples配下に WAF と EBS のテンプレートとポリシールールが配置されているのでチェックを走らせてみます.EBS のテンプレートをチェックしてみると6つの違反が検出されました.

» cfn-guard -t Examples/ebs_volume_template.json -r Examples/ebs_volume_template.ruleset
"[NewVolume2] failed because [Encrypted] is [false] and the permitted value is [true]"
"[NewVolume2] failed because [Size] is [99] and the permitted value is [100]"
"[NewVolume2] failed because [us-west-2c] is not in [us-east-1a,us-east-1b,us-east-1c] for [AvailabilityZone]"
"[NewVolume] failed because [Encrypted] is [false] and the permitted value is [true]"
"[NewVolume] failed because [Size] is [101] and the permitted value is [100]"
"[NewVolume] failed because [us-west-2b] is not in [us-east-1a,us-east-1b,us-east-1c] for [AvailabilityZone]"
Number of failures: 6

EBS のポリシーセットとテンプレート詳細

EBS のポリシーを見てみると以下のルールがあります.

  • EBS の暗号化が必須
  • EBS の Availability Zone の指定
  • EBS ボリュームサイズが 100 GiB を固定化
let encryption_flag = true
let allowed_azs = [us-east-1a,us-east-1b,us-east-1c]

AWS::EC2::Volume AvailabilityZone IN %allowed_azs
AWS::EC2::Volume Encrypted == %encryption_flag
AWS::EC2::Volume Size == 100

EBS テンプレートをみると以下の定義となっていました.

{Resources”: {NewVolume” : {Type” : “AWS::EC2::Volume”,
            “Properties” : {Size” : 101,
                “Encrypted”: false,
                “AvailabilityZone” : “us-west-2b”
            }
        },
        “NewVolume2” : {Type” : “AWS::EC2::Volume”,
            “Properties” : {Size” : 99,
                “Encrypted”: false,
                “AvailabilityZone” : “us-west-2c”
            }
        }
    }
}

ポリシールールとの違反ポイントを整理しました.

  • テンプレートでは EBS の暗号化をしない
    • EBS の暗号化が必須になるポリシーに違反
  • テンプレートでは EBS ボリュームの Availability Zone の指定が us-west-2b と us-west-2c
    • Availability Zone の指定 が us-east-1a,us-east-1b,us-east-1c のいずれかなのでポリシーに違反
  • テンプレートでは EBS ボリュームサイズは 101 GiB と 99 GiB
    • 100 GiB の指定でないためポリシーに違反

この結果を見ると,プロジェクトや組織内でのルールに準拠したテンプレートを開発できているかどうかのチェックを動化しやすいと感じました.リポジトリにも記載がありましたが,次のようなユースケースが載っています.

Q: Why should you use Guard?

A: Guard solves a number of use-cases:

It can be used to check repositories of CloudFormation templates for policy violations with automation. It can be a deployment gate in a CI/CD pipeline. It allows you to define a single source-of-truth for what constitutes valid infrastructure definitions. Define rules once and have them run both locally and as lambdas in your AWS account for integration with other AWS services. It allows for pre-deployment safety checks of your CloudFormation template resources. You can both require settings to be included and prohibit configurations that have caused issues previously. It’s easy to get started. You can extract rules you want from existing, known-good templates using the CloudFormation Guard Rulegen auto-generation tool.

テンプレートの違反チェックの自動化,CI/CD パイプラインへの組み込み,既存のテンプレートにも適用してのチェックなどが挙がっていました.加えて複数人の開発においてローカルとリポジトリにあげた後等にチェックする機構に有効かと思います.

cfn-guard の実践(EC2 の CloudFormation テンプレートチェック)

cfn-guardを実践してみます.簡単な EC2 の CloudFormation テンプレートをチェックするルールを作っていきます.Amazon Linux2 の t3.small で EBS ボリュームとして 20 GiB がアタッチされるサーバーを作るテンプレートを用意します.

Resources:
  TestEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: "ami-0a1c2ec61571737db"
      KeyName: "testkey"
      InstanceType: t3.small
      BlockDeviceMappings:
      - DeviceName: "/dev/sda1"
        Ebs:
          VolumeType: "gp2"
          VolumeSize: "20"

テンプレートのルールの記法は <CloudFormation Resource Type> <Property> == <Value> が基本です.簡単な次のルールを作ってみました.

  • AMI の ID は指定のものを使う
  • インスタンスタイプ は t3.micro に固定
  • EBS ボリュームサイズも 20 GiB に固定
let ami_id = ami-0a1c2ec61571737db

AWS::EC2::Instance ImageId == %ami_id
AWS::EC2::Instance InstanceType == t3.micro
AWS::EC2::Volume Size == 20

記法ルールの解説ページ github.com

意図的にインスタンスタイプのみが違反するように作ったので,インスタンスタイプが違反する結果になりました.

» cfn-guard -t test-ec2_template.yaml -r test-ec2_template.ruleset
"[TestEC2Instance] failed because [InstanceType] is [t3.small] and the permitted value is [t3.micro]"
Number of failures: 1

まとめ

CloudFormation Guard」のセットアップとチュートリアルを通して使い方を学べました.このツールは下記の issue でも述べられていますが「CloudFormation Guard」関連のツールcfn-lint と「CloudFormation Guard」を相互補完的に使うことでに静的解析しつつガバメントを有効に利かせるツールになりそうです.

github.com

関連情報

@toricls さんもcfn-guardの ECS サンプルを公開されているので気になる人は要チェックです!

github.com