Edited at

WerckerCI + CodeDeployでGolangのCI環境を整える

More than 3 years have passed since last update.

結構ハマってしまったので設定ファイルを残しておきます。

① Werckerでビルドし、

② CodeDeployでEC2にデプロイ

という流れにしています。

develop環境ではCodeDeployを使わずにscpを使ってデプロイしてます。頻繁にビルド&デプロイを行うので、毎回S3にビルド成果物を置くのがもったいないと考えたのでそうしました。(大した金額にならないと思うので置くのもありですが)

CodeDeployはAutoScaleグループに対してローリングデプロイができ、便利です。


wercker.yml

box: golang

build:
steps:
- setup-go-workspace

# Check go and gb version
- script:
name: check go version
code: |
go version

# Build the project
- script:
name: gb build
code: |
go get github.com/constabulary/gb/...
gb vendor restore
gb build

# Test the project
- script:
name: gb test
code: |
gb test -v

- script:
name: artifacts copy
code: |
cp -a ./bin ./conf ./resources ./server ./appspec.yml ./deploy_script $WERCKER_OUTPUT_DIR

# slack notification
after-steps:
- slack-notifier:
url: $SLACK_URL
channel: wercker
username: wercker
icon_url: $SLACK_ICON_URL
notify_on: "failed"

deploy:
development:
- script:
name: show archive files
code: |
find .

- script:
name: archive
code: |
FILE_DATE=$(date +"%Y%m%d_%H%M")
FILE_NAME=${FILE_DATE}.tgz
tar zcvf $FILE_NAME *
mkdir artifact
mv $FILE_NAME artifact

- add-ssh-key:
keyname: WERCKER_SSH_KEY_PRIVATE

# deploy to development server
- script:
name: scp deploy to development server
code: |
ssh -o "StrictHostKeyChecking=no" ec2-user@$SERVER_DEVELOPMENT 'rm -rf /opt/app/api/*'
scp -o "StrictHostKeyChecking=no" -r artifact/* ec2-user@$SERVER_DEVELOPMENT:/opt/app/api/
ssh -o "StrictHostKeyChecking=no" ec2-user@$SERVER_DEVELOPMENT 'cd /opt/app/api && tar zxvf *tgz'
ssh -o "StrictHostKeyChecking=no" ec2-user@$SERVER_DEVELOPMENT 'sudo /usr/local/bin/supervisorctl restart all && sudo /usr/local/bin/supervisorctl status'

production:
- script:
name: show archive files
code: |
find .

- script:
name: archive
code: |
FILE_DATE=$(date +"%Y%m%d_%H%M")
FILE_NAME=${FILE_DATE}.tgz
tar zcvf $FILE_NAME *
mkdir artifact
mv $FILE_NAME artifact

- s3sync:
key-id: $AWS_ACCESS_KEY_ID
key-secret: $AWS_SECRET_ACCESS_KEY
bucket-url: s3://$AWS_BUCKET_NAME/$AWS_BUCKET_PATH/
source-dir: artifact/
delete-removed: false

- script:
name: install pyinstaller
code: |
python --version
which python
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
sudo pip install awscli

- script:
name: CodeDeploy
code: |
aws deploy create-deployment \
--application-name app-api \
--s3-location bucket=$AWS_BUCKET_NAME,key=$AWS_BUCKET_PATH/$FILE_NAME,bundleType=tgz \
--deployment-group-name deploy-group-app-api \
--region ap-northeast-1

# slack notification
after-steps:
- slack-notifier:
url: $SLACK_URL
channel: wercker
username: wercker
icon-url: $SLACK_ICON_URL


appspec.yml

version: 0.0

os: linux

files:
- source: /
destination: /opt/app/api

hooks:
# アプリケーションを停止
ApplicationStop:
- location: deploy_script/stop_application.sh
timeout: 300
runas: root

# ビルド先のフィルを削除する
BeforeInstall:
- location: deploy_script/before_install.sh
timeout: 300
runas: root

# アプリケーションを起動
ApplicationStart:
- location: deploy_script/start_application.sh
timeout: 300
runas: root


deploy_script/stop_application.sh

#!/bin/sh

/usr/local/bin/supervisorctl stop unisize-api


deploy_script/stop_application.sh

#!/bin/sh

rm -rf /opt/unisize/unisize-api/*


deploy_script/start_application.sh

#!/bin/sh

service supervisord start
/usr/local/bin/supervisorctl start unisize-api

golangはテスト&ビルドが早くていい!