AWS が提供するサービスを組み合わせて、Git で管理された Markdown を PDF に一括変換する CI/CD パイプラインを構築した。
パイプライン構成図
処理フロー
- Markdown を含むファイルを Git で CodeCommit のリポジトリにプッシュ
- CodeBuild で CodeCommit から Markdown を含むソース一式を取得
- ECR にある Pandoc の Docker イメージを利用して Markdown から PDF に変換
- PDFをまとめて zip に圧縮し S3 へ転送
パイプライン構築手順
【注意】各種サービスのリージョンは同一リージョンに揃える必要がある
S3
生成したPDFを格納するS3バケットを構築する。特に注意点はなし。
ECR
Pandoc の Docker イメージをプッシュするためのレジストリを予め作成しておき、Docker イメージをプッシュする。
Pandoc Docker イメージ
k1low さん作成の Docker イメージを利用させていただきました。1
FROM k1low/alpine-pandoc-ja
上記 Dockerfile をビルドしたイメージを ECR にプッシュする
アクセス許可
CodeBuild から ECR の Docker イメージをプルできるようにアクセス許可を与える必要がある。
Pandoc が格納されているレジストリの Permissions を選択し、ポリシー JSON を下記のように編集する
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "CodeBuildAccess",
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
]
}
]
}
CodeCommit
Git リポジトリを作成する。
ディレクトリ構成
.
├── buildspec.yml
└── src
├── foo.md
└── bar.md
- CodeCommit 上のリポジトリに必要なファイル及びディレクトリ
- buildspec.yml : Codebuild で必要な YAMLファイル。次節で解説。
- src : PDF に変換したい Markdown 一式を格納するディレクトリ。
CodeBuild
CodeCommit からソース一式と ECR からPandoc の Docker イメージを持ってきて、Markdown を PDF に変換する。
ビルドプロジェクト作成
- 任意のプロジェクト名を入力
- ソースプロバイダは AWS CodeCommit を選択し、リポジトリは Markdownを含むリポジトリを選択
- 環境イメージはECRにプッシュしたPandocのDocker イメージを利用するため、カスタムイメージを選択
- 本稿のDockerfileを利用する場合、下記のように設定
- 環境タイプは Linux
- イメージレジストリは Amazon ECR
- ECR は自分の ECR アカウント
- レポジトリは Pandoc の Docker イメージをプッシュしたリポジトリ
- 特権付与にチェック
- サービスロールは既存のものがあれば選択、ない場合は新規で作成
- BuildSpec は buildspec.ymlを利用
- アーティファクト(生成した PDF)を任意のS3のバケットにアップロードするように設定
サービスロールに割り当てるポリシー
今回のCI/CDパイプラインを動作させるために、CodeBuild のサービスロールに下記のポリシーを IAM から割り当てる。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ecr:DescribeImageScanFindings",
"ecr:GetLifecyclePolicyPreview",
"ecr:GetDownloadUrlForLayer",
"ecr:GetAuthorizationToken",
"ecr:ListTagsForResource",
"ecr:UploadLayerPart",
"ecr:PutImage",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:DescribeImages",
"ecr:InitiateLayerUpload",
"ecr:BatchCheckLayerAvailability",
"ecr:GetRepositoryPolicy",
"ecr:GetLifecyclePolicy"
],
"Resource": "*"
}
]
}
buildspec.yml
実際に Markdown を PDF に変換する処理を buildspec.yml に記述する。
version: 0.2
phases:
install:
commands:
- echo Nothing to do in the install phase...
build:
commands:
- echo Build started on `date`
- ls #for execution test on docker environment
- mkdir -p _build
- for file in `find src -type f -name "*.md"`;
do
out=`echo $file | (sed -e s/src/_build/ | sed -e s/\.md//)`;
echo $out.pdf;
pandoc $file -f markdown -o $out.pdf -V documentclass=ltjarticle -V classoption=a4j -V geometry:margin=1in --pdf-engine=lualatex;
done
- ls _build
post_build:
commands:
- echo Build completed on `date`
artifacts:
files:
- '_build/*'
上記 YAML の build フェーズの commands が Pandoc の Docker イメージで実行されるコマンド。
src/
にある Markdown を _build/
に PDF に変換したファイルを格納する。
artifacts で、 _build/
にある全ての PDF をアップロードすることを記述している。
CodePipeline
CodeCommit, CodeBuild をつなげる。デプロイステージは今回は省略した。
これまで構築したサービスが正しく設定されていれば、CodePipelineが成功するはず。
Markdown を編集して CodeCommit に push すると、CodePipeline が動作し、編集した内容を反映させてPDFを作成する。
作成した PDF は ログから保存先の S3 バケットにアクセスできる。zip で保存されているため、ダウンロードして展開すると生成した PDF が参照できる。
サンプルソース
参考資料
- k1low/alpine-pandoc-ja | Docker Hub
- GitHub - k1LoW/docker-alpine-pandoc-ja: Pandoc for Japanese based on Alpine Linux
- MarkdownからWordやPDF生成ができるようにする (またはPandoc環境の構築方法) (2017/12版) - Copy/Cut/Paste/Hatena
- CodeBuild の Docker サンプル - AWS CodeBuild
- CodeBuild の Amazon ECR サンプル - AWS CodeBuild
- MarkdownをCircleCI上でPDFに変換してGoogleドライブにデプロイする | QUARTETCOM TECH BLOG
-
参考資料 k1low/alpine-pandoc-ja | Docker Hub を参照 ↩