GitLabリポジトリへのPushをトリガーにS3にファイルをアップロードする

みなさん、GitLabは使っていますか??

そして、GitLabを使っている中でリポジトリの最新バージョンをS3にアップロードしたいと思ったことはありませんか??例えば..

  • リポジトリへのPushをトリガーに自動デプロイしたい!CDにはCodePipelineを利用したい。
  • EC2/Lambdaなどから最新のコンフィグファイルを参照させたい!コンフィグファイルはリポジトリ管理しているがEC2/Lambdaから参照できる状態ではない。などなど

S3にファイルを持っていきたい理由はいくつか考えられるかと思います。

そこで、本日は「GitLabリポジトリへのPushをトリガーにS3にファイルをアップロードする方法」を紹介したいと思います。

やってみた

検証環境

検証環境は以下の通りです。

$ cat /etc/system-release
Amazon Linux release 2 (Karoo)
$ sudo gitlab-rake gitlab:env:info

System information
System:
Current User:   git
Using RVM:      no
Ruby Version:   2.5.3p105
Gem Version:    2.7.6
Bundler Version:1.17.3
Rake Version:   12.3.2
Redis Version:  3.2.12
Git Version:    2.18.1
Sidekiq Version:5.2.5
Go Version:     unknown

GitLab information
Version:        11.10.4
Revision:       62c464651d2
Directory:      /opt/gitlab/embedded/service/gitlab-rails
DB Adapter:     PostgreSQL
DB Version:     9.6.11
URL:            http://gitlab.example.com
HTTP Clone URL: http://gitlab.example.com/some-group/some-project.git
SSH Clone URL:  git@gitlab.example.com:some-group/some-project.git
Using LDAP:     no
Using Omniauth: yes
Omniauth Providers: 

GitLab Shell
Version:        9.0.0
Repository storage paths:
- default:      /var/opt/gitlab/git-data/repositories
GitLab Shell path:              /opt/gitlab/embedded/service/gitlab-shell
Git:            /opt/gitlab/embedded/bin/git

GitLabはEC2上に構築しS3に対しオブジェクトを作成できる権限を付与しています。 また、gitlab.ymlhostは自身URLとなるように値を変更し、GitLabを再起動しています。

$ cat /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml
・・・・
  gitlab:
    ## Web server settings (note: host is the FQDN, do not include http://)
    host: XXXXXXXXXX
    port: 80
    https: false
・・・・
$ sudo gitlab-ctl restart

それでは実際に構築していきましょう!!

ファイルアップロード対象バケット作成

まずはアップロード対象バケットを作成します。バケット名、リージョンは任意のものに変更してください。

$ aws s3api create-bucket \
  --bucket XXXXXXXXXX \
  --create-bucket-configuration "LocationConstraint=ap-northeast-1"
{
    "Location": "http://XXXXXXXXXX/"
} 

GitLabプロジュエクト作成

ここからはGitLab(もしくはGitLabをホストしているOS)での操作になります。 GitLabプロジュエクトs3-upload-projectを作成します。

GitLab Runnerインストール

リポジトリへのPushをトリガーに処理を実行するためのライブラリを導入します。 下記のブログの GitLab Runnerの構環境築 を実施してください。

GitLab RunnerでCI/CDしてみる(前編)

※本記事も上記と同様、GitLab RunnerのexecutorにはDocker、BaseImageはpython:3.6.5を利用します。

各種ファイル作成

リポジトリをcloneします。

$ git clone http://XXXXXX/root/s3-upload-project.git
Cloning into 's3-upload-project'...
Username for 'http://XXXXXX/root/s3-upload-project.git': root
Password for 'http://root@XXXXXX/root/s3-upload-project.git': 
warning: You appear to have cloned an empty repository.

アップロード対象ファイル作成

S3にアップロードするファイルを作成します。

$ mkdir hoge huga
$ touch hoge/hoge.txt huga/huga.txt
tree
.
├── hoge
│   └── hoge.txt
└── huga
    └── huga.txt

2 directories, 2 files

Dockerイメージ定義ファイル作成

リポジトリPush時に起動されるコンテナの設定/定義を.gitlab-ci.ymlとして作成します。

trigger_pipeline:
  image: python:3.6.5
  variables: # 任意の値に変更すること
    AWS_REGION: XXXXXXXXX
    S3_BUCKET: XXXXXXXXX
    S3_OBJECT_KEY: XXXXXXXXX
  before_script:
    - apt-get update && apt-get install -y zip git
    - pip install --upgrade awscli
    - aws configure set default.region ${AWS_REGION}
  script:
    - dockerfiles/archive-and-upload-src.sh

対象ファイルを圧縮するためにzipを、S3にファイルをアップロードするためawscliをそれぞれ導入します。このコンテナからarchive-and-upload-src.shを呼び出すことでファイルをS3にアップロードします。

シェルスクリプト作成

S3にファイルをアップロードするためのスクリプトを作成します。アップロードファイルにはgitのコミットハッシュとhogehugaディレクトリを含めます。

dockerfilesディレクトリを作成した後、以下のシェルを配置します。

SOURCES="./hoge ./huga"

rm -f src.zip
git rev-parse HEAD | cut -c 1-8 > .git-commit-hash
zip -r src.zip .git-commit-hash $SOURCES

aws s3api put-object \
  --bucket $S3_BUCKET --key $S3_OBJECT_KEY \
  --body src.zip

最終的なファイル構成は以下のようになります。

$ tree
.
├── .gitlab-ci.yml
├── dockerfiles
│   └── archive-and-upload-src.sh
├── hoge
│   └── hoge.txt
└── huga
    └── huga.txt

リポジトリへのPush

準備が整いました。最後にリポジトリへファイルをPushしてみましょう!

$ git add .
$ git commit -m "first commit"
$ git push -u origin master

しばらくするとGitLab上のジョブが起動します。

指定のバケットに圧縮されたファイルが格納されていることを確認しましょう!

$ aws s3 ls s3://XXXXXXX
2019-05-15 21:09:55        775 XXXXXXX.zip
$ aws s3 cp s3://XXXXXXX.zip ./
download: s3://XXXXXXX.zip to ./XXXXXXX.zip
$ unzip XXXXXXX.zip
$ tree .
.
├── hoge
│   └── hoge.txt
├── XXXXXXX.zip
└── huga
    └── huga.txt

中身も想定通りのものであることが確認できました!!

さいごに

GitLabへのPushをトリガーに必要なファイルをS3にアップロードしてみました。皆さんも上手にS3を活用していきましょう!

参考