- CodePipeline よ Github や CodeCommit と連携出来るのはわかった
- ということで
— ざっくり構成
— Backlog Git の Webhook は…
— Lambda ファンクションは…
— API Gateway と Lambda ファンクションのセットアップは…
— CodePipeline と S3 バケットの連携は…
— Codebuild では Ruby のテストを走らせてみる - まとめ
— 課題
— Serverless Framework
CodePipeline よ Github や CodeCommit と連携出来るのはわかった
では、Backlog Git と連携はどげんすればよかとかね。
その答えにヒントを与えてくれたのは以下の記事。
Integrating Git with AWS CodePipeline | AWS DevOps Blog
なるほど…とにかく、何らかの方法で Codepipeline までソースコードをお届け出来れば…ということで、Backlog Git の Webhook と API Gateway + Lambda を組み合わせればいけそうな気がする!
ということで
ざっくり構成
以下のような構成を作ってみた。
Backlog Git の Webhook は…
以下のような JSON データを送信する。
{ "before": push前のコミット, "after": push後のコミット, "ref": 参照 "repository": { "url": リポジトリのURL, "name": リポジトリ名, "description": リポジトリの説明, }, "revisions": [{ "id": コミットのID, "url": コミットのURL, "author": { "email": コミットした人のメールアドレス, "name": コミットした人の名前 }, "message": コミットメッセージ, "timestamp": タイムスタンプ, "added": [ 追加されたファイル ], "removed": [ 削除されたファイル ], "modified": [ 修正されたファイル ], }] }
詳細は以下のページに記載されている。
www.backlog.jp
Lambda ファンクションは…
Python で書いてみた。
# -*- coding: utf-8 -*- import os import os.path import sys import urllib import urlparse import shutil import json sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'vendor')) import boto3 import dulwich.client from dulwich.repo import Repo from dulwich import porcelain target = os.environ['TARGET_DIR'] username = os.environ['USER_NAME'] password = os.environ['PASSWORD'] source_bucket = os.environ['BUCKET_NAME'] def git_clone(repo_url): print repo_url + ' からソースコードを取得します.' parsed_url = urlparse.urlparse(repo_url) src = parsed_url.scheme + '://' + username + ':' + password + '@' + parsed_url.netloc + parsed_url.path + '.git' if not os.path.isdir(target): os.mkdir(target) else: shutil.rmtree(target) try: porcelain.clone(src, target) except Exception as e: print(e) print(os.listdir(target)) def zip_files(): print 'ソースコードを zip で圧縮します.' try: shutil.make_archive(target, 'zip', target) except Exception as e: print(e) def upload_to_s3(): print '圧縮したソースコードを s3 にアップロードします.' zip_file_name = target.split('/')[-1] s3 = boto3.client('s3') try: s3.upload_file(target + '.zip', source_bucket, zip_file_name + '.zip') except Exception as e: print(e) def git(event, context): payload = json.loads(event['body']['payload']) repo_url = payload['repository']['url'] git_clone(repo_url) zip_files() upload_to_s3() response = { 'statusCode': 200 } return response
以下の点を直したいけど取り急ぎ。
- エラー処理
- 環境変数で指定している各種値を KMS で暗号化
API Gateway と Lambda ファンクションのセットアップは…
Serverless Framework を使えば一瞬だった… serverless.yml は以下の通り。
service: slstest provider: name: aws runtime: python2.7 region: ap-northeast-1 iamRoleStatements: - Effect: "Allow" Action: - "s3:PutObject" Resource: "arn:aws:s3:::demodemo-codepipeline/*" functions: hello: handler: handler.git memorySize: 128 timeout: 60 events: - http: path: git/push method: post integration: lambda request: parameters: querystrings: payload: true environment: USER_NAME: kappa PASSWORD: xxxxxxxxxxxxxx TARGET_DIR: /tmp/oreno-repo BUCKET_NAME: demodemo-codepipeline
今まで何で Serverless Framework を使っていなかったんだろうと後悔。
CodePipeline と S3 バケットの連携は…
以前に書いた記事を参考にした。
inokara.hateblo.jp
これはマネジメントコンソールから。
S3 バケットを作って、バージョニングを有効にして CodePipeline からソースプロバイダとして指定するだけ。
Codebuild では Ruby のテストを走らせてみる
以下のドキュメントを参考にして Codebuild で Ruby のテストを走らせてみた。
docs.aws.amazon.com
ファイル構成は以下の通り。
$ tree oreno-repo/ oreno-repo/ ├── HelloWorld.rb ├── HelloWorld_spec.rb └── buildspec.yml 0 directories, 3 files
buildspec.yml は以下の通り。
version: 0.1 phases: install: commands: - echo Installing RSpec... - gem install rspec build: commands: - echo Build started on `date` - echo Compiling the Ruby code... - rspec HelloWorld_spec.rb post_build: commands: - echo Build completed on `date` artifacts: files: - HelloWorld.rb
実際にビルドを走らせた図。
あえて Failed させている。
まとめ
課題
本構成には以下のような課題が残っている。
- Webhook 用 URL のアクセス制限(API キーによる認証又は IP アドレス制限)
- Lambda ファンクションで利用する環境変数の暗号化(KMS と連携させる)
- ブランチ毎に処理を変えられるようにする(master ブランチ以外のブランチだけでビルドが走るようにするとか)
Serverless Framework
API Gateway と Lambda のセットを丸っとサクッと作ってくれるのが気持ち良すぎた。
元記事はこちら
「いろいろとツッコミどころはあるばってん、Backlog Git と AWS CodePipeline の連携について考察してみたくさ」