Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
- name: Test application and region selection without Azure access
shell: pwsh
run: ./setup/tests/Selections.Tests.ps1
- name: Test deployment progress without Azure access
shell: pwsh
run: ./setup/tests/Progress.Tests.ps1
- name: Compile Bicep without deploying
shell: pwsh
run: |
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# External Phone Provider Azure Function Sample

Connect Microsoft Entra ID to a phone provider for SMS and voice one-time passwords.
Guided setup deploys **one regional endpoint** using JavaScript, C#, or Python.
Guided setup deploys **one regional endpoint** using JavaScript by default, with C# and Python options.

> [!IMPORTANT]
> Start in a separate nonproduction environment. Confirm provider access and Microsoft's approved
Expand Down Expand Up @@ -50,7 +50,7 @@ Follow the **[five-step setup guide](docs/GETTING-STARTED.md)** in order:

1. <a id="1-get-ready"></a>[Get ready](docs/GETTING-STARTED.md#1-get-ready): confirm access, approvals, permissions, and budget.
2. <a id="2-register-your-application"></a>[Register the app](docs/GETTING-STARTED.md#2-register-your-application): save the tenant and client IDs.
3. <a id="3-run-guided-setup"></a>[Deploy](docs/GETTING-STARTED.md#3-run-guided-setup): choose the provider, runtime, and plan.
3. <a id="3-run-guided-setup"></a>[Deploy](docs/GETTING-STARTED.md#3-run-guided-setup): choose the provider and hosting plan.
4. <a id="4-connect-your-provider-and-test"></a>[Connect and test](docs/GETTING-STARTED.md#4-connect-your-provider-and-test): configure provider access and run approved checks.
5. <a id="5-activate-and-hand-over"></a>[Activate and hand over](docs/GETTING-STARTED.md#5-activate-and-hand-over): activate after validation and assign owners.

Expand Down
35 changes: 24 additions & 11 deletions docs/GETTING-STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,33 +99,46 @@ Review the downloaded script, then run it:

On a shared workstation, use `.\Setup-Epp.ps1 -ForceAuthentication` for a fresh sign-in.

Select the tenant, subscription, existing application **client ID**, and Azure region. Then choose:

- **Provider and route:** enter or confirm the provider by name. **Tenant scope** means Global/EU
provider routing, not Azure region or a data-residency guarantee.
- **Platform:** Node.js, .NET, or Python. Setup downloads the matching stable release asset,
verifies `SHA256SUMS.txt`, and builds when required.
JavaScript is used by default, without a language prompt. To deploy another language, run
`.\Setup-Epp.ps1 -Language csharp` or `.\Setup-Epp.ps1 -Language python`.

Select the tenant, subscription, and existing application **client ID**. Setup detects the tenant's
replication scope and selects the corresponding provider route; it does not ask you to choose EU or
Global. Select the Azure region, then complete the remaining settings:

- **Azure region:** EU tenants receive recommendations within the EU Data Boundary (EU/EFTA).
Other tenants retain the existing Azure-recommended shortlist. All-region and manual selection,
including `-Location`, remain available; EU tenants receive a warning for an out-of-boundary or
unverifiable choice. Recommendations are not a data-residency or GDPR compliance guarantee.
- **Provider:** enter or confirm the provider by name. Setup downloads the language's matching
stable release asset, verifies `SHA256SUMS.txt`, and builds when required.
- **Hosting:** FC1 can scale to zero and cold-start. EP1 has paid warm capacity. Review
[plan details](../setup/docs/README.md#service-plan-selection).
- **Resource prefix:** 2-8 lowercase letters/digits, starting with a letter.
[plan details](../setup/docs/README.md#service-plan-selection) and the [cost estimate](COST-CALCULATOR.md).
- **Resource prefix:** press Enter to use `epp`, or enter 2-8 lowercase letters/digits, starting
with a letter. When rerunning an existing deployment, use its original prefix.

Complete required sign-in, MFA, or administrator consent. Resolve preflight errors before approval.

For existing encryption credentials, follow
[certificate selection](../setup/docs/README.md#encryption-certificate-selection). Coordinate
changes across every endpoint sharing the application.

**Review the deployment plan before typing `Yes`.** Check accounts, region, provider URLs,
**Review the deployment plan before typing `Yes` or `Y`.** Check accounts, region, provider URLs,
runtime, plan, resource names, permissions, certificate key IDs, and vault access.
The plan includes Microsoft Graph `Application.Read.All` for the Microsoft phone-provider service
principal. `No` or Enter cancels.
principal. `No`, `N`, or Enter cancels. Responses are case-insensitive.

**Plan review:** run interactively and choose **No** at the final prompt. See
[plan review](../setup/docs/README.md#reviewing-the-plan-without-deploying).

Wait for **Deployment completed** and the saved summary before Step 4. Setup creates or updates
Azure resource deployment and Function publication can each take several minutes. Keep the session
open; a rotating indicator identifies the operation in progress, without a percentage or estimated
completion time. Unattended or redirected output uses static status messages instead.

Wait for **Deployment completed successfully** and the saved summary before Step 4. Setup creates or updates
the Function App, hosting plan, storage, Key Vault, identities, Log Analytics, Application
Insights, diagnostics, Easy Auth, and scoped role assignments. Do not precreate these resources.
**Save the output: the endpoint URL and Application (client) ID are required for policy updates.**
Keep `epp-output` private. Its [summary](../setup/docs/README.md#read-the-deployment-summary)
records the selected tenant, subscription, provider route, runtime, plan, resource names, endpoint,
application, package provenance, and encryption certificate references. No private key is downloaded.
Expand Down
13 changes: 8 additions & 5 deletions docs/ONBOARDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@ renewal.
| Endpoint application client ID | Microsoft Entra admin center > App registrations > application > Overview | `-ApplicationId` |
| Azure region | Available Linux FC1/EP1 region that meets quota and organization requirements | `-Location` |
| Provider | Approved Security Store integration | `-Provider telesign` or `soprano` |
| Provider route | Provider-confirmed Global or EU route | `-EndpointRegion global` or `eu` |
| Runtime and plan | JavaScript, .NET, or Python with FC1 or EP1 | `-Language`, `-ServicePlan` |
| Resource prefix | Unique 2-8 character lowercase label that starts with a letter | `-ResourcePrefix` |
| Provider route | Detected from the tenant's replication scope; EU for EU tenants, Global otherwise | Optional `-EndpointRegion eu` or `global` must match the detected route |
| Language and plan | JavaScript by default; C# or Python by parameter, with FC1 or EP1 | `-Language csharp` or `python`, `-ServicePlan` |
| Resource prefix | Interactive default `epp`, or a unique 2-8 character lowercase label that starts with a letter | `-ResourcePrefix` (required unattended) |
| Encryption certificate | Existing registered key or approved replacement | `-CertificateAction` and certificate options |
| Output and source versions | Private output folder and reviewed source/release versions | Optional output and version options |

Use the application **client ID**, not its Object ID. The customer tenant ID and provider tenant ID
are different values. Global or EU selects provider routing, not Azure location or data residency.
are different values. Global or EU identifies provider routing, not Azure location or data residency.
EU tenants receive an EU Data Boundary region shortlist; other tenants retain the existing
recommendations. Explicit region overrides remain available with a warning for EU tenants.

One guided deployment uses one provider and supports both SMS and voice. Each request selects its
channel. Reusing the same subscription, application, and prefix reconfigures that deployment.
Expand All @@ -68,7 +70,8 @@ and [certificate selection](../setup/docs/README.md#encryption-certificate-selec
<a id="setup-script-compatibility"></a>
### Values setup configures

Keep `deployment-*.json` and the public certificate in private storage. Compare the summary with
Save the deployment output: the endpoint URL and Application (client) ID are required for policy
updates. Keep `deployment-*.json` and the public certificate in private storage. Compare the summary with
the approved plan. `policyChanged: false` is expected because setup does not activate policy.

| Setting | Purpose | Check |
Expand Down
10 changes: 9 additions & 1 deletion setup/Setup-Epp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
.PARAMETER ServicePlan
FC1 for Flex Consumption with a free usage grant, or EP1 for Premium with a warm instance.
Prompts when omitted; required for unattended setup.
.PARAMETER Language
JavaScript by default, without a prompt. Use csharp or python to select another language.
The legacy dotnet value remains supported for C#.
.PARAMETER EndpointRegion
Optional eu/global provider route assertion. Setup detects the tenant replication scope
and rejects a conflicting value. Omit to use the detected route.
.PARAMETER ResourcePrefix
Interactive resource-name prefix, defaulting to epp on Enter. Required for unattended setup.
.PARAMETER InstallPrerequisites
Install the Azure CLI Bicep component after explicit opt-in. The Graph SDK is not required.
.PARAMETER ForceAuthentication
Expand Down Expand Up @@ -47,7 +55,7 @@ param(
[string] $Provider,
[string] $EndpointRegion,
[string] $ResourcePrefix,
[string] $Language,
[string] $Language = 'javascript',
[string] $ServicePlan,
[ValidateSet('Create', 'Reuse', 'Replace')]
[string] $CertificateAction,
Expand Down
Loading
Loading