TIG DXユニット 1 アルバイトの小林です。
案件で認証プラットフォームであるAuth0を利用しています。
Auth0がHashiCorpとのパートナーシップを結び、TerraformでAuth0リソースの管理が可能となりました。
https://auth0.com/blog/partners-with-hashicorp-terraform/
今回はTerraformで既存のAuth0リソースを移行するという観点で調査を行いました。
Auth0とは
Auth0の概要についてはAuth0導入編をご参照ください。他にも技術ブログにはAuth0関連の記事が沢山あります。
Terraformとは
TerraformとはHashiCorpによって開発されたオープンソースのクラウド管理ツールです。
クラウド環境のインフラの構成をコードに落とし込むことで、Git管理が可能になり、さらに状態を定義することが可能になるため、状態との差分からクラウド環境のリソース変更部分の表示が可能になるため、設定ミスのリスクを低減が見込めます。
技術ブログではTerrafom関連の記事が沢山あるためそちらも合わせてご参照ください。
また、Terraform以外でAuth0のクラウドリソースをコードに落とし込むツールにはauth0-deploy-cli
が上げられます。
Auth0 Deploy CLI
https://github.com/auth0/auth0-deploy-cli
Auth0が出しているツールで、テナント構成をyamlに落とし込んだり、yamlに書かれたテナント構成を反映するなど、CI/CDを可能にします。
Auth0 Deploy CLIについては、TIG市川さんのAuth0の設定をバージョン管理し、Auth0 Deploy CLIを利用してデプロイ環境を整えるをご参照ください。
Auth0 Deploy CLIには、dry-run
がサポートされておらず 8、実際に実行してみるまでテナント構成がどうなるのか分からない、さらに意図していない変更を検出出来ないといった課題があります。
Auth0 Deploy CLI vs Terraform
Auth0環境の構成をAuth0 Deploy CLIで行う場合とTerraformで行う場合について、それぞれの強みと弱みについて調査しました。
Auth0 Deploy CLIの強み
- テナントの構成をまるっとエクスポートすることが出来ます。
- rules,hooksもディレクトリに区切ってファイルを作成してくれるなど、親切です。
- mappingが公式サポートされています。
- auth0-deploy-cli/README.md:AUTH0_KEYWORD_REPLACE_MAPPINGS· auth0/auth0-deploy-cli
- そのため単一のyamlファイルを複数の環境に転用させて、検証環境と本番環境の設定の同一化が比較的容易に実現出来ます。
Auth0 Deploy CLIの弱み
- Auth0専用のツールなのでこのツールの操作方法を独自で覚える必要があります。
dry-run
機能が無いため意図していない設定変更が生じうる可能性があります 9。
Terraformの強み
- 独自ツール無しでTerraformだけで済むため、いままでAWSなどでTerraformを使っている場合、学習コストほぼ0で利用出来ます。
- Terraformには
plan
と呼ばれる現在の状態と変更後の状態の差分を表示させる、dry-run
に該当する機能があります。 - Terraform workspaceを利用することで同一のリソースブロックを複数環境で利用することが可能になります。これにより検証環境と本番環境の設定の同一化が比較的容易に実現出来ます。
Terraformの弱み
- 一括で全リソースをインポートする手段が無いためテナント設定が膨大の場合、Terraformで管理出来る状態に持っていくまでが大変です。
- terraformのimportをAuth0プロパイダで利用する際、IDの特定方法が複雑(後述)です。
今回、私の所属しているプロジェクトでは、他のクラウドリソースをTerraformで管理していること、
Auth0の構成が複雑になっていることから、plan
が非常に強力であり、作業ミスのリスクを大幅に減少出来る見込みのため、Terraformを採用することにしました。
Terraformで管理すると
Terraformで管理出来る様になると以下の点で便利になります。
- 環境毎の設定差異の検出が簡単に出来る。
- Auth0のリソース更新時にdry-runが可能になり、意図していないリソースの変更や、リソースの更新忘れのリスクを軽減できる。
- 環境全体がコードに落ちるためGitなどのバージョン管理ツールで管理が出来る様になる。
この記事では以下の2点について扱います。
- terraform importを利用して既存のAuth0リソースをTerraformに移行できるか
- 複数環境で設定を統一化出来るか
前提
- terraformのバージョンはv0.14.6を利用します。
- プロパイダはalexkappa/auth0を利用します。
- バージョンはv0.17.1です。
- 事前にAuth0のテナントのダッシュボードから、Management APIが利用可能なM2Mのアプリケーションを作成しておき、ClientIDとClientSecretを取得しておく必要があります。
準備手順
作業ディレクトリにmain.tfを作成して以下の様に記載します。
terraform { |
その後、terraform init
をします。
以上で準備完了です。
terraform importを利用して既存のAuth0リソースをTerraformに移行できるか
TL;DR
1つだけtfstateを弄る必要があるが、可能です。
既存のAuth0リソースをTerraformに移行する際の流れ
まずは移行手順の全体像について記載します。
- 空のリソース定義を作成する。
- terraform import で既存のリソースをstateに取り込む
terraform state show
でstateに取り込んだ既存リソースのパラメータを確認し、先程作成した空のリソース定義に追加していく。terraform plan
して差分が無くなればそのリソースの移行完了
この手順をAuth0で管理出来る全リソースについて実行します。
Terraformで管理出来るリソースの一覧(リソースタイプ)は↓で定義されています。
Docs overview | alexkappa/auth0 | Terraform Registry
かなりの作業量になるため何らかのツールがあるだろうと探してみたのですが、見つけられませんでした。 2
加えてこの手順でAuth0のリソースをインポートするに当たって、ある事象でハマってしまいました。
ハマったポイント: IDが無いリソースタイプがいくつかある。
Terraformで定義されているimportコマンドの書式はこのようになっています。
terraform import [options] ADDRESS ID |
ADDRESSとは▼
ADDRESS
はリソースアドレスの事であり、<given type>.<local name>
の形式で表します。
例えば、
resource "auth0_custom_domain" "main_domain" { |
の様なリソースブロックにおいて、
ADDRESS
はauth0_custom_domain.main_domain
です。
ID
はそのリソースをインポートするための識別子です。例えば、Auth0 Custom Dmainのドメイン設定はcd_<random string>
の形で割り振られています。
このID
ですが、リソースタイプによっては存在しません。例えば、テナント設定である、auth0_tenantにはIDが存在しません。この場合、どうすれば設定のインポートが出来るのか、悩んでいました。
結論としては、IDを適当に自分で決めればインポート出来ました。
なぜ適当なIDで通るのか
ID
は識別子です。Auth0 のテナント設定に着目すると、IDが無くとも設定が判別できます。
IDが振られているリソースタイプである、auth0_role
のプロパイダのソースコード 3とTerraform公式のimportの説明 7を読むと、CLIから受け取ったIDがd.ID()
に入っている事が分かります。
同様にIDが不明なリソースタイプである、auth_tenant
のプロパイダのソースコード 4を読むと、auth0_role
では使われていた、d.ID()
が使われていない事が分かります。そのため、こちらで適当なIDを入れても問題無いことが分かります。
リソースタイプとIDの対応表
執筆当時プロパイダのドキュメントに、どのパラメータを使えばimportが出来るかの情報がほとんど載っていません。issueにはちらちら書かれていますが、テナント設定のimport方法について書いている人は見つけられませんでした。
そのためリソースタイプとID対応関係について表にまとめてみたので参考にお使い下さい。執筆当時で、この中の全リソースタイプについてimportが出来ている事を確認しています。 5
また、ID
の確認が必要なリソースタイプについては、IDが確認しやすい様にManagement APIのAPI Explorerの該当APIのURLを載せています。
IDの欄に"id"
と書かれていた場合はAPIを叩いた時のJSONレスポンスのキーが”id”の値を指します。
自由と書かれていた場合は先述の理由により、自由に設定出来ます。
複数環境で設定を統一化出来るか
複数テナントが推奨されているAuth0において、テナントの設定を統一化したいケースがあると思います。
その際はterraform workspace
と呼ばれる機能を用いて1つのリソースブロックを複数の環境で共有することが可能になります。
dev環境とtest環境があったとして、この2つの環境で同一の設定にさせたい場合について考えます。
先程のmain.tfと同階層にvariables.tfを置きます。
locals { |
main.tfのプロパイダ設定を以下の様に変えます。
provider "auth0" { |
Terraformのworkspaceを追加しましょう。main.tfで以下のコマンドを実行します。
terraform workspace new dev |
以下の様に表示されます(現在いるworkspaceに*が付きます。)
$ terraform workspace list |
今自分が入っているworkspaceはterraform workspace list
で確認します。
移動したい場合はterraform workspace [移動先のworkspace名]
です。
dev環境を正としたい場合は先程のリソースのimport手順をworkspaceがdevの状態で進めます。その後、workspaceをtestに変更してからリソースブロックを変更せずにterraform import
を全リソースに対して行います。
最後に、terraform plan
でdev環境とtest環境の設定の差分が表示されます。
一部だけ設定を変えたい
test環境の時だけ空のルールであるempty-rule.js
、その他の環境の時はsome-rule.js
を動かしたいケースについて考えてみます。
HCLの組み込み関数file
と三項演算子により実現出来ます。
resource "auth0_rule" "some_rule" { |
Terraformの組み込み関数replace
を使えば、同一のファイルを参照しつつ振る舞いを返る事が可能になります。
テナント環境毎に挙動が変わるRuleをTerraformで管理してみます。
初めに以下の様なスクリプトを保存し、
function setEnv(user, context, callback) { |
以下の様にリソース定義を行います。
resource "auth0_rule" "set_env" { |
このように書く事でdev環境では
function setEnv(user, context, callback) { |
として、test環境では
function setEnv(user, context, callback) { |
として環境毎に振る舞いを変える事が出来ました。
まとめ
今回はTerraform + Auth0の環境構築について、既存のAuth0環境の移行を観点として調査を行いました。
調査結果をまとめると、
- importの手順に一癖あるが、一応全リソースを移行出来る。
- workspaceを用いて複数のテナントで環境を同一にしつつ、一部だけ環境毎に振る舞いを変えることが出来る。
ことが分かりました。
既存のAuth0環境をTerraformに移行したい場合の考慮材料にして頂ければ幸いです。
ここまで読んで頂きありがとうございました。
終わりに
私事で恐縮ですが、2019年の2月からアルバイトとして働いてきたFutureを今日で退職します。
この2年を通してFutureで沢山の技術を学び、自身のスキルを大幅に向上させることが出来ました。
2年間本当にお世話になりました。ありがとうございました!
- 1.TIG: Technology Innovation Groupの略で、フューチャーの中でも特にIT技術に特化した部隊です。DXユニット: TIGの中にありデジタルトランスフォーメーションに関わる仕事を推進していくチームです。 ↩
- 2.執筆中にterraformerと呼ばれる既存のインフラリソースをリソース定義(.tf)や状態(.tfstate)に落とし込むCLIツールは見つけたのですが、執筆当時はまだ対応リストに記載されていません。 ↩
- 3.https://github.com/alexkappa/terraform-provider-auth0/blob/master/auth0/resource_auth0_role.go#L86 ↩
- 4.https://github.com/alexkappa/terraform-provider-auth0/blob/master/auth0/resource_auth0_tenant.go#L256 ↩
- 5.あくまで全リソースタイプについて確認しているため、リソースタイプのauth0_email_templateのIDは
verify_email
とreset_email
のみ確認済みです。 ↩ - 6.このリソースタイプはどうリソースブロックを編集しても
terraform plan
で差分を無くす事が出来ません。verification_method
がManagement APIの仕様上importされないため、tfstate側がnullと設定されてしまうからです。スキーマ定義を見ると、Required
とForceNew
が付いているためこのままではリソースの再生成が走ってしまいます。そのため、.tfstate
,.tf
の両方についてverification_method = "txt"
に強制的に変更することでterraform plan
で差分を表示させない様に設定出来ます。この問題はプロパイダのリポジトリのissueでも言及されていました。 Importing auth0_custom_domain resource forces recreation · Issue #294 · alexkappa/terraform-provider-auth0 ↩ - 7.Resources - Import - Terraform by HashiCorp ↩
- 8.Support Test Mode · Issue #70 · auth0/auth0-deploy-cliissue自体は記載されています。 ↩
- 9.一応Auth0 Deploy CLIでは、意図していないリソースの破壊を防ぐために
AUTH0_ALLOW_DELETE
フラグが設定可能です。https://github.com/auth0/auth0-deploy-cli/blob/master/examples/yaml/README.md#config ↩