Auth0’s extensive configuration options, from custom database scripts to complex role-based access control policies, are notoriously difficult to manage manually, especially as your application scales and evolves.

Imagine you’re running a SaaS product and need to onboard a new customer. This involves creating a new tenant in Auth0, configuring its specific branding, setting up SAML or OIDC connections to their identity provider, defining user roles, and potentially deploying custom login pages. Doing this manually for every new customer is a recipe for disaster – inconsistent configurations, missed steps, and a significant drain on engineering time.

This is where managing Auth0 configuration as code, specifically with Terraform, becomes a game-changer. It allows you to treat your Auth0 tenant’s settings as infrastructure, version-controlled, tested, and deployed repeatably.

Let’s see how this looks in practice. Here’s a simplified Terraform configuration for an Auth0 application.

provider "auth0" {
  domain = "your-tenant.auth0.com"
  api_token = var.auth0_api_token
}

resource "auth0_client" "my_app" {
  name = "My Awesome App"
  app_type = "regular"
  grant_types = [
    "authorization_code",
    "refresh_token"
  ]
  callbacks = [
    "https://my-app.example.com/callback"
  ]
  allowed_logout_urls = [
    "https://my-app.example.com"
  ]
}

resource "auth0_connection" "google_oauth2" {
  name     = "google-oauth2"
  strategy = "google-oauth2"
  enabled_clients = [auth0_client.my_app.client_id]
}

resource "auth0_role" "admin_role" {
  name = "App Admin"
}

resource "auth0_role_user" "admin_user" {
  role_id = auth0_role.admin_role.id
  user_id = "auth0|some-user-id" # In a real scenario, this would likely be dynamic
}

This configuration defines:

  • The Auth0 Provider: This tells Terraform how to connect to your Auth0 tenant using its domain and an API token.
  • An Auth0 Client (auth0_client): This represents your application within Auth0, defining its name, type, allowed grant types (how it can request tokens), and callback URLs for redirects.
  • A Social Connection (auth0_connection): Here, we’re setting up a Google OAuth2 connection. enabled_clients specifies which of your Auth0 applications can use this connection.
  • A Role (auth0_role): This defines a custom role named "App Admin."
  • A Role Assignment (auth0_role_user): This assigns the "App Admin" role to a specific Auth0 user ID.

When you run terraform apply, Terraform communicates with the Auth0 Management API to create or update these resources. If you change the name of the auth0_client, running terraform apply again will update that name in Auth0. If you add a new callback URL, it gets added. If you delete the auth0_role resource, the role is removed from your Auth0 tenant.

The core problem this solves is the lack of a single source of truth for your Auth0 configuration. Manual changes lead to drift between what you think is configured and what is configured. With Terraform, your .tf files are that single source of truth.

Internally, the Auth0 Terraform provider acts as a client to the Auth0 Management API. It uses resource definitions in your Terraform code to make API calls for creating, reading, updating, and deleting Auth0 resources. Terraform’s state file keeps track of the resources it manages, allowing it to detect changes and plan the necessary API operations to bring your Auth0 tenant in sync with your code.

The levers you control are the Auth0 resource types available in the provider (e.g., auth0_client, auth0_connection, auth0_rule, auth0_user, auth0_tenant_settings, etc.) and their specific arguments, which directly map to Auth0’s API parameters. You can define users, roles, permissions, social connections, enterprise connections, custom database scripts, email templates, and much more, all within your Terraform code.

When defining auth0_connection resources, it’s crucial to understand that the enabled_clients argument expects an array of client IDs. If you intend for a connection to be available to multiple applications managed by Terraform, you’ll need to reference each auth0_client resource within that array. For instance, if you had auth0_client.web_app and auth0_client.mobile_app, the enabled_clients for a shared connection would look like enabled_clients = [auth0_client.web_app.client_id, auth0_client.mobile_app.client_id]. Forgetting to include a client ID here will result in that application losing access to the connection upon terraform apply.

The next hurdle is managing secrets like API tokens and sensitive connection credentials securely.

Want structured learning?

Take the full Auth0 course →