How Can I Configure Azure B2C Automatically?

Viewed 2681

I have been following several Microsoft tutorials to configure Azure B2C with my web app and rest api. e.g. https://docs.microsoft.com/en-ca/azure/active-directory-b2c/tutorial-single-page-app-webapi?tabs=app-reg-ga

There was a lot of back and forth and now it is working.

All of the config was done in the portal and now it feels very fragile as it took me several attempts to get it all right.

The rest of my Azure deployment is configured with Terraform, Ansible and Azure CLI.

I couldn't see any support for B2C for any of these.

Is there an alternative? Can you export the config to a file as a backup?

What if something breaks? How do I roll back to a previously working version?

2 Answers

You can automate the process by using below Powershell script to create a service principal and provider.tf:

#!/bin/bash

error()
{
  if [[ -n "$@" ]]
  then
    tput setaf 1
    echo "ERROR: $@" >&2
    tput sgr0
  fi

  exit 1
}

yellow() { tput setaf 3; cat - ; tput sgr0; return; }
cyan()   { tput setaf 6; cat - ; tput sgr0; return; }


# Grab the Azure subscription ID
subId=$(az account show --output tsv --query id)
[[ -z "$subId" ]] && error "Not logged into Azure as expected."

# Check for existing provider.tf
if [[ -f provider.tf ]]
then
  echo -n "The provider.tf file exists.  Do you want to overwrite? [Y/n]: "
  read ans
  [[ "${ans:-Y}" != [Yy] ]] && exit 0
fi

sname="terraform-${subId}-sp"
name="http://${sname}"

# Create the service principal
echo "az ad sp create-for-rbac --name \"$name\"" | yellow
spout=$(az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/$subId" --name "$sname" --output json)

# If the service principal has been created then offer to reset credentials
if [[ "$?" -ne 0 ]]
then
  echo -n "Service Principal already exists. Do you want to reset credentials? [Y/n]: "
  read ans
  if [[ "${ans:-Y}" = [Yy] ]]
  then spout=$(az ad sp credential reset --name "$name" --output json)
  else exit 1
  fi
fi

[[ -z "$spout" ]] && error "Failed to create / reset the service principal $name"

# Echo the json output
echo "$spout" | yellow

# Derive the required variables
clientId=$(jq -r .appId <<< $spout)
clientSecret=$(jq -r .password <<< $spout)
tenantId=$(jq -r .tenant <<< $spout)

echo -e "\nWill now create a provider.tf file.  Choose output type."
PS3='Choose provider block type: '
options=("Populated azurerm block" "Empty azurerm block with environment variables" "Quit")
select opt in "${options[@]}"
do
  case $opt in
    "Populated azurerm block")
      cat > provider.tf <<-END-OF-STANZA
    provider "azurerm" {
      subscription_id = "$subId"
      client_id       = "$clientId"
      client_secret   = "$clientSecret"
      tenant_id       = "$tenantId"
    }
    END-OF-STANZA

      echo -e "\nPopulated provider.tf:"
      cat provider.tf | yellow
      echo
      break
      ;;
    "Empty azurerm block with environment variables")
      echo "provider \"azurerm\" {}" > provider.tf
      echo -e "\nEmpty provider.tf:"
      cat provider.tf | yellow
      echo >&2

      export ARM_SUBSCRIPTION_ID="$subId"
      export ARM_CLIENT_ID="$clientId"
      export ARM_CLIENT_SECRET="$clientSecret"
      export ARM_TENANT_ID="$tenantId"

      echo "Copy the following environment variable exports and paste into your .bashrc file:"
      cat <<-END-OF-ENVVARS | cyan
    export ARM_SUBSCRIPTION_ID="$subId"
    export ARM_CLIENT_ID="$clientId"
    export ARM_CLIENT_SECRET="$clientSecret"
    export ARM_TENANT_ID="$tenantId"
    END-OF-ENVVARS
      break
      ;;
    "Quit")
      exit 0
      ;;
    *) echo "invalid option $REPLY";;
  esac
done

echo "To log in as the Service Principal then run the following command:"
echo "az login --service-principal --username \"$clientId\" --password \"$clientSecret\" --tenant \"$tenantId\"" | cyan

exit 0

The script will interactively:

  1. Create the service principal (or resets the credentials if it already exists)
  2. Prompts to choose either a populated or empty provider.tf azurerm provider block exports the environment variables if you selected an empty block (and display the commands)
  3. Display the az login command to log in as the service principal

The following command will download and run it:

uri=https://raw.githubusercontent.com/azurecitadel/azurecitadel.github.io/master/automation/terraform/createTerraformServicePrincipal.sh
curl -sL $uri > createTerraformServicePrincipal.sh && chmod 750 createTerraformServicePrincipal.sh
./createTerraformServicePrincipal.sh

Refer to this great article by Richard Cheney on this - https://azurecitadel.com/automation/terraform/lab5/

Related