/md2pdf-pipeline

CI/CD for converting markdown to pdf using AWS services.

Primary LanguageDockerfileMIT LicenseMIT

Qiita記事へのリンク

AWS が提供するサービスを組み合わせて、Git で管理された Markdown を PDF に一括変換する CI/CD パイプラインを構築した。

パイプライン構成図

md2pdf-pipeline.png

処理フロー

  1. Markdown を含むファイルを Git で CodeCommit のリポジトリにプッシュ
  2. CodeBuild で CodeCommit から Markdown を含むソース一式を取得
  3. ECR にある Pandoc の Docker イメージを利用して Markdown から PDF に変換
  4. 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"
      ]
    }
  ]
}

Screen Shot 2020-04-16 at 20.46.35.png

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を含むリポジトリを選択

Screen Shot 2020-04-16 at 20.17.44.png

  • 環境イメージはECRにプッシュしたPandocのDocker イメージを利用するため、カスタムイメージを選択
  • 本稿のDockerfileを利用する場合、下記のように設定
    • 環境タイプは Linux
    • イメージレジストリは Amazon ECR
    • ECR は自分の ECR アカウント
    • レポジトリは Pandoc の Docker イメージをプッシュしたリポジトリ
    • 特権付与にチェック
    • サービスロールは既存のものがあれば選択、ない場合は新規で作成

Screen Shot 2020-04-16 at 20.19.42.png

  • BuildSpec は buildspec.ymlを利用
  • アーティファクト(生成した PDF)を任意のS3のバケットにアップロードするように設定

Screen Shot 2020-04-16 at 20.23.03.png

サービスロールに割り当てるポリシー

今回の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": "*"
        }
    ]
}

Screen Shot 2020-04-16 at 20.26.12.png

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 をつなげる。デプロイステージは今回は省略した。

Screen Shot 2020-04-16 at 20.35.58.png

Screen Shot 2020-04-16 at 20.37.05.png

Screen Shot 2020-04-16 at 20.37.43.png

Screen Shot 2020-04-16 at 20.38.48.png

これまで構築したサービスが正しく設定されていれば、CodePipelineが成功するはず。 Screen Shot 2020-04-16 at 20.40.51.png

Markdown を編集して CodeCommit に push すると、CodePipeline が動作し、編集した内容を反映させてPDFを作成する。 作成した PDF は ログから保存先の S3 バケットにアクセスできる。zip で保存されているため、ダウンロードして展開すると生成した PDF が参照できる。

Screen Shot 2020-04-18 at 0.29.13.png

サンプルソース

参考資料

Footnotes

  1. 参考資料 k1low/alpine-pandoc-ja | Docker Hub を参照