鳩小屋

落書き帳

Github Actions:CI


CICDはAWS CodeXシリーズしか触ったことがなかったのでGithub Actions(CI)を少し動かしてみました。
Dockerfileやアプリケーションを更新すると自動でイメージビルドとイメージプッシュが行われるシンプルな環境を構成します。

アプリケーションとDockerfileの用意

user@user-HP:~/gitops/code/app$ ls
Dockerfile  main.go

user@user-HP:~/gitops/code/app$ cat main.go 
package main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w,"Hello GitOps!!")
}

func main(){
  http.HandleFunc("/",handler)
  http.ListenAndServe(":8080",nil)
}
user@user-HP:~/gitops/code/app$ cat Dockerfile 
# Stage-1
FROM golang:1.16 as builder
COPY ./app/main.go ./
RUN go build -o /gitops-go-app ./main.go

# Satge-2
FROM ubuntu
EXPOSE 8080
COPY --from=builder /gitops-go-app /.
ENTRYPOINT ["./gitops-go-app"]

上記が格納されたgitリポジトリを用意します。
f:id:FallenPigeon:20210815180703p:plain

GitHub Actionsのセットアップ

f:id:FallenPigeon:20210815180844p:plain
f:id:FallenPigeon:20210815181101p:plain

Secretの登録

ワークフローの設定で参照するシークレットを作成します。
f:id:FallenPigeon:20210815181437p:plain

ローカルリポジトリとの同期

user@user-HP:~/gitops/code$ git pull

ワークフローの設定

user@user-HP:~/gitops/code/.github/workflows$ nano main.yml                                                                       

name: Github Action CI

# mainブランチへのプッシュをトリガーにする
on:
  push:
    branches: [ main ]

jobs:
  build:
    name: GitOps Workflow
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      #Buildkitによるイメージビルド
      - name: Build an image from Dockerfile
        run: |
          DOCKER_BUILDKIT=1 docker image build . -f app/Dockerfile --tag ${{ secrets.DOCKERUSER }}/gitops-go-app:latest
      #Trivyによるイメージスキャン  
      - name: Run Trivy
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: '${{ secrets.DOCKERUSER }}/gitops-go-app:latest'
          format: 'table'
          exit-code: '1'
          ignore-unfixed: true
          severity: 'CRITICAL,HIGH'
      #Docker Hubにイメージプッシュ
      - name: Push Image
        run: |
          docker login docker.io --username ${{ secrets.DOCKERUSER }} --password ${{ secrets.DOCKERPASSWORD }}
          docker image push ${{ secrets.DOCKERUSER }}/gitops-go-app:latest

リポジトリへのプッシュ

user@user-HP:~/gitops/code$ git add .
user@user-HP:~/gitops/code$ git commit -m "main.yml change"
user@user-HP:~/gitops/code$ git push -u origin main

ワークフローの確認

自動でワークフローが起動します。

f:id:FallenPigeon:20210815182859p:plain

エラーが出たとき
f:id:FallenPigeon:20210815183412p:plain

成功時
f:id:FallenPigeon:20210815183128p:plain

Docker Hubの確認

ワークフローが完了するとlatestタグのついたイメージが格納されているのが確認できます。
f:id:FallenPigeon:20210815183607p:plain

まとめ

セキュリティ観点では、ソースコード、Dockerfile、コンテナイメージの診断処理も実施すると良さそうです。
Argo CD等でKubernetesと連携すれば、コンテナ型CICDパイプラインが完成するはず。