「Infrastructure as Code ( IaC )」で有名な「Terraform」。「インフラ」の構成管理ツールだとばかり思っていましたが、なんと SaaS にも対応しているみたいなんです! 定義ファイルをテンプレート化すると、同じ構成で SaaS を展開できるので、 CIer の方にとってはかなり便利だと思います。
今回は、認証・認可の SaaS である 「Auth0」でterraform apply
を試してみたので、作業ログを記事にしました。
Terraform と Auth0
どちらもまだ初心者クラスですが、これまでに2つの記事を書きました。機能紹介やセットアップ方法、コマンドの動作などの情報が知りたい方は、こちらををご参照ください。
↓ Terraform のインストール方法やコマンドの使い方を紹介しています。 blog.pirox.dev
↓ Auth0 の機能概要やアカウント作成方法を紹介しています。 blog.pirox.dev
Terraform の「Resource」と「Provider」
Terraform の定義ファイル(.tf
)に記述する代表的なブロックが「Resource」と「Provider」です。
たとえば、 AWS の VPC を管理(作成)するには以下のように記述します。
# Configure the AWS Provider provider "aws" { version = "~> 2.0" region = "us-east-1" } # Create a VPC resource "aws_vpc" "example" { cidr_block = "10.0.0.0/16" }
Provider: AWS - Terraform by HashiCorp
Terraform が公式サポートしている Provider は、執筆時点(2019/05/31)で103個もあります。冒頭で紹介した通り、 GitHub や Datadog といった SaaS も多く含まれています。
Custom Provider を使う(作る)ことで、サポート対象外のサービスも Terraform で扱えるようになります。 (対象サービスが API を公開している必要あり。) www.terraform.io
(現時点では) Auth0 もサポート対象外なので、 Custom Provider を作ります。 運良く Auth0 Communnity で開発中の GitHub リポジトリが見つかったので、利用させていただきました。感謝!
※ Terraform の Community Providers には別の GitHub リポジトリが掲載されていますが、2017年から更新がなかったため利用を見送りました。
Custom Provider の作成
Example を参考にして、 Auth0 の Application ( client )の定義ファイルを作成します。
Domain
・Client ID
・Client Secret
の値は、別途 Auth0 のダッシュボードで確認します。(確認方法は後述。)
# sample-auth0.tf # provider に Auth0 を指定 provider "auth0" { domain = "<Domain>" client_id = "<Client ID>" client_secret = "<Client Secret>" } # 「 Example Application ( Managed by Terraform )」という名称の Application を作成 resource "auth0_client" "my_app_client" { name = "Example Application (Managed by Terraform)" description = "Example Application Loooooong Description" app_type = "regular_web" }
公式サポートされているProvider
の場合、terraform init
するとplugin
(≒ SDK )が自動でダウンロードされます。 今回は以下のエラーが表示され、「手動で配置せよ」とのことです。
$ terraform init Initializing provider plugins... - Checking for available provider plugins on https://releases.hashicorp.com... Provider "auth0" not available for installation. A provider named "auth0" could not be found in the official repository. This may result from mistyping the provider name, or the given provider may be a third-party provider that cannot be installed automatically. In the latter case, the plugin must be installed manually by locating and downloading a suitable distribution package and placing the plugin's executable file in the following directory: terraform.d/plugins/darwin_amd64 Terraform detects necessary plugins by inspecting the configuration and state. To view the provider versions requested by each module, run "terraform providers".
GitHub リポジトリを clone して、 Auth0 の Custom Provider を作成します。ソースは Golang で書かれており、 $GOPATH/bin にバイナリファイルの「terraform-provider-auth0」が作成されます。コレが Custom Provider です。
$ git clone https://github.com/alexkappa/terraform-provider-auth0.git Cloning into 'terraform-provider-auth0'... remote: Enumerating objects: 3878, done. remote: Total 3878 (delta 0), reused 0 (delta 0), pack-reused 3878 Receiving objects: 100% (3878/3878), 7.83 MiB | 2.73 MiB/s, done. Resolving deltas: 100% (1581/1581), done. $ cd terraform-provider-auth0/ $ make build ==> Checking that code complies with gofmt requirements... go install $ ls -l $GOPATH/bin ・・・ -rwxr-xr-x 1 pirox staff 26981684 5 30 14:17 terraform-provider-auth0
「terraform-provider-auth0」を以下のいずれかに配置することで、terraform init
が成功します。
配置先に関する仕様はこちらです。Home - Extending Terraform - Terraform by HashiCorp
$ mkdir -p terraform.d/plugins/darwin_amd64 $ cp $GOPATH/bin/terraform-provider-auth0 ./terraform.d/plugins/darwin_amd64/terraform-provider-auth0 $ terraform init Initializing provider plugins... Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.
これで Terraform 側の準備は完了です。
Auth0 のクレデンシャル情報を取得
ここからは Auth0 のダッシュボードを操作します。クレデンシャル情報(Client ID
・Client Secret
)を取得するための Application ( Client ) を作成します。ここで2つのハマりポイントがあったので、気をつけください。
# sample-auth0.tf # provider に Auth0 を指定 provider "auth0" { domain = "<Domain>" client_id = "<Client ID>" client_secret = "<Client Secret>" } ...
「CREATE APPLICATION」をクリックして作成を開始します。
任意の名称を入力後、 Application Type として「Machine to Machine Applications」を選択します。(ハマりポイント①)
「Auth0 Management API」に対して、必要となる権限 ( Scope )を付与します。(ハマりポイント②)
※今回は「 ALL 」を付与しましたが、実運用では必要最低限とすべきでしょう。
これで Application が作成されるので、 Settings 画面で各値を確認し、.tf
ファイルに記述します。(今回はハードコードで試しました。)
ハマりポイント①:Application Type
Auth0 の Application Type が4種類あり、それぞれ用途が異なります。(詳細:
Auth0 Application Types)
Terraform のようなコマンドラインツールで利用する場合は、 Machine to Machine Applications を選択します。他のタイプを選択するとterraform apply
に失敗します。
$ terraform apply ... Error: Error applying plan: 1 error(s) occurred: * auth0_client.my_app_client: 1 error(s) occurred: * auth0_client.my_app_client: Post https://b-pirox.auth0.com/api/v2/clients: oauth2: cannot fetch token: 403 Forbidden Response: {"error":"access_denied","error_description":"Client is not authorized to access \"https://b-pirox.auth0.com/api/v2/\". You might probably want to create a \"client-grant\" associated to this API. See: https://auth0.com/docs/api/v2#!/Client_Grants/post_client_grants"} Terraform does not automatically rollback in the face of errors. Instead, your Terraform state file has been partially updated with any resources that successfully completed. Please address the error above and apply again to incrementally change your infrastructure.
公式ドキュメントに以下の記述があり、エラーの原因に気づくことができました。
With machine-to-machine (M2M) applications, such as CLIs, daemons, or services running on your back-end, the system authenticates and authorizes the app rather than a user.
ハマりポイント②: API のアクセス権限
ハマりポイント①を解決したと思ったら、またもや同様のエラーで悩むことに。。エラーメッセージが同一なので四苦八苦しましたが、クレデンシャルを取得した Application で、 API へのアクセス権限を設定しなかったことが原因でした。
Auth0 の API
Auth0 では2種類の API が用意されています。 Terraform は「Management API」を利用して、 Auth0 の構成を管理します。 auth0.com
参考: Auth0 APIs
Management API を利用できるのはが「M2M Applications」のみのようです。(ハマりポイント①の背景がコレです。)他のタイプは SPA などのフロントエンドでの使用を想定したもので、 Authentication API に紐付いています。
terraform apply
以上を設定してterraform apply
を実行すると、 Auth0 の Application が作成できました。
$ terraform apply An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: + auth0_client.my_app_client id: <computed> app_type: "regular_web" client_id: <computed> client_secret: <computed> custom_login_page_on: <computed> description: "Example Application Loooooong Description" grant_types.#: <computed> is_first_party: <computed> is_token_endpoint_ip_header_trusted: <computed> name: "Example Application (Managed by Terraform)" token_endpoint_auth_method: <computed> Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes auth0_client.my_app_client: Creating... app_type: "" => "regular_web" client_id: "" => "<computed>" client_secret: "<sensitive>" => "<sensitive>" custom_login_page_on: "" => "<computed>" description: "" => "Example Application Loooooong Description" grant_types.#: "" => "<computed>" is_first_party: "" => "<computed>" is_token_endpoint_ip_header_trusted: "" => "<computed>" name: "" => "Example Application (Managed by Terraform)" token_endpoint_auth_method: "" => "<computed>" auth0_client.my_app_client: Creation complete after 2s (ID: OoWS2E7kJGWNT2QUmcIAaZWXHvSGOB6p) Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
terraform destroy
による削除にも成功しました。
$ terraform destroy auth0_client.my_app_client: Refreshing state... (ID: OoWS2E7kJGWNT2QUmcIAaZWXHvSGOB6p) An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: - auth0_client.my_app_client Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes auth0_client.my_app_client: Destroying... (ID: OoWS2E7kJGWNT2QUmcIAaZWXHvSGOB6p) auth0_client.my_app_client: Destruction complete after 1s Destroy complete! Resources: 1 destroyed.
まとめ
- Custom Provider を使うことで、 Terraform で Auth0 の構成管理ができる
- Auth0 の
Provider
はコミュニティで開発中
- Auth0 の
- Auth0 の Management API の理解が深まった
- CLI でアクセスするためには、 Machine to Machine Application のクレデンシャルを使用する
- アクセス権の設定も必要( ApplicationのAuthorize 、 Scope )
今回「 Terraform で Application を作成するため」の Application (クレデンシャル取得用)を手動で作成しましたが、他にもっといい方法がある気がしています。また、社内ツールの認証に Auth0 を使って、認証基盤( Azure AD )と SSO したいと考えているので、引き続き検証を進めていきます。 Auth0 のprovider
開発にも Contribute してみたいです。頑張ろう!!
参考リンク
Custom Provider の実装方法が丁寧に説明されている記事を見つけました。参考になりそう。 febc-yamamoto.hatenablog.jp