Terraformで一発起動できるNew RelicのAPMマイクロサービスDEMO環境を構築する(12/20追記)

Amazon EKS上で動くマイクロサービスのAPM、もちろんk8s/AWSインフラ監視も。locust付きでトラフィックも流せます。素敵! でもメンテナンスが2022年末で止まっていたので、今(2023年)の環境で動くようにしました。 ※落穂拾いを追記しました
2023.12.04

"From zero to Observability while you brew coffee"

New Relic 社の GitHub アカウント「New Relic Experimental」で、 newrelic-microservices-sandbox というリポジトリが公開されています。
これを使うと、New Relic の計装設定が既にされた状態の Kubernetes (k8s) クラスタ環境と、その上で動くマイクロサービスアプリケーションが手に入ります。

しかも負荷ジェネレータ locust のスクリプト(テストシナリオ)ファイルも同梱されているので、実際にトラフィックを流してその様子を New Relic で観察することができます。

さらに言うと、k8s 環境として Amazon EKS、つまり AWS 上での動作が想定されています。
EKS ということは AWS インテグレーションもし放題。つまり、ちょっと New Relic の画面を確認したりデモをしたりといった用途にめちゃくちゃ最適なのです。

こんな素敵な環境が terraform apply 一発 *1で起動し、同 destroy で削除することができるのです。

なんて素敵なんでしょう!
これを公開してくれた New Relic の方々に感謝してもしきれません。

ただ、これをいま動かそうとすると、いくつかの問題で起動させることができませんでした。
最終メンテナンスが 2022/11、記事執筆時点からみても 1 年前なので、動きの速い現代ではよくあること。仕方ないですね。。

と、ここであきらめるのも勿体ないので、手を入れて動かす事にしました。幸いコードを何行か修正するだけで動作するようになりましたので、その方法も合わせてご紹介します。 *2

起動方法

newrelic-microservices-sandbox を起動させる流れは以下のような感じです:

  1. オリジナルのリポジトリを、各自の GitHub リポジトリに fork する
  2. 同梱の GitHub Action を起動して、デモ環境用のブランチとコンテナイメージを作成する
  3. demo をローカルに clone
  4. New Relic のライセンスキーや AWS アカウントなどの環境設定を記載する
  5. terraform apply で一発で環境を構築する
  6. 必要に応じて locust でトラフィックを発生させる
  7. Enjoy!
  8. 使い終わったら terraform destroyで後片付けする

つまり 1. 〜 4. を一度やっておけば、あとは好きなときに 5.〜6. で起動、 8. で削除できるわけです。
素敵ですね!

なお前述した「今の環境で動かす」ところは、3. で clone してきたブランチに対して実施する感じになります。

必要なもの

newrelic-microservices-sandbox 以外に必要なものも列挙しておきます。

  • GitHub アカウント(Free プランで十分)
  • New Relic アカウント(Free プランで十分)
    • 計装に使うライセンスキー
    • 設定追加のためのユーザーキー
  • AWS アカウント
    • デプロイに使う IAM ユーザー (Administrator 権限) とそのクレデンシャル、MFA を設定していないもの
  • ローカル PC、あるいは VM などの CLI シェル環境
    • git コマンド、terraform、locust などのツールをインストール出来る環境

また動作させると、それに応じて(当然)AWS の利用費も発生しますので、その旨あらかじめご了承ください。
手元で数時間〜半日程度動かした感じだとだいたい $5〜$7 くらいだったので、今のレートだと ¥1,000 程度、多くて ¥1,500 くらいみておけば、といった感じでしょうか。

なおこの環境を起動すると、フルオープンの SecurityGroup が作成されます。そういう意味でも、このデモ環境は使う時に起動し、使い終わったら停止するようにしましょう。

備考:IAM ユーザについて

ここで使用する IAM ユーザは、Terraform の AWS プロバイダ を使って EKS 環境を deploy するためのものです。
MFA が設定されていると動作しない記述になっているので、普段お使いの IAM ユーザとは別に作成するといいでしょう。

そこに必要な権限は「Administrator 権限」、と上で書いたんですが、実際に動かしてみてみると以下のサービスに限定されていたようです。IAM ロール周りの作成削除が必要なので PowerUser Access ではダメみたいですね。

  • Amazon EC2(含む VPC、サブネット)
  • Amazon Elastic Kubernetes Service
  • AWS Identity and Access Management

気になる方は権限を限定することも考えてみてください。

やってみる

実際にやってみます。
公式の手順はこちら↓にあるので、これに従って進めてみましょう。

1. レポジトリの fork(手順 1.)

自分の GitHub アカウントに、該当リポジトリを fork してください。 Be sure to include all branches とあるように全てのブランチを fork する必要があるため、「 Copy the main branch only 」のチェックを外すことを忘れないようにしてください。 *3

リポジトリ名もそのままでいいですが、ぼくは(個人的に分かりやすくするために) newrelic-microservices-sandbox-202312 としました。

2. ビルド(手順 2.〜4.)

手順書の通りに GitHub Action を実行します。
手元で実行したところ、prepare fork ワークフローは 1 分半ほどで完了しました。

また、手順 2. でも言われているように、GitHub から注意を促されます。通常は fork したてのリポジトリの workflow をいきなり実行するのは大変危険だからですね、念のため、御自身の目で workflow ファイルをご確認下さい。 .github/workflows/ 以下に格納されています。

その後、こちらの手順に従ってデフォルトブランチを demo に変更します。

3. ローカルに clone(手順 5.)

作成されたブランチ demo をローカルに clone します。

% git clone git@github.com:<GitHubユーザ名>/newrelic-microservices-sandbox.git
% cd newrelic-microservices-sandbox-202312/

ちゃんと demo ブランチが clone されてきてますでしょうか。念のため確認してみて下さい。

% git branch
* demo

fork したコードの修正

前述したとおり、 clone したコードを一部修正します。
修正内容は以下の 2 ヶ所です。

  • データベース(mariadb)コンテナのイメージを LTS から作るように変更
  • k8s のバージョンを 1.21 --> 最新に変更

修正後の差分は以下のようになります:

% git diff -U1
diff --git a/apps/mysql/Dockerfile b/apps/mysql/Dockerfile
index 92d4fe6..e88c6cb 100644
--- a/apps/mysql/Dockerfile
+++ b/apps/mysql/Dockerfile
@@ -1,3 +1,3 @@
 #FROM mysql
-FROM mariadb:jammy
+FROM mariadb:lts-jammy
 
diff --git a/terraform/eks-cluster/cluster.tf b/terraform/eks-cluster/cluster.tf
index 45ffdd2..fc3aa52 100644
--- a/terraform/eks-cluster/cluster.tf
+++ b/terraform/eks-cluster/cluster.tf
@@ -2,3 +2,2 @@ resource "aws_eks_cluster" "nr_sandbox" {
   name     = var.cluster_name
-  version  = var.kubernetes_version
   role_arn = aws_iam_role.nr_sandbox-cluster.arn
diff --git a/terraform/eks-cluster/variables.tf b/terraform/eks-cluster/variables.tf
index e9ff573..abbf86f 100644
--- a/terraform/eks-cluster/variables.tf
+++ b/terraform/eks-cluster/variables.tf
@@ -3,6 +3 @@ variable "cluster_name" {
 }
-
-variable "kubernetes_version" {
-  type    = string
-  default = "1.21"
-}

順に説明します。

データベースコンテナのイメージを LTS から作るように変更

修正するファイルは以下です:

  • apps/mysql/Dockerfile

mariadb のコンテナイメージなのですが、 mysql アプリケーション用のコンテナイメージとして( mysql ではなく) mariadb:jammy使われています。ただこのまま起動すると、 mysqlcheck がないと理由で k8s のヘルスチェックに失敗し、全体として起動しません。

こちらをみると mariadb:jammy はバージョン 11.2 を指していますが、 mariadb 11 系のリリースは 2023 年 6 月。何か仕様変更があったのかもしれません。
同じ jammy でも 2022 年末当時のバージョンを示すよう lts-jammy を指定してみたところ、問題なく動作しましたので、ひとまずこれを指定します。 *4

k8s のバージョンを 1.21 --> 最新に変更

修正するファイルは以下のふたつです:

  • terraform/eks-cluster/cluster.tf
  • terraform/eks-cluster/variables.tf

k8s は記事執筆時点(2023.12)で 1.28 であり、指定してある 1.21 はもう EKS ではサポートされておらずクラスタを作成できません。
バージョンを指定しなければ最新の k8s が選択される とのことなので、ここではこの設定を思い切って削ります。

修正がおわったら、git add, commit して push します。

% git add .
% git commit -m 'fix'
% git push origin

GitHub に push すると、自動的に workflow がふたつ動き出すと思います。

このうち Repolinter Action のほうは失敗していても問題ありません。 *5

Build and push docker images ワークフローが正常に完了していたら完了です!
念のために実行ログをみたり、リポジトリが更新されているかを確認したり、実際に出来上がったイメージを手元に持って来て mysqlcheck があるか確認しても大丈夫です! *6

修正が終わったら手順にもどりましょう。

4. ローカルで各種環境の設定、deploy 準備(手順 6.〜9.)

New Relic のユーザーキーなどを設定します。
terraform/terraform.tfvars.sample から terraform/terraform.tfvars を作成し、そこに必要な情報を記載していきます。

% cd terraform/
% cp -piv terraform.tfvars.sample terraform.tfvars
  • cluster_name:
    • EKS クラスタの名称。 newrelic-microservices-sandbox で良さそうですが好みでカスタマイズしてください。
  • owner:
    • ここで指定した文字列が、作成される AWS リソースの owner タグに設定されます。
  • new_relic_license_key, new_relic_user_api_key:
  • new_relic_account_id:
  • new_relic_region:
    • お使いの New Relic アカウントのリージョンを US (米国)か EU (欧州連合)で指定します。どちらのリージョンか分からなくなったら、こちらのドキュメント を参考に確認して下さい。
  • repository_basepath:
    • GitHub リポジトリのパスを記載します。 <GitHub ユーザ名>/newrelic-microservices-sandbox-202312 のようになります。

それらを記載したら、 terraform init します(手順 9.)。 Terraform has been successfully initialized! と表示されたら準備完了です。

terraform plan してみろ、と表示されるので、まず AWS のクレデンシャルとリージョンを設定してから実行してみましょう。
なお、ちょっとでも AWS 利用費を安くするため、東京(ap-northeast-1)ではなくオレゴン(us-west-2)リージョンを設定しています。

% export AWS_PROFILE=<AWSプロファイル名>
% export AWS_DEFAULT_REGION="us-west-2"
% terraform plan

とくに問題なく実行できたでしょうか!

5. 環境構築(手順 10.〜11.)

では早速起動してみましょう!

% terraform apply
    :
Apply complete! Resources: 36 added, 0 changed, 0 destroyed.
    :

ドキュメントに「20〜30 分」とありますので、だいたいそのくらい見てください。 *7

この状態で既に New Relic への連携も終わっていると思うので、確認してみて下さい!

6. トラフィックを発生させる

特に手順にはないのですが、前述したとおり locust 用のスクリプトもあるので、トラフィックを流すこともできます。
負荷をかけるターゲット URL は terraform.tfstate に吐き出されていますので、それをひろって指定します(画面にも出力されています)。

% locust \
    --autostart \
    --web-port 3000 \
    --users 3 \
    --spawn-rate 3 \
    --locustfile ../apps/loadgen/locustfile.py \
    --host "http://$(jq -r '.outputs.loadbalancer_hostname.value' ./terraform.tfstate)"

locust の WebUI には `http://0.0.0.0:3000` から接続出来ます。

locust についてはこちらの記事もご参照ください!

7. Enjoy!

New Relic の UI をいじり倒してください!

8. 後片付け

terraform destroy で削除出来ます。簡単ですね!

たまに 1 回で消しきれないときがある(エラーで止まる)ことがありますが、その場合は再度 terraform destroy してください。 *8
削除にも 10〜15 分くらいかかります。

% terraform destroy

落穂拾い:kubectl を使えるようにする

「Terraform で検証環境を起動する」という本来の目的とは外れますが、やっておくと良いことを少し記載します。

実は、いまのままだと kubectl コマンドが実行できません。
実行しようとすると以下のようなエラーが出力されます:

% export KUBECONFIG="$(pwd)/newrelic-microservices-sandbox-202312.kubeconfig"
% kubectl cluster-info dump
% error: exec plugin: invalid apiVersion "client.authentication.k8s.io/v1alpha1"

ここは、API バージョンを v1beta1 にしてやることで使えるようになります。

--- a/terraform/kubernetes-objects/kubeconfig.tpl
+++ b/terraform/kubernetes-objects/kubeconfig.tpl
@@ -20,7 +20,7 @@ users:
 - name: ${cluster_name}
   user:
     exec:
-      apiVersion: client.authentication.k8s.io/v1alpha1
+      apiVersion: client.authentication.k8s.io/v1beta1
       command: aws-iam-authenticator
       args:
         - token

ちなみに普段EKSを使ってない方は、 aws-iam-authenticator が入ってないかもしれないので、そちらと、ついでに eksctl も入れておいてください。

% brew install eksctl aws-iam-authenticator

まとめ

Terraform いっぱつで New Relic のデモ環境が作れる newrelic-microservices-sandbox をご紹介しました。
本番環境でいろいろ試したり、他のひとにデモしたりするのも難しい、そもそも本番導入のまえに試したい、でも New Relic だけ立ち上げても見るものがなくて意味が無い。。こういったときに便利なサンプルアプリケーションだと思います。

ちなみにこれだけの段階だと、k8s 環境以外のインテグレーションは行われていないので、このあと CloudWatch メトリクスや VPC フローログも連携してみてください!

脚注

  1. 多少誇張してます
  2. 実はもうちょっと修正した方がいいところはあるのですが、とりあえず動くようにする最低限の修正となります
  3. 経験談
  4. 本当はバージョンを固定した方がいいのかもですが、 LTS ということで安心感もありこうしています。2026 年 6 月までは大丈夫のようです。あと 2 年半!
  5. それはそれでどうなんだという意見はごもっともですが、ここは完璧よりやり遂げることを優先したいと思います
  6. 全部ぼくがやったことです
  7. 「yes」と入力することに気付かない時間は除きます。せっかちなひとは「 -auto-approve 」をつけて apply するといいと思います。特に 2 回目以降は。
  8. ぼくの環境では、むしろ止まらないほうが珍しいです。何が悪いのか。。。