Terraform Action Trigger Binding Based on Variable

Last Modified: Oct 31, 2024

Overview

This article will explain how to use Terraform to deploy multiple actions and bind them to the same trigger dynamically.

Applies To

  • Terraform
  • Actions

Cause

As Auth0 uses one Terraform “resource” for a given flow (trigger such as “post-login”) - Actions must be added using a “dynamic block”, and all actions must be put into the block in one go.

Solution

Here is an example of using Terraform to set up clients based on a set of input variables and to create an action for each client and map them all to the client credentials trigger:

terraform {
  required_providers {
    auth0 = {
      source  = "auth0/auth0"
      version = "~> 0.45.0"
    }
  }
}
//Set up a variable that will be used to create 2 clients by default
variable "deployment" {
  type = set(string)
  default=["deployment1","deployment2"]
}

//Create a client for each input deployment variable
resource "auth0_client" "m2m-client" {  
  for_each = var.deployment
  name = "My M2M Client ${each.key}"
  description                = "Client for server to server communication"
  app_type                   = "non_interactive"
  oidc_conformant            = true
  is_first_party             = true
  custom_login_page_on       = false
  token_endpoint_auth_method = "client_secret_post"
  jwt_configuration {
    alg                 = "RS256"
    lifetime_in_seconds = 36000
  }
  grant_types = [
    "client_credentials"
  ]
  addons {}
}

//Action that is created dynamically for each input variable to provide a different custom claim value for certain client IDs
resource "auth0_action" "add_tenant_claim" {
  for_each = auth0_client.m2m-client
  name = "Add-Tenant-Claim for ${each.key}"
  runtime = "node16"
  deploy  = true
  code    = <<-EOT
  /**
   * Handler that will be called during the execution of a credentials exchange flow.
   */
   exports.onExecuteCredentialsExchange = async (event, api) => {
     if(event.client.client_id == "${each.value.id}")
     {
      api.accessToken.setCustomClaim("https://custom.namespace/claims"", "${each.key}")
     }
   };
  EOT

  supported_triggers {
    id      = "credentials-exchange"
    version = "v2"
  }
}

//For every input variable-based Action, map it to the credentials-exchange trigger
resource "auth0_trigger_binding" "m2m_flow" {
  
  trigger = "credentials-exchange"

  dynamic "actions" {
    for_each = auth0_action.add_tenant_claim
    content {
      id = actions.value.id
      display_name = actions.value.name
    }
  }
}
1 Like