Terraform ハンズオン with MySQL Provider

    Terraform を勉強するには実際に使ってみるのが一番手っ取り早いですが、 では手頃な題材はあるかと言われると少し難しいです。 公式の Getting Started では AWS が使われていますが、 AWS のアカウントやクレデンシャルが必要ですしお金もかかってしまいます(無料枠はありますが)。 もう少し手軽なものが欲しいところです。 そこで公式の Provider で丁度いいものはないか探したところ、 MySQL Provider が良さそうでした。 MySQL のユーザーや Database を Terraform で管理したいとは自分は思いませんが、 Terraform の入門で遊ぶにはちょうどよいでしょう。 ちなみに公式の Provider のリストはこちらです。 https://github.com/terraform-providers https://www.terraform.io/docs/providers/index.html また、 Terraform に関しては Terraform 入門 も参照してください。 今回の作業用に適当にディレクトリを作成し、そこで作業しましょう。 以降、コマンドの実行結果は一部省略することがあります。 $ mkdir workspace $ cd workspace Terraform のバージョンと tfenv Terraform を複数人で使う場合、 Terraform のバージョンを揃えるのが重要です。 理由の一つとして、 Terraform の State は State を作成した Terraform のバージョンを記録しており、それより古いバージョンの Terraform で terraform plan などを実行すると失敗するようになっていることが挙げられます(この点については後でも触れます)。 そういう意味では、 tfenv によってバージョン管理するのが良いです。

    Terraform 入門

    参考 10分で理解するTerraform | Qiita Terraform入門資料(v0.12.0対応) ~基本知識から設計や運用、知っておくべきtipsまで~ | Qiita AWSでTerraformに入門 | Developers.io Terraform職人入門: 日々の運用で学んだ知見を淡々とまとめる | Qiita 手を動かしたい方は Terraform ハンズオン with MySQL Provider も参考にしてください。 前提 執筆時点 (2020/01/05) で Terraform の最新バージョンは v0.12.18 です Terraform とは Terraform は Infrastructure as Code を実現する汎用的なCLIツールです。 インフラの状態を設定ファイルに定義し、コマンドを実行することで、 実際のインフラの状態と設定ファイルの差分を検知し、設定ファイルに記述されたとおりになるようにインフラを変更(CRUD)します。 Hashicorp という企業がホストしている OSS になります。 Go で書かれています。 https://github.com/hashicorp/terraform Terraform のインストール Terraform は Go 製なので 1 バイナリをダウンロードしてインストールするだけです。 https://www.terraform.io/downloads.html tfenv を使うと管理が楽です。 https://github.com/tfutils/tfenv tfenv は Terraform のバージョン管理ツールです。 pyenv や rbenv の Terraform 版みたいなものです。

    Terraform の State Locking の概要

    Terraform の State Locking という機能の概要について説明します。 ただし、自分もちゃんと理解しているわけではないので、推測も混じります。 基本的には公式ドキュメントに書いてある内容なのでそちらをご参照ください。 State Locking とは terraform plan などのコマンドは State を変更する場合があります。 その処理は atomic ではないため、同時に複数のコマンドが State を書き換えようとすると不整合が生じる可能性があります。 例えば S3 backend の state を state rm で更新する場合を考えます。 これはコマンド内部で 現在の State を取得する (READ) 修正した State を S3 に push する (WRITE) という処理を行っているはずであり、複数のコマンドを実行した場合、READ と WRITE の間に他のコマンドによって WRITE されると、その WRITE による変更が消えてしまいます。 そこで State Locking を使うと各コマンドで State を変更する前に lock を取り、WRITE 後に lock を解除します。 コマンドラインオプション plan, apply, refresh, state rm, state mv, state push には次のようなオプションがあります。

    Terraform Providerで import を実装する方法

    terraform provider graylog で alert condition と stream rule の import を実装しました。 https://github.com/suzuki-shunsuke/go-graylog/pull/59 https://github.com/suzuki-shunsuke/go-graylog/pull/60 そこで import を実装する方法を紹介したいと思います。 terraform でリソースをimportするにはリソースがimportをサポートしている必要があります。 schema.Resource の Importer フィールドですね。リソースがIDだけでGet出来る場合、schema.ImportStatePassthroughを使えば終わりです。 一方、Graylogのalert condition や stream rule はIDだけでなく、stream id も必要になります。 terraform import コマンドは1つの引数しか取らないため、サポートできないのでは?と以前まで思っていました。 そういった場合、次のようにStateFuncを実装すればサポートできます。 https://github.com/suzuki-shunsuke/go-graylog/pull/59/commits/baee1165f49d2bc21b6ea7551ceff6b7daf01543#diff-f41be2a3640efd12ad4e808d77c5c8d5 # "/" で区切って stream id と ID を渡す $ terraform import graylog_alarm_callback.test 5bb1b4b5c9e77bbbbbbbbbbb/5c4acaefc9e77bbbbbbbbbbb 区切り文字は何でも良いのでしょうが、公式のprovider が “/” で区切っていたのでそれに従うことにしました。 https://www.terraform.io/docs/providers/google/r/spanner_database.html#import https://godoc.org/github.com/hashicorp/terraform/helper/schema#ImportStatePassthrough の実装を見てみれば分かりますが、 StateFunc の中では GET API を叩いてリソースを取得したりはしません。 terraform import コマンドの標準出力を見ると分かりますが refresh を実行しているのでそこでGETしているようです。 StateFunc は *schema.

    Graylog の Terraform を CI/CDで実行する

    以前 Graylog を Terraform で管理する記事を書きました。 https://suzuki-shunsuke.github.io/graylog-terraform/ 今回はそれを CI/CD で実行できるようにした話です。 ただし、今回の内容は Graylog に限らず Terraform を CI/CD で実行する方法として使えると思います。 今回実現したのは以下のことです。 PR時にテストをする plan/* tag を push すると terraform plan が実行される apply/* tag を push すると terraform apply が実行され、tfstate がコミット、プッシュされる ソースコード https://github.com/suzuki-shunsuke/example/tree/master/graylog-terraform に置いておきました。 https://github.com/suzuki-shunsuke/example/blob/master/graylog-terraform/role.tf#L13-L25 https://github.com/suzuki-shunsuke/example/blob/master/graylog-terraform/user.tf#L12-L21 https://github.com/suzuki-shunsuke/example/blob/master/graylog-terraform/.drone.yml https://github.com/suzuki-shunsuke/example/blob/master/graylog-terraform/terraform.tfvars.tpl https://github.com/suzuki-shunsuke/example/blob/master/graylog-terraform/drone_pipeline_commands/git.sh CI/CD用の user, role を作成する まずは role を作成します。 resource "graylog_role" "terraform" { name = "terraform" description = "terraform" permissions = [ "dashboards:*", "indexsets:*", "inputs:*", "roles:*", "streams:*", "users:*", ] } permission は terraform で管理するリソースのみ付与しますが、 それでも結構強い権限を付与するので取扱に注意してください。

    GraylogをTerraformで管理する

    Graylogのリソースを terraform で管理するために作った terraform provider を紹介します。 Graylogとは何かはこちらを読んでください。 Graylogには様々なリソースがあります。 User Role Input Index Set Stream Stream Rule Dashboard Alert etc これらのリソースはWeb UIから作成したり出来るわけですが、 Web UIでポチポチするのは疲れますし、ソースコードで管理したいものです(Infrastructure as Code)。 また、Web UIからでは細かな権限管理は出来ず(限られた権限管理しか出来ない)、APIを使ってする必要があります。 APIを使って管理できるツールを探したものの見つからなかったので、 APIを使ってGraylog用のterraform providerを自作しています。 https://github.com/suzuki-shunsuke/go-graylog GraylogのAPIの種類は非常に多く、残念ながらカバーできているのは一部だけですが、以下のようなものをサポートしています。 Alert Condition Alert Notification (Alarm Callback) Input User Role Index Set Stream Stream Rule Dashboard Ldap Setting Role はサポートしているので権限管理は問題なく出来ます。 Dashboard Widget もサポートしたいです。 出来れば Alert の設定も出来ると良いのですが、Alertに関するCRUD APIが提供されていない(GETのみ)ので、サポートできません。 terraform を使った管理方法 以下では自分の管理方法を紹介します。 https://github.com/suzuki-shunsuke/example/tree/master/graylog-terraform にサンプルが置いてあります。 基本はプロジェクトごとに Index Set, Stream, Role といったリソースを作成 User に Role を付与 という流れになります。