概要
GoのAPIテストをCircleCIと連携する際に詰まったので備忘録として投稿します。
要件
今回の用件として、GCPのサービスアカウントを使用すること、Goのバージョンを1.17以上にすることがあります。
また、GCPのサービスアカウントを使用する際にgcloud
コマンドを使用するので、Go1.17以上 + gcoudコマンドを使用できる環境が必要です。(厳密にはこちらのコマンドを使用したいと思っています)
筆者が調べた限りでは、Go1.17以上でgcloud
コマンドを使用できるDocker imageは見つからなかったので自作で環境を構築する必要がありそうでした。
GCPのサービスアカウントを使用する理由
テスト実行時にGCPと連携する必要があるためです。
GOのバージョンが1.17以上である理由
実装の都合上なのでCircleCIとの連携に深く関係はしていません。
実装方法の検討
まず初めに、どの様にCircleCIと連携させるかを検討して以下の3つの方法を検討・調査しました。
① GCPのContainer Registryを使用して実行環境を作成する。
② Docker Hubを使用して実行環境を作成する。
③ GCPのSDK imageを使用して実行環境を作成して、その後のjobでGoをinstallする。
① GCPのContainer Registryを使用して実行環境を作成する
GCPのContainer Registry(以下からGCRと略す)からimageをpullして実行環境を作成する方法です。
この機能以外にもGCRを使用していたため一元管理できる点が魅力でした。
CircleCIのコードのイメージとしては以下の様になります。
version: 2.1
executors:
defaults: &defaults
working_directory: [任意のディレクトリ]
docker:
- image: [GCRのimage]
しかし、GCRのimageをpullして実行環境を作成するにはGCPのアカウントの認証情報が必要なようで以下の様なエラーになります。
Error response from daemon: unauthorized: You don't have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication
最初に別のimageをコンテナ化して、そのコンテナに認証情報を登録してimageをpullできればできそうでしたが、今回は別の方法を模索することにしました。
② Docker Hubを使用して実行環境を作成する
①とほぼ同様の方法で、Docker imageの格納先をDocker Hubに変更します。
しかし、他の機能でのimageの管理はGCRで行なっており、新たにDocker Hubを使用すると管理するコストや手間が増えるのでまた別の方法を模索することになりました。
③ GCPのSDK imageを使用して実行環境を作成して、その後job移行の過程でGoをinstallする。
結論としてこちらの対策を取りました。
google/cloud-sdkをpullして環境を構築し、その後Goの1.19をcurlコマンドでインストールします。
これで、今回の要件である「GCPのサービスアカウントを使用すること」「Goのバージョンを1.7以上にすること」を満たすことができます。
実装
それでは、どの様に実装していったのかを記載していきます。
executorsで実行環境を定義しています。
今回は複数のexecutorがある中で追加する形だったのでgcloud-golang
という名称の実行環境を追加しました。
executors:
gcloud-golang:
<<: *defaults
docker:
- image: google/cloud-sdk:412.0.0
environment:
- GOPATH: /go
- PATH: /usr/local/go/bin:/go/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/google-cloud-sdk/bin/
Goをインストールするコマンドです。
commands:
go-install:
steps:
- run:
command: |
curl -Lso go.tar.gz "https://dl.google.com/go/go1.19.linux-amd64.tar.gz"
tar -C /usr/local -xzf go.tar.gz
rm go.tar.gz
executorsで定義した実行環境を指定し、Goをインストールするコマンドを打ち込みます。
次にcheckout
します。
jobs:
build:
executor:
name: gcloud-golang
steps:
- go-install
- checkout
上記の手順で今回の要件を満たすことができました。
おまけ
今回初めてGCRにimageを登録したので備忘録として手順を記載します。
私の環境はmacOS Montereyを使用しています。
Docker build
こちらの記事を参考にして以下のようなDockerfileを作成します。
FROM google/cloud-sdk:412.0.0
ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/bin:$PATH
ENV GOLANG_VERSION 1.19
RUN curl -Lso go.tar.gz "https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz" \
&& tar -C /usr/local -xzf go.tar.gz \
&& rm go.tar.gz
ENV PATH /usr/local/go/bin:$PATH
Dockerfileをbuildしてimageを作成します。
その後に作成したimageを起動してログインします。
docker run -it [image ID] /bin/bash
コンテナ
コンテナにログイン後にgcloudコマンドでログインします。
ブラウザへのリンクが表示されるので、任意のブラウザリンクを打ち込んでGCPのアカウントで認証します。
# gcloud auth login
Go to the following link in your browser:
https://~省略~
Enter authorization code: ~ブラウザで確認したコードを入力する。
You are now logged in as [GCPのアカウントのメールアドレス].
Your current project is [None]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
gcloud auth configure-docker
コマンドを実行します。
gcloud auth configure-docker
コマンドに関しての詳細はこちらです。
# gcloud auth configure-docker
Adding credentials for all GCR repositories.
~ 省略 ~
Do you want to continue (Y/n)? Y
Docker configuration file updated.
プロジェクト名を設定します。
# gcloud config set project [GCPのproject名]
Updated property [core/project].
コンテナでの設定は終了したのでコンテナを抜けます。
exit
ローカル環境
先ほど起動したコンテナの情報を確認してコンテナをイメージ化します。
GCRのレジストリの命名規則はこちらを参照ください。
毎回タグにlatest
を付与すると、以前のtagはnoneになります。
% docker commit [コンテナ] asia.gcr.io/[プロジェクト内]/[GCRのフォルダ名]/[格納するGCRのimage名]:latest
最後にiamgeをGCRにpushします。
% docker push asia.gcr.io/[プロジェクト内]/[GCRのフォルダ名]/[格納するGCRのimage名]:latest
以上。