Docker+AWS Codebuild+Amazon S3による自動ドキュメンテーション機構
挨拶
株式会社ジンズのバックエンドエンジニア兼開発環境保全活動家の中島です。
今回は開発環境保全の取り組みとしてCI/CDの一機構、自動ドキュメンテーション機構を実装したためご紹介します。
背景
われわれJINS、日本国内だけでも既に約500店舗出店しているのですが、さらに海外にも積極的に店舗を展開していっています。これに加えてECサイトの強化・トランザクション管理システムの見直しなど陰に陽にシステムの改善を進めています。
こういった小売業の展開にあたって重視されるのがITシステムの「アジリティ」、すなわち "改善・横展開をスピーディーに行えること"。これが事業を拡大するにあたり重要な要素となります。これを踏まえて現在の社内システムの構築にあたっては マイクロサービスアーキテクチャ を積極的に採用しています。
マイクロサービスアーキテクチャとは、システムを"多数の独立したサービスの連携"で実現する設計方式です。機能ごとに独立して開発できるため、モノリシックなシステムに比べ部分的な改善・拡張が容易に実現できるというメリットがあります。
一方で、当然ながら 機能間の連携が開発者内で適切に共有されている必要があります。お隣のシステムに「どう問い合わせれば」「どういった応答を返してくれるのか」を正しく把握できていない中で開発を進めると、マイクロサービスアーキテクチャはバグの温床になるばかりです。
この情報共有が難しい。
今回はここの改善を狙い
- マイクロサービスの機能仕様のドキュメントが
- 常に最新の状態に更新され
- 関係する開発者全員がアクセスできる
状態を常に維持するべく、自動ドキュメンテーションの機構を構築しました。
構成図
JINSのバックエンドで動くシステムのCI/CDは
bitbucketにリポジトリをpush → AmazonECSとしてサービス立ち上げ
が比較的一般的な構成となっています。
今回はここにドキュメンテーションのためのフロー(赤枠)を追加します。
自動ドキュメンテーションにあたってはタイトルの通り下記3つのツール・サービスをコアとしています。
- Docker:サービスの定義に追加してドキュメント生成ステージを定義
- AWS Codebuild:サービスのビルドとともにドキュメントを生成
- Amazon S3:静的ホスティングを利用しドキュメントを公開
実装
Docker
DockerFileではマルチステージビルドを利用しドキュメント生成用のdoc
ステージを構成しておきます。
つまり、アプリケーションサイドとインフラサイドとの間に 「doc
ステージの/docs
ディレクトリにドキュメントが生成される」というお約束 のみを設け、開発上での結合を疎にします。
設計としてシステム構成のみならず開発プロセスの面でもマイクロサービスアーキテクチャ的疎結合の思想に倣います。素敵。
FROM node:latest as doc
...
RUN ["bash", "-c", "<ドキュメント自動生成コマンド> --output=/docs/index.html"]
ドキュメントの自動生成コマンドはredocなりdoxygenなりsphinxなり何でも…index.html
が生成されればokです。
今回はインフラ開発者(私)とアプリケーション開発者(ベンダーさん)でそれぞれ別々に開発を進めましたが、この切り分けが予想以上に上手く機能して満足。
AWS Codebuild
JINSではTerraformを利用したIaCを導入しています。
今回のAWS側のインフラ定義もすべてTerraformで実装します。
AWS Codebuild側ではDockerFileの定義に従ってシステムをビルドするのに加え、コンテナ内で生成されたドキュメントをS3に渡す処理を実装します。
resource "aws_codebuild_project" "main" {
name = "codebuild_project_name"
buildspec = templatefile("build_spec.tpl", {})
artifacts {
type = "S3"
location = data.aws_s3_bucket.documents.bucket
encryption_disabled = true
}
...
}
aws_codebuild_project
リソース内でartifactsを定義し、locationとしてAmazonS3バケットを指定します。
これに合わせてcodebuildのビルド仕様build_spec.yml
に下記を記載します。
version: 0.2
phases:
...
build:
commands:
...
- docker build --target doc -t documentation-image . # ドキュメント用ステージをターゲットにビルド
- docker cp $(docker create documentation-image):/docs documents # 生成されるファイルをdocumentsディレクトリにコピー
...
...
artifacts:
files:
- "**/*"
base-directory: documents
これにより、docステージでビルドされるコンテナ内で/docs
に生成される全てのファイルは指定したS3バケット内の<codebuild_project_name>
ディレクトリ以下にコピーされます。
AmazonS3
ドキュメントを配置するAmazonS3
バケットを作成します。
開発者限定でアクセスできるようにしたいため、バケットへのパブリックアクセスは制限しAmazonCloudFront
経由でのアクセスのみ許可します。
今回は割愛しますがAmazonCloudFront
では社内のVPNからのみアクセスできるような制限を設けています。
// S3バケット定義
resource "aws_s3_bucket" "documents" {
bucket = "document_bucket_name"
}
// 静的ホスティングの定義
resource "aws_s3_bucket_website_configuration" "documents" {
bucket = aws_s3_bucket.documents.bucket
index_document {
suffix = "index.html"
}
}
// パブリックアクセスのブロック
resource "aws_s3_bucket_public_access_block" "documents" {
bucket = aws_s3_bucket.documents.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
// CloudFront経由のアクセスのみ許可するポリシー定義
data "aws_iam_policy_document" "documents" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["cloudfront.amazonaws.com"]
}
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.documents.arn}/*"]
condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = [aws_cloudfront_distribution.documents.arn]
}
}
}
// バケットとポリシーの紐づけ
resource "aws_s3_bucket_policy" "documents" {
bucket = aws_s3_bucket.documents.id
policy = data.aws_iam_policy_document.documents.json
}
// アクセス制限+https通信のためのCloudFront定義
resource "aws_cloudfront_distribution" "documents" {
origin {
domain_name = aws_s3_bucket.documents.bucket_regional_domain_name
origin_id = aws_s3_bucket.documents.id
...
}
default_root_object = "index.html"
...
}
上記を一式Terraformでapplyすることで<CloudFrontのURL>/<codebuild_project_name>/index.html
に常に最新のドキュメントが反映されるようになります。
まとめの所感
アジャイル寄りの開発におけるドキュメント保守運用は人間の仕事ではないので徹底的に自動化しましょう。
最後に
我々株式会社ジンズITデジタル部、社内では比較的若い部署ではありますが、少しずつ需要も規模も拡大していっています。そのため新たなエンジニアを随時募集しています。
- 大局を見ながらプロジェクトを運営してビジネスを動かしたい!という方
- 実際に動くシステムをバリバリ実装しながらベンダーさんと殴り合いたい!という方
どちらの志向でも活躍できる土壌があります。
興味ある方はぜひ、下記募集ページをご覧ください!
Discussion