【小ネタ】TerraformとSSMパラメータストアを利用したLogentriesのトークン管理

2018.03.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、中山です。

最近すっかりCloudFormation一色になっていたのですが、久々にTerraformを使った際けっこう便利な発見があったので本エントリでご紹介したいと思います。先に結論を書くと Terraformを利用してAWS以外のサービスで生成した情報をSSMパラメータストアに突っ込むといろいろ捗る という話です。

Logentriesのトークン管理

Webアプリケーションを作成している場合、何らかの外部サービスを利用する機会は多いと思います。例えばログの送り先としてログ管理SaaSを利用するなどです。私が今関わっている案件ではLambda関数を中心としたサーバーレスアプリケーションを構築しているのですが、そのログ管理にLogentriesを利用しています。おおよその構成は以下のような感じです。

全体のフローは以下の通りです。

  1. Lambda関数のログは普通にCloudWatch Logsへ出力し、後段のKinesis Data Streamsにサブスクライブしておく
  2. Kinesis Data Streamsをポーリングしているログ転送用Lambda関数がレコードの投入を検知後、Logentriesへログを出力する

この内2点目がちょっとややこしいです。Logentriesにログを出力するためには出力先ログ毎に一意なトークンを生成する必要があります。例えば、Lambda関数が2つ存在しそれぞれログを分けて出力させたい場合(大半はそうだと思いますが)2つのトークンが必要になるということです。

ここでCloudWatch LogsをサブスクライブしているKinesis Data Streamsと、それをポーリングしているログ転送用Lambda関数が1つずつしか存在しない点に注意してください。つまり、転送すべきログは複数のLambda関数から送られてくるのでログの内容を見て適切なトークンを判定する必要があります。そうしないと、ログに複数のLambda関数の出力が混ざった状態になってしまうためです。

これを解決するためにLogentriesのトークンをSSMパラメータストアに保存するという仕組みにしています。仕組み自体は単純です。

  1. Logentriesでログとトークンを作成
  2. SSMパラメータストアにLambda関数名をキーとしてそのトークンを保存
  3. ログ転送用Lambda関数はKinesis Data Streamsから送られたデータからログ送信元Lambda関数名を判定、SSMパラメータストアからトークンを取得しLogentriesへログ出力

1と2の管理にTerraformを使っています、便利ですという話でした。ちょっと話長くなりました…

Terraformが便利な理由

Terraform以外でも同じようなことは実現できるかもしれませんが、私が特に便利だと思う点を以下に記載します。

1. 多くのIaaS/SaaS/PaaSを統一的に管理できる

TerraformはProviderという仕組みによってAWSを初めたとしたさまざまなサービスを扱うことが可能です。現在対応しているProvider一覧はドキュメントに記載されていますが、前述したLogentries以外にも現時点でさまざまなサービスに対応していることが分かるかと思います。これらIaaS/SaaS/PaaSをHCLというDSLによって統一的に管理することが可能です。また、当然ですがSSMパラメータストア用リソースにも対応しています。

CloudFormationはAWSに特化している分その管理においては優位な面がありますが、AWS以外のリソースを扱うことはできません(カスタムリソースでできなくもないが)。

2. バックエンドを利用した秘匿情報の管理

今回ご紹介したLogentriesの場合、トークンがStateに含まれています。このトークンは要するにパスワードと同じ扱いなのでリポジトリに直接突っ込んでしまうのはやめたいものです。デフォルトではTerraformを実行したPC上のローカルストレージにStateが保存されます。

TerraformはBackendという仕組みでStateをS3などのリモートストレージサービスに保存することが可能です。この機能を使うとStateはリモートストレージに保存してくれるのでリポジトリにトークンのような秘匿情報を含めずに管理することが可能です。

3. 構成管理の実現

当然ですがTerraformで管理すること自体にさまざまなメリットがあります。リポジトリで管理することによってCI/CDの仕組みを作る、Workspaceを利用して別AWS環境にも同じ仕組みを簡単に構築するなどです。

実際の所どんな感じか

能書きはいいとして実際どんな感じなのか。以下にサンプルとなるHCLファイルを記載します。

  • Logentries用HCL

Logentriesのセットアップにはlogentries_logsetlogentries_logを利用します。ログセットとはログをグルーピングするような機能で、私はAWS環境毎(開発/本番など)に作成しています。そして、このログセットの中に実際のLambda関数のログを出力させるという構成です。こうすると各環境毎にログを分けることができるので識別しやすくなります。

例えば、 test-func というLambda関数用のログ環境をセットアップしたい場合は以下のようになります。

resource "logentries_logset" "environment_logset" {
  name = "${terraform.workspace}"
}

resource "logentries_log" "test_func" {
  name      = "test-func"
  logset_id = "${logentries_logset.environment_logset.id}"
}

${terraform.workspace} はTerraformのWorkspaceを参照している(ログセット名をWorkspace名にしている)という意味です。このWorkspaceをAWS環境とひも付けるようにしています。この仕組によって、Workspaceを切り替えると別AWS環境に同じ仕組みを簡単に構築できるようになります。

  • SSMパラメータストア用HCL

SSMパラメータストアの方はシンプルですね。CloudFormationとほぼ同じです。

resource "aws_ssm_parameter" "test_func" {
  name  = "test-func"
  type  = "SecureString"
  value = "${logentries_log.test_func.token}"
}

まとめ

いかがだったでしょうか。

TerraformとSSMパラメータストアを利用したLogentriesのトークン管理についてご紹介しました。今回Logentriesに限定してご紹介しましたが、このSSMパラメータを仲介として全体をTerraformで管理するパターンは結構応用範囲広いのではないかと思ってます。つまり、他のサービスを利用する場合にも使える場合があるのではということです。いい感じにハマるパターンを見つけたら別エントリでご紹介できればと思います。

本エントリがみなさんの参考になれば幸いに思います。