CI/CDパイプラインへのGithub App導入
概要
元々、筆者が現在管理しているCI/CDフローにおいては、GitのPrivateリポジトリにアクセスする必要があり、その際には個人(筆者)に紐づく認証情報を使っていました。
要件としては過不足なく満たしていたものの、他方で、万一筆者が現職を辞した場合には、CI/CDフローが機能不全に陥るという状況がありました。端的に言って、あまり気持ちのいいものではなく、どうしたものかなと思っていたのですが、Github Appを利用することによって、この状況を改善できましたため、あらましを共有します。
Before
まず、従来の(Github App導入前の)github actionsや、Dockerfileのつくりが以下の通り(一部抜粋)です。なお、Dockerfileについては、同僚のkaito2氏が公開している記事の内容がベースになっております。
- name: set up ssh
run: |
mkdir -p ~/.ssh
echo "${GIT_PRIVATE_KEY}" > ~/.ssh/id_rsa
chmod 700 ~/.ssh/id_rsa
eval "$(ssh-agent)"
ssh-add ~/.ssh/id_rsa
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
git config --global url.git@github.com:.insteadOf https://github.com/
env:
GIT_PRIVATE_KEY: ${{ secrets.GIT_PRIVATE_KEY }}
#
# Build
#
FROM golang:1.19.5 as builder
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
ENV GOPRIVATE=github.com/fivot/go-lib
WORKDIR /build
RUN mkdir -p -m 0700 ~/.ssh && \
ssh-keyscan github.com >> ~/.ssh/known_hosts && \
git config --global url.git@github.com:.insteadOf https://github.com/
COPY . .
RUN go mod download
RUN go build -buildvcs=false -o /build/main ./cmd/...
上の通り、github actions において(筆者のアカウントに紐づく)githubのPRIVATE_KEYを、~/.ssh/id_rsa
に配置。その後、Dockerfile内において --mount=type=ssh go mod download
することで、Privateリポジトリの依存を解決していました。
Github Appの設定方法
Afterに筆を進める前に、個人的に結構ひっかかったので、Github Appの設定方法について記述しておきます。Organization単位でGithub Appを導入する場合、Github右上のアカウント設定から「Your organizations」へ進み、対象のOrganizationsについて「Setting」を選択。その後、画面左側の「Developper settings」から「Github Apps」を選択することで設定が可能です。
After
さて、Github App導入後のgithub actionsや、Dockerfileのつくりが以下の通り(一部抜粋)です。
- name: Generate token
id: generate_token
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_PRIVATE_KEY }}
repositories: >-
["go-lib"]
permissions: >-
{
"contents": "read"
}
#
# Build
#
FROM golang:1.22.3 as builder
ARG TOKEN
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
ENV GOPRIVATE=github.com/fivot/go-lib
WORKDIR /build
# トークンが提供されていればトークンを使用し、提供されていなければSSHを使用
RUN if [ -z "$TOKEN" ] ; then \
# SSHを使用する設定
mkdir -p -m 0700 ~/.ssh && \
ssh-keyscan github.com >> ~/.ssh/known_hosts && \
git config --global url.git@github.com:.insteadOf https://github.com/ ; \
else \
# トークンを使用する設定
git config --global url."https://x-access-token:${TOKEN}@github.com/".insteadOf "https://github.com/" ; \
fi
COPY . .
# トークンが提供されていれば通常のgo mod downloadを使用し、提供されていなければSSHを使用
RUN if [ -z "$TOKEN" ] ; then \
# SSHを使用してモジュールをダウンロード
--mount=type=ssh go mod download; \
else \
# 通常のHTTP経由でモジュールをダウンロード
go mod download; \
fi
RUN go build -buildvcs=false -o /build/main ./cmd/...
ローカルでの docker build
時にはトークンなしで実行可能なようにしているため、多少冗長な記述になっています。が、CI/CDパイプライン上ではGithub Appから払い出されたトークンを使って、そうでない場合、即ち各開発者のローカル環境においてビルドする場合には、通常通りに開発者が保有しているだろうsshの秘密鍵を使って、それぞれ依存を解決するように設定しました。
また、弊社のCI/CDパイプラインには suzuki-shunsuke氏のghalintを利用させていただいているため、lintで怒られてしまわないよう( the input permissions is required
が出ないよう)、actions内では明示的にpermission, repositoriesを指定しています。
まとめ
以上の通り、Github Appを導入することによって、筆者個人に紐づく認証情報を、CI/CDパイプラインから切除することができました。これでいつでも退職ができるという寸法です!!
......というのは冗談ですが、組織全体のCI/CDパイプラインが、組織内の一個人の在職如何というか、秘密鍵の有効状況に左右されるというのは、どう考えても健全な状況ではありませんので、もし(そうそうないとは思いますが)皆さまが似たような状況にありましたら、これを機会に、Github Appを導入してみるのはいかがでしょうか。
Discussion