-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1095 from amine-mejaouel/create-b2c-tenant
Create b2c tenant
- Loading branch information
Showing
9 changed files
with
288 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
title: "B2C Tenant" | ||
date: 2024-02-01T00:00:00+01:00 | ||
chapter: false | ||
weight: 1 | ||
--- | ||
|
||
#### Overview | ||
Creates a new B2C tenant, please note that the current implementation only supports the creation of a new B2C tenant. | ||
|
||
Usage of this computation expression when a B2C tenant already exists will result in an error, check the [example](#example) for more infos. | ||
|
||
#### B2C Tenant Builder Keywords | ||
| Applies To | Keyword | Purpose | | ||
|-|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| B2C Tenant | initial_domain_name | Initial domain name for the B2C tenant as in `initial_domain_name.onmicrosoft.com` | | ||
| B2C Tenant | display_name | Display name for the B2C tenant. | | ||
| B2C Tenant | sku | [SKU](https://learn.microsoft.com/en-us/rest/api/activedirectory/b2c-tenants/list-by-subscription?view=rest-activedirectory-2021-04-01&tabs=HTTP#b2cresourceskuname) for the B2C tenant. | | ||
| B2C Tenant | country_code | Country code defined by two capital letter, for examples check the official [docs](https://learn.microsoft.com/en-us/azure/active-directory-b2c/data-residency] | | ||
| B2C Tenant | data_residency | Data residency for the B2C tenant, for more infos check the official [docs](https://learn.microsoft.com/en-us/azure/active-directory-b2c/data-residency] | | ||
| B2C Tenant | tags | Tags for the B2C tenant. | | ||
|
||
#### Example | ||
|
||
Basic creation of a B2C tenant, while avoiding having an error when such tenant already exists. | ||
|
||
```fsharp | ||
open Farmer | ||
open Farmer.B2cTenant | ||
open Farmer.Builders | ||
open Farmer.Deploy | ||
let initialDomainName = "myb2c" | ||
let myb2c = | ||
b2cTenant { | ||
initial_domain_name initialDomainName | ||
display_name "My B2C" | ||
sku Sku.PremiumP1 | ||
country_code "FR" | ||
data_residency B2cDataResidency.Europe | ||
} | ||
let b2cDoesNotExist (initialDomainName: string) = | ||
let output = | ||
Az.AzHelpers.executeAz $"resource list --name '{initialDomainName}.onmicrosoft.com'" | ||
|> snd | ||
not (output.Contains initialDomainName) | ||
let deployment = | ||
arm { | ||
location Location.FranceCentral | ||
add_resources | ||
[ | ||
// This allows to avoid having an error when the B2C tenant already exists | ||
if b2cDoesNotExist initialDomainName then | ||
myb2c | ||
] | ||
} | ||
```` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
[<AutoOpen>] | ||
module Farmer.Arm.B2cTenant | ||
|
||
open Farmer | ||
|
||
let b2cTenant = | ||
ResourceType("Microsoft.AzureActiveDirectory/b2cDirectories", "2021-04-01") | ||
|
||
type B2cDomainName = | ||
| B2cDomainName of string | ||
|
||
static member internal Empty = B2cDomainName "" | ||
|
||
member this.AsResourceName = | ||
match this with | ||
| B2cDomainName name -> ResourceName name | ||
|
||
type B2cTenant = | ||
{ | ||
Name: B2cDomainName | ||
DisplayName: string | ||
DataResidency: Location | ||
CountryCode: string | ||
Tags: Map<string, string> | ||
Sku: B2cTenant.Sku | ||
} | ||
|
||
interface IArmResource with | ||
member this.ResourceId = accounts.resourceId this.Name.AsResourceName | ||
|
||
member this.JsonModel = | ||
{| b2cTenant.Create(this.Name.AsResourceName, this.DataResidency, tags = this.Tags) with | ||
sku = | ||
{| | ||
name = string this.Sku | ||
tier = "A0" | ||
|} | ||
properties = | ||
{| | ||
createTenantProperties = | ||
{| | ||
countryCode = this.CountryCode | ||
displayName = this.DisplayName | ||
|} | ||
|} | ||
|} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
[<AutoOpen>] | ||
module Farmer.Builders.B2cTenant | ||
|
||
open Farmer | ||
open Farmer.Arm | ||
open Farmer.Validation | ||
open Farmer.B2cTenant | ||
|
||
type B2cDomainName with | ||
|
||
static member FromInitialDomainName initialDomainName = | ||
[ containsOnlyM [ lettersOrNumbers ] ] | ||
|> validate "B2c initial domain name" initialDomainName | ||
|> Result.map (fun x -> B2cDomainName $"{x}.onmicrosoft.com") | ||
|
||
type B2cTenantConfig = | ||
{ | ||
Name: B2cDomainName | ||
DisplayName: string | ||
DataResidency: Location | ||
CountryCode: string | ||
Sku: Sku | ||
Tags: Map<string, string> | ||
} | ||
|
||
interface IBuilder with | ||
member this.ResourceId = b2cTenant.resourceId this.Name.AsResourceName | ||
|
||
member this.BuildResources _ = | ||
[ | ||
{ | ||
B2cTenant.Name = this.Name | ||
DisplayName = this.DisplayName | ||
DataResidency = this.DataResidency | ||
CountryCode = this.CountryCode | ||
Tags = this.Tags | ||
Sku = this.Sku | ||
} | ||
] | ||
|
||
type B2cTenantBuilder() = | ||
member _.Yield _ = | ||
{ | ||
Name = B2cDomainName.Empty | ||
DisplayName = "" | ||
DataResidency = B2cDataResidency.Europe.Location | ||
CountryCode = "FR" | ||
Sku = Sku.PremiumP1 | ||
Tags = Map.empty | ||
} | ||
|
||
[<CustomOperation("initial_domain_name")>] | ||
member _.InitialDomainName(state: B2cTenantConfig, name: string) = | ||
{ state with | ||
Name = B2cDomainName.FromInitialDomainName(name).OkValue | ||
} | ||
|
||
[<CustomOperation("display_name")>] | ||
member _.DisplayName(state: B2cTenantConfig, displayName: string) = | ||
{ state with DisplayName = displayName } | ||
|
||
[<CustomOperation("sku")>] | ||
member _.Sku(state: B2cTenantConfig, sku: Sku) = { state with Sku = sku } | ||
|
||
/// Data residency location as described in: https://learn.microsoft.com/en-us/azure/active-directory-b2c/data-residency#data-residency | ||
[<CustomOperation("data_residency")>] | ||
member _.DataResidency(state: B2cTenantConfig, b2cDataResidency: B2cDataResidency) = | ||
{ state with | ||
DataResidency = b2cDataResidency.Location | ||
} | ||
|
||
/// Country Code defined by two capital letters (example: FR), as described in: https://learn.microsoft.com/en-us/azure/active-directory-b2c/data-residency#data-residency | ||
[<CustomOperation("country_code")>] | ||
member _.CountryCode(state: B2cTenantConfig, countryCode: string) = | ||
{ state with CountryCode = countryCode } | ||
|
||
interface ITaggable<B2cTenantConfig> with | ||
member _.Add state tags = | ||
{ state with | ||
Tags = state.Tags |> Map.merge tags | ||
} | ||
|
||
let b2cTenant = B2cTenantBuilder() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
module B2cTenant | ||
|
||
open Expecto | ||
open Farmer | ||
open Farmer.B2cTenant | ||
open Farmer.Builders | ||
open Newtonsoft.Json.Linq | ||
|
||
let tests = | ||
testList | ||
"B2c tenant tests" | ||
[ | ||
test "B2c tenant should generate the expected arm template" { | ||
let deployment = | ||
arm { | ||
location Location.FranceCentral | ||
|
||
add_resources | ||
[ | ||
b2cTenant { | ||
initial_domain_name "myb2c" | ||
display_name "My B2C tenant" | ||
sku Sku.PremiumP1 | ||
country_code "FR" | ||
data_residency B2cDataResidency.Europe | ||
} | ||
] | ||
} | ||
|
||
let jobj = deployment.Template |> Writer.toJson |> JObject.Parse | ||
|
||
let generatedTemplate = jobj.SelectToken("resources[0]") | ||
|
||
Expect.equal | ||
(generatedTemplate.SelectToken("apiVersion").ToString()) | ||
"2021-04-01" | ||
"Invalid ARM template api version" | ||
|
||
Expect.equal | ||
(generatedTemplate.SelectToken("type").ToString()) | ||
"Microsoft.AzureActiveDirectory/b2cDirectories" | ||
"Invalid ARM template type" | ||
|
||
Expect.equal | ||
(generatedTemplate.SelectToken("name").ToString()) | ||
"myb2c.onmicrosoft.com" | ||
"`name` should match <initial_domain_name>.onmicrosoft.com" | ||
|
||
Expect.equal | ||
(generatedTemplate | ||
.SelectToken("properties.createTenantProperties.displayName") | ||
.ToString()) | ||
"My B2C tenant" | ||
"Invalid display name" | ||
|
||
Expect.equal | ||
(generatedTemplate.SelectToken("location").ToString()) | ||
"europe" | ||
"`location` should match with the provided `data_residency`" | ||
|
||
Expect.equal | ||
(generatedTemplate | ||
.SelectToken("properties.createTenantProperties.countryCode") | ||
.ToString()) | ||
"FR" | ||
"Invalid country code" | ||
|
||
Expect.equal (generatedTemplate.SelectToken("sku.name").ToString()) "PremiumP1" "Invalid sku" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters