GitHub Actionsでデプロイを記録する

こんにちは、@katzchangです。これは New Relic Advent Calendar 2019 - Qiita、12/6の記事です。みなさん、今日もデプロイしていますか?

デプロイが行われるということは、何らかの意図した挙動の変化を期待してるはずです。新しい機能の追加、パフォーマンスの改善など。そしてご存知の通り、アプリケーションのデプロイにはリスクが伴います。だいたいのトラブルはアプリケーションのデプロイが原因だったりします。私はこれを、デプロイの「作者の意図」と「副作用」と呼んでたりします(まれに良い副作用もある)。

つまり、モニタリング上の挙動の変化とデプロイは、関連が深いのです。

という背景がありつつ、New Relic APMではデプロイを記録することができるようになっているので、その紹介をさせていただこうかと思っております!せっかくなので先月から正式版となったGitHub Actionsで動かしてみるところまでやってみます。

デプロイを記録する

デプロイの記録は各言語のエージェントで用意しているAPI経由でもできますが、ここは単純にPOSTリクエストを送る方法をとってみましょう。ドキュメントを開くと、 curl コマンドの例が見えます。なるほど、できそう。

f:id:katzchang:20191205204449p:plain
おなじみのコマンド

これをMakefileに書き下すと例えばこんな感じになります。ほぼそのままです。

deploy-create:
    curl -X POST 'https://api.newrelic.com/v2/applications/$(application_id)/deployments.json' \
         -H 'X-Api-Key:$(NEW_RELIC_REST_API_KEY)' -i \
         -H 'Content-Type: application/json' \
         -d '{"deployment":{"revision":"$(revision)","changelog":"$(changelog)","description":"$(description)","user": "$(user)"}}'

これでもう、終わったようなものですね。

REST API Keyを取ってくる

上のドキュメントからたどると、REST API Keyを取ってくるためのドキュメントにたどり着きます。なるほど、アカウント管理からたどればいいのか。

f:id:katzchang:20191205204416p:plain
中途半端に下の方にある

生成したAPIキーは、環境変数に設定するのがとりあえずよいと思います。zshを使っていれば、 ~/.zshenv に書いていきます

export NEW_RELIC_REST_API_KEY=NRRA-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

シェルを起動しなおしたりすると、環境変数が設定された状態になるはずです。

application_idを取ってくる

APMのapplication idは、URLを見るのが一番はやいでしょう。

f:id:katzchang:20191205204335p:plain
APMのURL

applications の次の数字(ここでは 475666074 )がapplication idです。

リクエストを組み立てよう

あとのパラメータはとりあえず適当にやってみます。まずは動かしてみることが大事です。

revision:=$(shell git rev-parse HEAD)
description:=$(shell git log -1 --oneline)
application_id:=475666074
user=$(shell git log -1 --pretty=format:'%an')
deploy-create:
    curl -X POST 'https://api.newrelic.com/v2/applications/$(application_id)/deployments.json' \
         -H 'X-Api-Key:$(NEW_RELIC_REST_API_KEY)' -i \
         -H 'Content-Type: application/json' \
         -d '{"deployment":{"revision":"$(revision)","changelog":"$(changelog)","description":"$(description)","user": "$(user)"}}'

動かしてみよう

叩いてみます。

make deploy-create
curl -X POST 'https://api.newrelic.com/v2/applications/475666074/deployments.json' \
         -H 'X-Api-Key:NRRA-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -i \
         -H 'Content-Type: application/json' \
         -d '{"deployment":{"revision":"25ccfa8ad1427caa9c4895ed4c6a72aad6f27c90","changelog":"","description":"25ccfa8 fix...","user": "Kazunori Otani"}}'
HTTP/1.1 201 Created
Proxied-By: Service Gateway
Content-Security-Policy: frame-ancestors *.newrelic.com
Cache-Control: max-age=0, private, must-revalidate
Content-Length: 293
Content-Type: application/json
Date: Thu, 05 Dec 2019 11:27:15 GMT
Etag: "1cbcc8f7b8f9124ba6fb97d66e67c1e6"
Server: nginx
Status: 201 Created
X-Rack-Cache: invalidate, pass
X-Request-Id: 62377002304bcbcbd1f584335e347804
X-Runtime: 0.294061
X-Ua-Compatible: IE=Edge,chrome=1

{"deployment":{"id":47717396,"revision":"25ccfa8ad1427caa9c4895ed4c6a72aad6f27c90","changelog":"","description":"25ccfa8 fix...","user":"Kazunori Otani","timestamp":"2019-12-05T03:27:15-08:00","links":{"application":475666074}},"links":{"deployment.agent":"/v2/applications/{application_id}"}}% 

HTTP/1.1 201 Created とあるので、成功したっぽいです。APMのOverviewを開いて、デプロイが記録された様子を見てみましょう。

f:id:katzchang:20191205204240p:plain
オーサムなデプロイ

完璧です。

GitHub Actionsを使ってみる

GitHub Actionsは先月から正式版になった、GitHub謹製のサービスです。Gitの動作にフックして、いろんな挙動をもたせることができます。

ここではとりあえず、masterへのpushを以てデプロイを記録することにしましょう。

name: New Relic 

on:
  push:
    branches:
    - master

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: test
      run: make test
    - name: deploy create
      env:
        NEW_RELIC_REST_API_KEY: ${{ secrets.NEW_RELIC_REST_API_KEY }}
      run: make deploy-create

APIキーは隠したいので、Secretsに入れることにします。リポジトリのSettingsタブから、設定項目を探してみましょう。

f:id:katzchang:20191205205201p:plain
秘密の情報

これで、 push master したり merge master すると、デプロイマーカーが記録されることになります。リポジトリのActionsタブを開くと、アクションの結果を見ることができます。

f:id:katzchang:20191205205510p:plain
苦悩の歴史が垣間見れます

GitHub Actionsに直接curlコマンドを書くこともできなくない。が、Makefileを用意することで、他のCIサービスで動かしたり、サーバ内のスクリプトで動かしたり、もしくは自分のMacBookから動かしたりしても、一貫したメッセージが記録されます。つまり、可搬性がよい。

いつ記録するか?それが問題だ

今回はmasterリポジトリへのpushで、デプロイとして記録することにしました。デプロイブランチを運用しているならそのブランチの変更を検知してもいいし、タグをつけてるならそれでもいいかもしれない。EC2などのVMやコンテナが複数ある場合が多い昨今なので、いつの時点が本当のデプロイと呼べるのかよくわからないときありますよね。まあでもいいんです、そんなことは。とりあえず便利な情報が出るようにしましょう。

はい、Deploymentタブから、デプロイの記録がみれるようになります。

f:id:katzchang:20191205205854p:plain
輝かしい歴史の一旦

これで、メトリックの変化、エラーの変化とデプロイがひと目でわかるようになりました。便利!

github.com

今回の内容は上のリポジトリに全部つっこんでいます。参考になれば幸いでございます。