CodeBuild で Go 1.9 と dep を使ったビルドを行う

Posted on

最近 CodeBuild を本格的に使い始めたのですが、Go 1.9 と dep を使ったビルドに苦労したのでポイントをまとめておきます。サンプルとして自分が書いた aws-billing のソースコードをビルドしてみます。

なお、自分が検証した Go のバージョンや環境は次のとおりです。

  • Go のバージョン: 1.9.2
  • dep のバージョン: devel
  • CodeBuild のイメージ: Ubuntu 14.04

CodeBuild で Go 1.9 と dep を使う

CodeBuild の処理は Docker コンテナの中で実行されますが、AWS が提供している Docker イメージは Go 1.7.3 までしか用意されていません(2017 年 10 月時点)。 dep を使うには Go 1.8 以上が必要なので AWS の Docker イメージは使えません。

Go 1.9 でビルドするには、自分で Docker イメージを用意して Amazon ECR に登録するか、Ubuntu のベースイメージに Go をインストールする必要があります。今回は Go のバージョンアップに追従しやすい後者の方法でやってみました。

Go 1.9 と dep を使ったビルドを行うための buildspec.yml

aws-billing のリポジトリにコミットしている buildspec.yml です。

Go と dep を使ったビルドを行うときのポイント

Go のビルドはシンプルですが、CodeBuild 上で実際にやってみるといろいろとハマりました。自分がハマったポイントです。

  • env シーケンスで定義した値はリテラルの文字列になる
    • たとえば GOPATH: $HOME/go と指定しても $HOME は変数展開されない
    • GOPATHPATH を設定するときは phases シーケンスの中でやる
  • dep ensure するときは GOPATH 以下にソースコードを移動する
    • ソースコードは CODEBUILD_SRC_DIR というディレクトリに展開されている
    • GOPATH 以下に移動しないと dep ensure でエラーになる
  • artifacts シーケンスのベースディレクトリは CODEBUILD_SRC_DIR になる
    • GOPATH 以下にビルドファイルがある場合は base-directory で明示的に指定しないといけない

あと、ビルドが安定するまでは buildspec.yml をリポジトリに毎回 push するのではなく、"Insert build commands" で YAML を貼り付けたほうがトライアンドエラーしやすいです。

この機能があることを知らずに Twitter につぶやいたら @riywo さんが教えてくれました。ありがとうございました!

まとめ

GOPATH など Go 独特の部分をクリアすれば、Go 1.9 と dep を使ったビルドも問題ありません。

CodeBuild は GitHub の Webhooks にも対応したので、push されるたびにビルドを走らせるのも簡単にできます。低コストでフルマネージド、かつ AWS とインテグレートされているのがいいですね。