From e9bedcb6355b00ec391c341598da787af3261f55 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 01:48:05 -0700
Subject: [PATCH 01/13] Add daily GitHub repo digest sample
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
.env.example | 5 ++
README.md | 20 ++++--
chat.py | 7 +-
function_app.py | 184 +++++++++++++++++++++++++++++++++++++++++++++---
host.json | 1 +
5 files changed, 198 insertions(+), 19 deletions(-)
diff --git a/.env.example b/.env.example
index fd10df3..a7f97d1 100644
--- a/.env.example
+++ b/.env.example
@@ -3,3 +3,8 @@
AZURE_AI_PROJECT_ENDPOINT="https://.services.ai.azure.com/api/projects/"
AZURE_AI_MODEL_DEPLOYMENT_NAME="chat"
+
+# Optional GitHub configuration for the daily digest sample
+GITHUB_REPOSITORY="microsoft-foundry/foundry-samples"
+# GITHUB_TOKEN can be set to increase public API rate limits. OAuth is not required.
+GITHUB_TOKEN=""
diff --git a/README.md b/README.md
index c25d3de..75ac0b9 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-# Simple Agent QuickStart (Python Copilot SDK)
+# Daily Repo Digest QuickStart (Python Copilot SDK on Azure Functions)
-A simple AI agent built with the GitHub Copilot SDK, running as an Azure Function.
+A simple AI agent built with the GitHub Copilot SDK, running as an Azure Function. It creates live daily GitHub repository digests for recent pull requests, issues, and workflow failures. The default repository is `microsoft-foundry/foundry-samples`.
> Looking for [C#](https://github.com/Azure-Samples/simple-agent-functions-dotnet) or [TypeScript](https://github.com/Azure-Samples/simple-agent-functions-typescript)?
@@ -34,14 +34,15 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
func start
```
-4. Test the agent (in a new terminal):
+4. Test the digest agent (in a new terminal):
```bash
# Interactive chat client
uv run chat.py
# Or use curl directly
- curl -X POST http://localhost:7071/api/ask -d "what are the laws"
+ curl -X POST http://localhost:7071/api/ask \
+ -d "Create a concise daily repo digest for microsoft-foundry/foundry-samples."
```
To chat with a deployed instance, grab the URL and function key from your `azd` environment:
@@ -58,10 +59,19 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
## Source Code
-The agent logic is in [`function_app.py`](function_app.py). It creates a `CopilotClient`, configures a session with a system message (Asimov's Three Laws of Robotics), and exposes an HTTP endpoint (`/api/ask`) that accepts a prompt and returns the agent's response.
+The agent logic is in [`function_app.py`](function_app.py). It creates a `CopilotClient`, fetches live public GitHub data through REST APIs, and asks the model to produce a concise daily digest. The sample keeps the Azure Functions hosting model from this repo and exposes:
+
+- An HTTP endpoint at `/api/ask` for chat or API requests.
+- A timer-triggered function named `daily_repo_digest` that runs the digest at 9 AM Pacific.
[`chat.py`](chat.py) is a lightweight console client that POSTs messages to the function in a loop, giving you an interactive chat experience. It defaults to `http://localhost:7071` but can be pointed at a deployed instance via the `AGENT_URL` environment variable.
+Ask for a digest with an optional public repo such as `microsoft-foundry/foundry-samples`. If you omit the repo, the agent uses `microsoft-foundry/foundry-samples` by default. Set `GITHUB_REPOSITORY` to change the default repository. Set `GITHUB_TOKEN` only if you want higher public GitHub API rate limits.
+
+## Daily Schedule
+
+The timer trigger uses the Azure Functions NCRONTAB schedule `0 0 16,17 * * *`. Azure Functions timer schedules run in UTC for this Linux Functions sample, so the function wakes at both possible 9 AM Pacific UTC offsets and only creates a digest when the current `America/Los_Angeles` hour is 9. This keeps the sample aligned with Pacific daylight and standard time without adding a separate scheduler service.
+
## Deploy Microsoft Foundry Resources
If you prefer to use your own models via BYOK and don't already have a Microsoft Foundry project with a model deployed:
diff --git a/chat.py b/chat.py
index d61259e..7fad780 100644
--- a/chat.py
+++ b/chat.py
@@ -1,13 +1,14 @@
-"""Console chat client for the Simple Agent function app."""
+"""Console chat client for the Repo Digest function app."""
import os
import urllib.request
BASE_URL = os.environ.get("AGENT_URL", "http://localhost:7071").rstrip("/")
FUNCTION_KEY = os.environ.get("FUNCTION_KEY", "")
-print(f"=== Simple Agent Chat ===")
+print(f"=== Repo Digest Agent Chat ===")
print(f"Endpoint: {BASE_URL}/api/ask")
-print(f"Type 'exit' or 'quit' to end.\n")
+print("Ask for a daily digest, or include a public repo like microsoft-foundry/foundry-samples.")
+print("Type 'exit' or 'quit' to end.\n")
while True:
message = input("You: ").strip()
diff --git a/function_app.py b/function_app.py
index 2ae80c7..623c831 100644
--- a/function_app.py
+++ b/function_app.py
@@ -1,16 +1,26 @@
import os
+import json
+import logging
+import re
+import urllib.error
+import urllib.parse
+import urllib.request
import azure.functions as func
+from datetime import datetime, timedelta, timezone
+from zoneinfo import ZoneInfo
from copilot import CopilotClient, PermissionHandler
app = func.FunctionApp()
client = CopilotClient()
+DEFAULT_REPOSITORY = "microsoft-foundry/foundry-samples"
+PACIFIC_TIME = ZoneInfo("America/Los_Angeles")
+GITHUB_API = "https://api.github.com"
+
instructions = """
- 1. A robot may not injure a human being...
- 2. A robot must obey orders given it by human beings...
- 3. A robot must protect its own existence...
-
- Objective: Give me the TLDR in exactly 5 words.
+ You create concise daily GitHub repository digests from live repository data.
+ Focus on what changed, what needs attention, and useful next actions.
+ Use clear sample language and do not invent activity that is not in the data.
"""
@@ -37,16 +47,168 @@ def _session_config():
return config
+def _repository_from_prompt(prompt: str) -> str:
+ match = re.search(r"\b([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)\b", prompt)
+ return match.group(1) if match else os.environ.get("GITHUB_REPOSITORY", DEFAULT_REPOSITORY)
+
+
+def _github_get(path: str, query: dict | None = None) -> dict | list:
+ url = f"{GITHUB_API}{path}"
+ if query:
+ url = f"{url}?{urllib.parse.urlencode(query)}"
+
+ headers = {
+ "Accept": "application/vnd.github+json",
+ "User-Agent": "simple-agent-functions-python",
+ "X-GitHub-Api-Version": "2022-11-28",
+ }
+ token = os.environ.get("GITHUB_TOKEN")
+ if token:
+ headers["Authorization"] = f"Bearer {token}"
+
+ req = urllib.request.Request(url, headers=headers)
+ try:
+ with urllib.request.urlopen(req, timeout=20) as response:
+ return json.loads(response.read().decode("utf-8"))
+ except urllib.error.HTTPError as exc:
+ detail = exc.read().decode("utf-8", errors="replace")
+ raise RuntimeError(f"GitHub API returned {exc.code} for {url}: {detail}") from exc
+ except urllib.error.URLError as exc:
+ raise RuntimeError(f"GitHub API request failed for {url}: {exc.reason}") from exc
+
+
+def _brief_user(item: dict) -> str:
+ user = item.get("user") or {}
+ return user.get("login", "unknown")
+
+
+def _repo_digest_context(repository: str) -> dict:
+ owner, repo = repository.split("/", 1)
+ since = datetime.now(timezone.utc) - timedelta(days=1)
+ since_text = since.isoformat(timespec="seconds").replace("+00:00", "Z")
+
+ repo_info = _github_get(f"/repos/{owner}/{repo}")
+ pulls = _github_get(
+ f"/repos/{owner}/{repo}/pulls",
+ {"state": "open", "sort": "updated", "direction": "desc", "per_page": 20},
+ )
+ issues = _github_get(
+ f"/repos/{owner}/{repo}/issues",
+ {"state": "open", "sort": "updated", "direction": "desc", "since": since_text, "per_page": 20},
+ )
+ runs = _github_get(
+ f"/repos/{owner}/{repo}/actions/runs",
+ {"status": "completed", "per_page": 20},
+ )
+
+ recent_pulls = [
+ {
+ "number": item["number"],
+ "title": item["title"],
+ "author": _brief_user(item),
+ "updated_at": item["updated_at"],
+ "url": item["html_url"],
+ }
+ for item in pulls
+ if item.get("updated_at", "") >= since_text
+ ][:10]
+
+ recent_issues = [
+ {
+ "number": item["number"],
+ "title": item["title"],
+ "author": _brief_user(item),
+ "updated_at": item["updated_at"],
+ "url": item["html_url"],
+ }
+ for item in issues
+ if "pull_request" not in item
+ ][:10]
+
+ failed_runs = [
+ {
+ "name": item.get("name"),
+ "conclusion": item.get("conclusion"),
+ "branch": item.get("head_branch"),
+ "created_at": item.get("created_at"),
+ "url": item.get("html_url"),
+ }
+ for item in runs.get("workflow_runs", [])
+ if item.get("created_at", "") >= since_text
+ and item.get("conclusion") in {"failure", "timed_out", "cancelled", "action_required"}
+ ][:10]
+
+ return {
+ "repository": repository,
+ "generated_at": datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z"),
+ "lookback": "24 hours",
+ "stars": repo_info.get("stargazers_count"),
+ "forks": repo_info.get("forks_count"),
+ "open_issues": repo_info.get("open_issues_count"),
+ "recent_open_pull_requests": recent_pulls,
+ "recent_open_issues": recent_issues,
+ "recent_workflow_failures": failed_runs,
+ }
+
+
+async def _run_digest(prompt: str) -> str:
+ repository = _repository_from_prompt(prompt)
+ context = _repo_digest_context(repository)
+ digest_prompt = f"""
+Create a concise daily repo digest for {repository}.
+
+User request:
+{prompt}
+
+Live GitHub data:
+{json.dumps(context, indent=2)}
+
+Return:
+1. A one-line summary.
+2. Pull requests updated in the last 24 hours.
+3. Issues updated in the last 24 hours.
+4. Workflow failures from the last 24 hours.
+5. Suggested next actions.
+
+If a section has no items, say "None found".
+"""
+ session = await client.create_session(_session_config())
+ try:
+ reply = await session.send_and_wait({"prompt": digest_prompt})
+ return (reply.data.content if reply and reply.data else None) or "No response"
+ finally:
+ await session.destroy()
+
+
@app.route(route="ask", methods=["POST"])
async def ask(req: func.HttpRequest) -> func.HttpResponse:
"""HTTP trigger that sends a message to the Copilot SDK agent."""
- prompt = req.get_body().decode("utf-8") or "What are the laws?"
+ prompt = req.get_body().decode("utf-8") or f"Create a concise daily repo digest for {DEFAULT_REPOSITORY}."
+ try:
+ response_text = await _run_digest(prompt)
+ except RuntimeError as exc:
+ logging.exception("Could not create repo digest.")
+ return func.HttpResponse(str(exc), status_code=502, mimetype="text/plain")
- session = await client.create_session(_session_config())
+ return func.HttpResponse(response_text, mimetype="text/plain")
- reply = await session.send_and_wait({"prompt": prompt})
- response_text = (reply.data.content if reply and reply.data else None) or "No response"
- await session.destroy()
+@app.timer_trigger(
+ schedule="0 0 16,17 * * *",
+ arg_name="daily_digest_timer",
+ run_on_startup=False,
+ use_monitor=True,
+)
+async def daily_repo_digest(daily_digest_timer: func.TimerRequest) -> None:
+ """Runs the digest once per day at 9 AM Pacific."""
+ now_pacific = datetime.now(PACIFIC_TIME)
+ if now_pacific.hour != 9:
+ logging.info("Skipping daily repo digest because it is %s Pacific.", now_pacific.strftime("%H:%M"))
+ return
- return func.HttpResponse(response_text, mimetype="text/plain")
+ if daily_digest_timer.past_due:
+ logging.info("Daily repo digest timer is past due.")
+
+ prompt = f"Create a concise daily repo digest for {os.environ.get('GITHUB_REPOSITORY', DEFAULT_REPOSITORY)}."
+ digest = await _run_digest(prompt)
+ logging.info("Daily repo digest:\n%s", digest)
diff --git a/host.json b/host.json
index 06d01bd..dbf749f 100644
--- a/host.json
+++ b/host.json
@@ -1,5 +1,6 @@
{
"version": "2.0",
+ "functionTimeout": "00:30:00",
"logging": {
"applicationInsights": {
"samplingSettings": {
From b84327b177307c28cb28ab7bd06a828791303d36 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 01:48:42 -0700
Subject: [PATCH 02/13] Update devcontainer to Python 3.13
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
.devcontainer/Dockerfile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index df6371a..66cf977 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,4 +1,5 @@
-FROM mcr.microsoft.com/vscode/devcontainers/python:dev-3.12-bookworm
+FROM mcr.microsoft.com/vscode/devcontainers/python:dev-3.13-bookworm
+COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
# Copy custom first notice message.
COPY first-run-notice.txt /tmp/staging/
From 5866d7f13c9978628278379a00eb0be53939a863 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 01:56:25 -0700
Subject: [PATCH 03/13] Use idiomatic uv workflow
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
README.md | 12 +-
infra/main.bicep | 2 +-
infra/main.json | 39 ++--
pyproject.toml | 14 ++
uv.lock | 571 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 611 insertions(+), 27 deletions(-)
create mode 100644 pyproject.toml
create mode 100644 uv.lock
diff --git a/README.md b/README.md
index 75ac0b9..d64e3db 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,8 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
## Prerequisites
-- [Python 3.11+](https://docs.astral.sh/uv/getting-started/installation/) (via [uv](https://docs.astral.sh/uv/))
+- Python 3.13+
+- [uv](https://docs.astral.sh/uv/getting-started/installation/)
- [Azure Functions Core Tools](https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local#install-the-azure-functions-core-tools)
- [Azure Developer CLI (azd)](https://aka.ms/azd-install) (only needed for deploying Microsoft Foundry resources)
- Access to an AI model via one of:
@@ -22,16 +23,13 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
2. Install dependencies:
```bash
- uv venv
- source .venv/bin/activate # macOS/Linux
- # .venv\Scripts\activate # Windows
- uv pip install -r requirements.txt
+ uv sync
```
3. Run the function locally:
```bash
- func start
+ uv run func start
```
4. Test the digest agent (in a new terminal):
@@ -68,6 +66,8 @@ The agent logic is in [`function_app.py`](function_app.py). It creates a `Copilo
Ask for a digest with an optional public repo such as `microsoft-foundry/foundry-samples`. If you omit the repo, the agent uses `microsoft-foundry/foundry-samples` by default. Set `GITHUB_REPOSITORY` to change the default repository. Set `GITHUB_TOKEN` only if you want higher public GitHub API rate limits.
+Local development uses [`pyproject.toml`](pyproject.toml) with `uv sync` and `uv run`. [`requirements.txt`](requirements.txt) is kept for Azure Functions packaging and should stay aligned with the dependencies in `pyproject.toml`.
+
## Daily Schedule
The timer trigger uses the Azure Functions NCRONTAB schedule `0 0 16,17 * * *`. Azure Functions timer schedules run in UTC for this Linux Functions sample, so the function wakes at both possible 9 AM Pacific UTC offsets and only creates a digest when the current `America/Los_Angeles` hour is 9. This keeps the sample aligned with Pacific daylight and standard time without adding a separate scheduler service.
diff --git a/infra/main.bicep b/infra/main.bicep
index 45890cd..ac93d0f 100644
--- a/infra/main.bicep
+++ b/infra/main.bicep
@@ -176,7 +176,7 @@ module api './app/api.bicep' = {
applicationInsightsName: monitoring.outputs.applicationInsightsName
appServicePlanId: appServicePlan.outputs.resourceId
runtimeName: 'python'
- runtimeVersion: '3.11'
+ runtimeVersion: '3.13'
storageAccountName: storage.outputs.name
deploymentStorageContainerName: deploymentStorageContainerName
identityId: apiUserAssignedIdentity.outputs.resourceId
diff --git a/infra/main.json b/infra/main.json
index 3db9165..c262495 100644
--- a/infra/main.json
+++ b/infra/main.json
@@ -4,8 +4,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "15312351327738428406"
+ "version": "0.44.1.10279",
+ "templateHash": "13649461923352592980"
}
},
"parameters": {
@@ -19,7 +19,6 @@
},
"location": {
"type": "string",
- "defaultValue": "eastus2",
"metadata": {
"azd": {
"type": "location"
@@ -125,7 +124,7 @@
},
"modelName": {
"type": "string",
- "defaultValue": "gpt-4.1-mini",
+ "defaultValue": "gpt-5-mini",
"metadata": {
"description": "Model name for deployment"
}
@@ -139,7 +138,7 @@
},
"modelVersion": {
"type": "string",
- "defaultValue": "2025-04-14",
+ "defaultValue": "2025-08-07",
"metadata": {
"description": "Model version for deployment"
}
@@ -11352,7 +11351,7 @@
"value": "python"
},
"runtimeVersion": {
- "value": "3.11"
+ "value": "3.13"
},
"storageAccountName": {
"value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage'), '2025-04-01').outputs.name.value]"
@@ -11388,8 +11387,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "13875020067717112629"
+ "version": "0.44.1.10279",
+ "templateHash": "10042534433781864103"
}
},
"parameters": {
@@ -17062,8 +17061,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "509960084051832567"
+ "version": "0.44.1.10279",
+ "templateHash": "1486066558996912834"
}
},
"parameters": {
@@ -17462,8 +17461,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "16600644053277764500"
+ "version": "0.44.1.10279",
+ "templateHash": "12002139959618347601"
}
},
"parameters": {
@@ -17722,8 +17721,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "11495693447171960690"
+ "version": "0.44.1.10279",
+ "templateHash": "13465598790985520929"
}
},
"parameters": {
@@ -18017,8 +18016,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "10558810039605184594"
+ "version": "0.44.1.10279",
+ "templateHash": "6300504802026129812"
}
},
"parameters": {
@@ -18114,8 +18113,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "10184174839951184336"
+ "version": "0.44.1.10279",
+ "templateHash": "5311757261854492420"
}
},
"parameters": {
@@ -18250,8 +18249,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "4878422762311213275"
+ "version": "0.44.1.10279",
+ "templateHash": "12790120829214215653"
}
},
"parameters": {
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..387ffac
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,14 @@
+[project]
+name = "simple-agent-functions-python"
+version = "1.0.0"
+description = "Azure Functions and Copilot SDK sample that creates daily GitHub repository digests."
+readme = "README.md"
+requires-python = ">=3.13"
+dependencies = [
+ "azure-functions",
+ "azure-identity",
+ "github-copilot-sdk",
+]
+
+[tool.uv]
+package = false
diff --git a/uv.lock b/uv.lock
new file mode 100644
index 0000000..5e879c0
--- /dev/null
+++ b/uv.lock
@@ -0,0 +1,571 @@
+version = 1
+revision = 3
+requires-python = ">=3.13"
+
+[[package]]
+name = "annotated-types"
+version = "0.7.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
+]
+
+[[package]]
+name = "anyio"
+version = "4.14.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "idna" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/3b/72/5562aabb8dd7181e8e860622a38bea08d17842b99ecd4c91f84ac95251b0/anyio-4.14.1.tar.gz", hash = "sha256:8d648a3544c1a700e3ff78615cd679e4c5c3f149904287e73687b2596963629e", size = 254831, upload-time = "2026-06-24T20:56:06.017Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b0/7b/90df4a0a816d98d6ea26f559d87836d494a2cf1fcf063be67df50a7bcc30/anyio-4.14.1-py3-none-any.whl", hash = "sha256:4e5533c5b8ff0a24f5d7a176cbe6877129cd183893f66b537f8f227d10527d72", size = 124875, upload-time = "2026-06-24T20:56:04.413Z" },
+]
+
+[[package]]
+name = "azure-core"
+version = "1.41.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "requests" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a6/f3/b416179e408990df5db0d516283022dde0f5d0111d98c1a848e41853e81c/azure_core-1.41.0.tar.gz", hash = "sha256:f46ff5dfcd230f25cf1c19e8a34b8dc08a337b2503e268bb600a16c00db8ad5a", size = 381042, upload-time = "2026-05-07T23:30:54.302Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5b/db/325c6d7312d2200251c52323878281045aaffcb5586612296484e4280eaa/azure_core-1.41.0-py3-none-any.whl", hash = "sha256:522b4011e8180b1a3dcd2024396a4e7fe9ac37fb8597db47163d230b5efe892d", size = 220920, upload-time = "2026-05-07T23:30:56.357Z" },
+]
+
+[[package]]
+name = "azure-functions"
+version = "2.2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "werkzeug" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d9/fe/76756c226321bdda7d42d42da4256dcc0c3200c38d2b710b85e376540a93/azure_functions-2.2.0.tar.gz", hash = "sha256:c1b498cf48beefe2271ebc454f1a4fb6f587bd97c116e412773854b4c66ad1dc", size = 166686, upload-time = "2026-07-06T19:39:42.934Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/19/8b/04b61f98fc24e87838339483d4374832caaf96ee09b86a551fe4e4efa6cf/azure_functions-2.2.0-py3-none-any.whl", hash = "sha256:7e73f2a3ce011cfff09eb8465ab5aeb3c61e86ffeadee209ff6ab65a5ef12f83", size = 123878, upload-time = "2026-07-06T19:39:44.374Z" },
+]
+
+[[package]]
+name = "azure-identity"
+version = "1.25.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "azure-core" },
+ { name = "cryptography" },
+ { name = "msal" },
+ { name = "msal-extensions" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c5/0e/3a63efb48aa4a5ae2cfca61ee152fbcb668092134d3eb8bfda472dd5c617/azure_identity-1.25.3.tar.gz", hash = "sha256:ab23c0d63015f50b630ef6c6cf395e7262f439ce06e5d07a64e874c724f8d9e6", size = 286304, upload-time = "2026-03-13T01:12:20.892Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/49/9a/417b3a533e01953a7c618884df2cb05a71e7b68bdbce4fbdb62349d2a2e8/azure_identity-1.25.3-py3-none-any.whl", hash = "sha256:f4d0b956a8146f30333e071374171f3cfa7bdb8073adb8c3814b65567aa7447c", size = 192138, upload-time = "2026-03-13T01:12:22.951Z" },
+]
+
+[[package]]
+name = "certifi"
+version = "2026.6.17"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" },
+]
+
+[[package]]
+name = "cffi"
+version = "2.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pycparser", marker = "implementation_name != 'PyPy'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz", hash = "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", size = 531036, upload-time = "2026-07-06T21:34:30.382Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/96/88/a996879e2eeccb815f6e3a5967b12a308257412acec882039d386bd2aa7b/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:10537b1df4967ca26d21e5072d7d54188354483b91dc75058968d3f0cf13fbda", size = 194331, upload-time = "2026-07-06T21:33:03.697Z" },
+ { url = "https://files.pythonhosted.org/packages/58/85/7ae00d5c8dd6266f4e944c3db630f3c5c9a98b61d469c714d848b1d8138a/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a95b05f9baf29b91171b3a8bd2020b028835243e7b0ff6bb23e2a3c228518b1b", size = 196966, upload-time = "2026-07-06T21:33:05.353Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/e9/45c3a76ad8d43ad9261f4c95436da61128d3ca545d72b9612c0ab5be0b1c/cffi-2.1.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:15faec4adfff450819f3aee0e2e02c812de6edb88203aa58807955db2003472a", size = 184795, upload-time = "2026-07-06T21:33:06.699Z" },
+ { url = "https://files.pythonhosted.org/packages/84/4c/82f132cb4418ee6d953d982b19191e87e2a6372c8a4ce36e50b69d6ade4a/cffi-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:716ff8ec22f20b4d988b12884086bcef0fc99737043e503f7a3935a6be99b1ea", size = 184746, upload-time = "2026-07-06T21:33:08.071Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/1c/4ed5a0e5bdca6cbc275556de3328dd1b76fd0c11cc13c88fe66d1d8715f2/cffi-2.1.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:63960549e4f8dc41e31accb97b975abaecfc44c03e396c093a6436763c2ea7db", size = 214747, upload-time = "2026-07-06T21:33:09.671Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/a6/e879bb68cc23a2bc9ba8f4b7d8019f0c2694bad2ab6c4a3701d429439f58/cffi-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff067a8d8d880e7809e4ac88eb009bb848870115317b306666502ccad30b147f", size = 222392, upload-time = "2026-07-06T21:33:10.896Z" },
+ { url = "https://files.pythonhosted.org/packages/88/f6/01890cfd63c08f8eb96a8319b0443690197d240a8bd6346048cf7bde9190/cffi-2.1.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3b926723c13eba9f81d2ef3820d63aeceec3b2d4639906047bf675cb8a7a500d", size = 210285, upload-time = "2026-07-06T21:33:12.251Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/cf/2b684132056f438567b61e19d690dd31cd0921ace051e0a458be6074369e/cffi-2.1.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:47ff3a8bfd8cb9da1af7524b965127095055654c177fcfc7578debcb015eecd0", size = 208801, upload-time = "2026-07-06T21:33:13.617Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/08/f2e7d62c460faae0926f2d6e423694aa409ced3bc1fe2927a0a6e5f05416/cffi-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:799416bae98336e400981ff6e532d67d5c709cfb30afb79865a1315f94b0e224", size = 221808, upload-time = "2026-07-06T21:33:15.466Z" },
+ { url = "https://files.pythonhosted.org/packages/38/37/04f54b8e63a02f3d908332c9effbf8c366167c6f733ed8a3d4f79b7e2a1e/cffi-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:961be50688f7fba2fa65f63712d3b9b341a22311f5253460ce933f52f0de1c8c", size = 225241, upload-time = "2026-07-06T21:33:16.869Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/d6/c72eecca433cd3e681c65ed313ab4835d9d4a379704d0f628a6a05f51c2e/cffi-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf5c6cf48238b0eb4c086978c492ad1cbc22373fc5b2d7353b3a598ce6db887a", size = 223588, upload-time = "2026-07-06T21:33:18.239Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/4b/e706f67279140f92939da3475ad610df18bfd52d50f14953a8e5fede71d5/cffi-2.1.0-cp313-cp313-win32.whl", hash = "sha256:db3eb7d46527159a878ec3460e9d40615bc25ba337d477db681aea6e4f05c5d2", size = 175248, upload-time = "2026-07-06T21:33:19.799Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/47/59eb7975cb0e4ef0afa764ea945b29a5bb4537a9f771cb7d6c8a5dd74c95/cffi-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:8e74a6135550c4748af665b1b1118b6aab33b1fc6a16f9aff630af107c3b4512", size = 185717, upload-time = "2026-07-06T21:33:21.47Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/af/34fee85c48f8d94efc8597bc09470c9dd274c145f1c12e0fbc6ab6d38d74/cffi-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:2282cd5e38aa8accd03e99d1256af8411c84cdbee6a89d841b563fdbd1f3e50f", size = 180114, upload-time = "2026-07-06T21:33:22.515Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/f0/81478e482afa03f6d18dc8f2afb5edc45b3080853b634b5ed91961be0998/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d2117334c3af3bdcb9a88522b844a2bdb5efdc4f71c6c822df55486ae1c3347a", size = 194142, upload-time = "2026-07-06T21:33:23.657Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/95/8de304305cd9204974b0ca051b86d307cafca13aa575a0ef1b44d92c0d8c/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:702c436735fbe99d59ada02a1f65cfc0d31c0ee8b7290912f8fbc5cd1e4b16c3", size = 196819, upload-time = "2026-07-06T21:33:25.007Z" },
+ { url = "https://files.pythonhosted.org/packages/20/71/7c8372d30e42415602ed9f268f7cfd66f1b855fed881ecd168bcb45dbc0b/cffi-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1ff3456eab0d889592d1936d6125bbfbc7ae4d3354a700f8bd80450a66445d4d", size = 184965, upload-time = "2026-07-06T21:33:26.605Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/5c/584e626835f0375c928176c04137c96927165cb8733cdb3150ec04e5ee5e/cffi-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c4165821e131d6d4ca444347c2b694e2311bcfa3fe5a861cc72968f28867beac", size = 184952, upload-time = "2026-07-06T21:33:27.823Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/d2/065fcae1c73979fac8e054462478d0ff8a29c40cdc2ed7ea5676a061df53/cffi-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:276f20fffd7b396e12516ba8edf9509210ac248cbbc5acbc39cd512f9f59ebe6", size = 222353, upload-time = "2026-07-06T21:33:29.178Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/a5/e8bbb1ce5b3ac2f53ad6a10bde44318a5a8d99d4f4a000d44a6e39aeb3e4/cffi-2.1.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7d5980a3433d4b71a5e120f9dd551403d7824e31e2e67124fe2769c404c06913", size = 210051, upload-time = "2026-07-06T21:33:30.534Z" },
+ { url = "https://files.pythonhosted.org/packages/28/ed/c127d3ac36e899c965e3361357c3befacd6578c03f40125183e41c3b219e/cffi-2.1.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6ca4919c6e4f89aa99c42510b42cf54596892c00b3f9077f6bdd1505e24b9c8d", size = 208630, upload-time = "2026-07-06T21:33:31.753Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/d7/97d3136f81db489ec8d1d67748c110d6c994268fd7528014aa9f2b085e4e/cffi-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d53d10f7da99ae46f7373b9150393e9c5eab9b224909982b43832668de4779f5", size = 221593, upload-time = "2026-07-06T21:33:33.044Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/27/93195977168ee63aed233a1a0993a2178798654d1f4bddcdd321d6fd3b21/cffi-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c351efb95e832a853a29361675f33a7ce53de1a109cd73fd47af0712213aa4ce", size = 225146, upload-time = "2026-07-06T21:33:34.224Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/c1/6dbd291ee2ae5a50a034aa057207081f545923bbf15dad4511e985aafff5/cffi-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:dbf7c7a88e2bac086f06d14577332760bdeecc42bdec8ac4077f6260557d9326", size = 223240, upload-time = "2026-07-06T21:33:35.57Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/6f/ade5ce9863a57992a6ea3d0d10d7e29b8749fc127204b3d493d667b2815f/cffi-2.1.0-cp314-cp314-win32.whl", hash = "sha256:1854b724d00f6654c742097d5387569021be12d3a0f770eae1df8f8acfcc6acd", size = 177723, upload-time = "2026-07-06T21:33:51.626Z" },
+ { url = "https://files.pythonhosted.org/packages/41/de/92b9eeed4ae4a21d6fd9b2a2c8505cbed573299902ea73981cc13f7ff62c/cffi-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:1b96bfe2c4bd825681b7d311ad6d9b7280a091f43e8f63da5729638083cd3bfb", size = 187937, upload-time = "2026-07-06T21:33:53.403Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/1a/cc6ae6c2913a03aab8898eee57963cf1035b8df5872ed8b9115fcc7e2be8/cffi-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:7d28dff1db6764108bc30788d85d61c876beff416d9a49cb9dd7c5a9f34f5804", size = 183001, upload-time = "2026-07-06T21:33:54.74Z" },
+ { url = "https://files.pythonhosted.org/packages/14/f0/134c00ce0779ec86dea2aa1aac69339c2741a8045072676763512363a2ea/cffi-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7ea6b3e2c4250ff1de21c630fe72d0f63eb95c2c32ffbf64a358cf4a8836d714", size = 188538, upload-time = "2026-07-06T21:33:36.792Z" },
+ { url = "https://files.pythonhosted.org/packages/50/d8/3b86aba791cb610d24e8a3e1b2cd529e71fa15096b04e4d4e360049d4a4c/cffi-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6af371f3767faeffc6ac1ef57cdfd25844403e9d3f476c5537caee499de96376", size = 188230, upload-time = "2026-07-06T21:33:38.011Z" },
+ { url = "https://files.pythonhosted.org/packages/14/d0/117dcd9209255ad8571fbc8c92ef32593a1d294dcec91ddc4e4db50606f2/cffi-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb4e8997a49aa2c08a3e43c9045d224448b8941d88e7ac163c7d383e560cbf98", size = 223899, upload-time = "2026-07-06T21:33:39.514Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/3d/f20f8b886b254e3ad10e15cd4186d3aed49f3e6a35ab37aab9f8f25f7c03/cffi-2.1.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf01d8c84cbea96b944c73b22182e6c7c432b3475632b8111dbfdc95ddad6e13", size = 211652, upload-time = "2026-07-06T21:33:40.851Z" },
+ { url = "https://files.pythonhosted.org/packages/28/3b/fad54de07260b93ddeef4b96d0131d57ea900675df1d410ae1deee52d7a6/cffi-2.1.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:33eb1ad83ebe8f313e0df035c406227d55a79456704a863fad9842136af5ad7d", size = 210755, upload-time = "2026-07-06T21:33:42.183Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/82/3d5c705acb7abbba9bbd7d79b8e62e0f25b6120eb7ae6ac49f1b721722fe/cffi-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ac0f1a2d0cfa7eea3f2aaf006ab6e70e8feeb16b75d65b7e5939982ca2f11056", size = 223933, upload-time = "2026-07-06T21:33:43.603Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/d0/47e338384ab6b1004241002fa616301020cea4fc95f283506565d252f276/cffi-2.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c16914df9fb7f500e440e6875fa23ff5e0b31db01fa9c06af98d59a91f0dc2e4", size = 226749, upload-time = "2026-07-06T21:33:45.046Z" },
+ { url = "https://files.pythonhosted.org/packages/70/25/65bd5b58ea4bfdfc15cde02cb5365f89ef8ab8b2adfb8fe5c4bd4233382f/cffi-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5ecbd0499275d57506d397eebe1981cee87b47fcd9ef5c22cab7ed7644a39a94", size = 225703, upload-time = "2026-07-06T21:33:46.374Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/78/aa01ac599a8a4322533d45a1f9bc93b338276d2d59dabbe7c6d92a775c81/cffi-2.1.0-cp314-cp314t-win32.whl", hash = "sha256:7d034dcffa09e9a46c93fa3a3be402096cb5354ac6e41ab8e5cc9cd8b642ad76", size = 182857, upload-time = "2026-07-06T21:33:47.696Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/26/d00496b22de4d4228f32dde94ad996f350c8aad676d63bcca0743c8dea4d/cffi-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0582a58f3051372229ca8e7f5f589f9e5632678208d8636fea3676711fdf7fe5", size = 194065, upload-time = "2026-07-06T21:33:48.953Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/dd/0c7dbf815a579ff005008a2d815a55d6bb047c349eef536d9dc53d3f0a8d/cffi-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:510aeeeac94811b138077451da1fb18b308a5feab47dd2b603af55804155e1c8", size = 186404, upload-time = "2026-07-06T21:33:50.309Z" },
+ { url = "https://files.pythonhosted.org/packages/55/c7/8c8c50cb11c6750051daf12164098a9a6f027ac4356967fd4d800a07f242/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:2e9dabb9abcb7ad15938c7196ad5c1718a4e6d33cc79b4c0209bdb64c4a54a5c", size = 194121, upload-time = "2026-07-06T21:33:56.109Z" },
+ { url = "https://files.pythonhosted.org/packages/99/e2/67680bf19a6b60d2bb7ff83baefa2a4c3d2d7dc0f3277034b802e1fc504c/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:37f525a7e7e50c017fdebe58b787be310ad59357ae43a053943a6e1a6c526001", size = 196820, upload-time = "2026-07-06T21:33:57.288Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/da/4bbe583a3b3a5c8c60892124fe17f3fa3656523faf0d3484eae90f091853/cffi-2.1.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:95f2954c2c9473d892eca6e0409f3568b37ab62a8eedb122461f73cc273476e3", size = 184936, upload-time = "2026-07-06T21:33:58.765Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/4b/1f4c36ab273980d7aa75bb126ea4f8971f24a96108acad3a0a084028c57b/cffi-2.1.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:cdf2448aab5f661c9315308ec8b93f4e8a1a67a3c733f8631067a2b67d5913dc", size = 185045, upload-time = "2026-07-06T21:34:00.085Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/c3/ad299dc38f3583f8d916b299f028af418a9ec98bc695fcbebeae7420691c/cffi-2.1.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:90bec57cf82089383bd06a605b3eb8daebf7e5a668520beaf6e327a83a947699", size = 222342, upload-time = "2026-07-06T21:34:01.814Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/d8/df4543cc087245044ed02ef3ad8e0a26619d0075ac7a77a12dc81177851b/cffi-2.1.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6274dcb2d15cef48daa73ed1be5a40d501d74dccd0cd6db364776d12cb6ba022", size = 210073, upload-time = "2026-07-06T21:34:03.255Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/0e/fac738d73728c6cea2a88a2883dca54892496cbba88a1dc1f2909cb8a6f5/cffi-2.1.0-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:2b71d409cccee78310ab5dec549aed052aaea483346e282c7b02362596e01bb0", size = 208551, upload-time = "2026-07-06T21:34:04.433Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/3f/0b04a700dd64f465c93020253a793a82c9b4dff9961f48facd0df945d9b8/cffi-2.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d3538f9c0e50670f4deb93dbb696576e60590369cae2faf7de681e597a8a1f1", size = 221649, upload-time = "2026-07-06T21:34:06.157Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/7c/b7379a5704c79eda57ce075869ba70a0368d1c850f803b3c0d078d39dcaf/cffi-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:8f9ec95b8a043d3dfbc74d9abc6f7baf524dd27a8dc160b0a32ff9cdab650c28", size = 225203, upload-time = "2026-07-06T21:34:07.489Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/02/d5e6c43ea85c41bda2a184a3418f195fe7cf602967a8d2b94e085b83deef/cffi-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:af5e2915d41fe6c961694d7bfdc8562942638200f3ce2765dfb8b745cf997629", size = 223263, upload-time = "2026-07-06T21:34:08.712Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/d8/772b8259bf75749adffb1c546828978381fb516f60cf701f6c83daf60c85/cffi-2.1.0-cp315-cp315-win32.whl", hash = "sha256:0a42c688d19fca6e095a53c6a6e2295a5b050a8b289f109adab02a9e61a25de6", size = 177696, upload-time = "2026-07-06T21:34:26.355Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/dd/afa2191fc6d57fedd26e5844a2fe2fcc0bbfa00961bbaa5a41e4921e7cca/cffi-2.1.0-cp315-cp315-win_amd64.whl", hash = "sha256:bccbbb5ee76a61f9d99b5bf3846a51d7fca4b6a732fe46f89295610edaf41853", size = 187914, upload-time = "2026-07-06T21:34:27.58Z" },
+ { url = "https://files.pythonhosted.org/packages/05/ef/6cd4f8c671517162379dc79cfae5aea9106bc38abb89628d5c16adf6a838/cffi-2.1.0-cp315-cp315-win_arm64.whl", hash = "sha256:8d35c139744adb3e727cd51b1a18324bbe44b8bd41bf8322bca4d41289f48eda", size = 183004, upload-time = "2026-07-06T21:34:28.905Z" },
+ { url = "https://files.pythonhosted.org/packages/11/b6/12fc55092817a5faa26fb8c40c7f9d662e11a46ee248c137aafc42517d92/cffi-2.1.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f9912624a0c0b834b7520d7769b3644453aabc0a7e1c839da7359f050750e9bc", size = 188378, upload-time = "2026-07-06T21:34:09.926Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/2e/cdac88979f295fde5daa69622c7d2111e56e7ceb94f211357fbe452339e4/cffi-2.1.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:df92f2aba50eb4d96718b68ef76f2e57a57b54f2fa62333496d16c6d585a85ca", size = 188319, upload-time = "2026-07-06T21:34:11.101Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/27/1d0b408497e41a74795af122d7b603c418c5fed0171450f899afd04e594f/cffi-2.1.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0520e1f4c35f44e209cbbb421b67eec42e6a157f59444dfb6058874ff3610e5d", size = 223904, upload-time = "2026-07-06T21:34:12.606Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/31/e115c985105dd7ffb32444505f18ceb874bb42d992af05d5dced7ecf1980/cffi-2.1.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3681e031db29958a7502f5c0c9d6bbc4c36cb20f7b104086fa642d1799631ff8", size = 211554, upload-time = "2026-07-06T21:34:13.987Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/67/9e6e09409336d9e515c58367e7cfcf4f89df06ad25252675595a58eb59d5/cffi-2.1.0-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:762f99479dcb369f60ab9017ad4ab97a36a1dd7c1ee5a3b15db0f4b8659120cd", size = 210795, upload-time = "2026-07-06T21:34:15.972Z" },
+ { url = "https://files.pythonhosted.org/packages/19/e5/d3cc82a4a0be7902af279c04181ad038449c096734464a5ae1de3e1401bd/cffi-2.1.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0611e7ebf90573a535ebdc33ae9da222d037853983e13359f580fab781ca017f", size = 223843, upload-time = "2026-07-06T21:34:17.509Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/65/b434abc97ce7cecc2c640fde160507c0ecc7e21544b483ba3325d2e2ea17/cffi-2.1.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:86cf8755a791f72c85dc287128cc62d4f24d392e3f1e15837245623f4a33cccc", size = 226773, upload-time = "2026-07-06T21:34:19.05Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/9f/d4dc66ca651eb1145a133314cda721abf13cfac3d28c4a0402263ae6ad75/cffi-2.1.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:ba00f661f8ba35d075c937174e27c2c421cec3942fd2e0ea3e66996757c0fdd9", size = 225719, upload-time = "2026-07-06T21:34:20.576Z" },
+ { url = "https://files.pythonhosted.org/packages/68/5a/e536c528bc8057496c360c0978559a2dc45653f89dd6151078aa7d8fca1a/cffi-2.1.0-cp315-cp315t-win32.whl", hash = "sha256:cb96698e3c7413d906ce83f8ffd245ec1bd94707541f299d0ce4d6b0193e982b", size = 182760, upload-time = "2026-07-06T21:34:22.059Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/0b/0ffe8b82d3875bced5fa1e7986a7a46b748262a40ab7f60b475eb9fb1bb3/cffi-2.1.0-cp315-cp315t-win_amd64.whl", hash = "sha256:f146d154428a2523f9cc7936c02353c2459b8f6cf07d3cd1ee1c0a611109c5d5", size = 193769, upload-time = "2026-07-06T21:34:23.589Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/17/1073b53b68c9b5ca6914adf5f8bf55aacc2d3be102418c90700160ea8605/cffi-2.1.0-cp315-cp315t-win_arm64.whl", hash = "sha256:cbb7640ce37159548d2147b5b8c241f962143d4c71231431820783f4dc78f210", size = 186405, upload-time = "2026-07-06T21:34:24.857Z" },
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.4.9"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/bd/2a/23f34ec9d04624958e137efdc394888716353190e75f25dd22c7a2c7a8aa/charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b", size = 152439, upload-time = "2026-07-07T14:34:58.454Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b2/06/97ec2aeae780b31d742b6352218b43841a6871e2564578ca522dce4a45c3/charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614", size = 317688, upload-time = "2026-07-07T14:33:35.408Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/39/8ff066c672434225f8d25f8b739f992af250944392173dcc88362681c9bf/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698", size = 214982, upload-time = "2026-07-07T14:33:36.996Z" },
+ { url = "https://files.pythonhosted.org/packages/92/8f/3a47a3667c83c2df9483d91644c6c107de3bf8874aa1793da9d3012eb986/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b", size = 236460, upload-time = "2026-07-07T14:33:38.536Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/60/b22cdbee7e4013dab8b0d7647fc6181120fbbbc8f7025c226d15bd5a47fc/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9", size = 232003, upload-time = "2026-07-07T14:33:40.059Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/f8/72eb13dcabe7257035cea8aefd922caad2f110d252bf9f67c4c2ca763aee/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33", size = 223149, upload-time = "2026-07-07T14:33:41.631Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/3e/faee8f9de92b14ee1198e9163252bb15efee7301b31256a3b6d9ebfdd0dd/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63", size = 207901, upload-time = "2026-07-07T14:33:43.209Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/25/45f30093ae27dd7b92a793b61882a38685f993700113ca36e0c9c14965e1/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0", size = 219176, upload-time = "2026-07-07T14:33:44.725Z" },
+ { url = "https://files.pythonhosted.org/packages/48/18/c8f397329c35e32f6a837e488986f4ae03bd2abebc453b48714991630c2f/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe", size = 217356, upload-time = "2026-07-07T14:33:46.192Z" },
+ { url = "https://files.pythonhosted.org/packages/86/7e/5ce0bba863470fd1902d5e5843968951bddf38abe4742fc97116ef4598b3/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35", size = 209614, upload-time = "2026-07-07T14:33:47.705Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/ef/2473d3c4d869155be4af1191111d59c4d5c4e0173026f7e85b176e23bf65/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8", size = 224991, upload-time = "2026-07-07T14:33:49.238Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/a3/53ddae3db108a088156aa8ddfafd411ebbc1340f48c5573f697b27f69a39/charset_normalizer-3.4.9-cp313-cp313-win32.whl", hash = "sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9", size = 150622, upload-time = "2026-07-07T14:33:50.711Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/ef/6953a77c7cf2c2ff9998e6f575ab3e380119f100223381565a4f94c1f836/charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115", size = 161947, upload-time = "2026-07-07T14:33:52.197Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/fb/d560d1d1555debbfe7849d9cac6145c1b537709d79576bf22557ed803b82/charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012", size = 152594, upload-time = "2026-07-07T14:33:53.486Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/8d/496817fa0944239ecae662dd57ea765cfeaec6a735f9f025d4b7b72e7143/charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380", size = 317253, upload-time = "2026-07-07T14:33:54.994Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/f9/ef4a69ea338ad3c0deceea0f5f7d2380ae8b52132b06d652cb0d2cd86706/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9", size = 215898, upload-time = "2026-07-07T14:33:56.334Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/e7/5ddfd76fc061eb52de219658a4aa431cbacadf0a0219c8854f00da50d289/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4", size = 236718, upload-time = "2026-07-07T14:33:57.9Z" },
+ { url = "https://files.pythonhosted.org/packages/49/ba/768fa3f36048d81c477a0ce61f813bc1454d80917ccfe550abd9f44f5e24/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a", size = 232519, upload-time = "2026-07-07T14:33:59.811Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046", size = 223143, upload-time = "2026-07-07T14:34:01.517Z" },
+ { url = "https://files.pythonhosted.org/packages/19/79/55c32d06d76ae4feafe053f061f3e3ab70bcf19f4007797ce8c3efda7830/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81", size = 206742, upload-time = "2026-07-07T14:34:03.04Z" },
+ { url = "https://files.pythonhosted.org/packages/10/e0/47c079dd82d217c807479cd59ffd30af56307ea31c108b75758970459ad3/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917", size = 219191, upload-time = "2026-07-07T14:34:04.657Z" },
+ { url = "https://files.pythonhosted.org/packages/42/ab/b9bc2e77d6b44a7e46ef62ec5cac1c9a6ba7b9135a5d560f002696ec9995/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41", size = 218328, upload-time = "2026-07-07T14:34:06.115Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/78/c9c71d599f5aa2d42bcdd35cbbd46d7f535351a57e40ff7d8e5a7e219401/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1", size = 207406, upload-time = "2026-07-07T14:34:07.554Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/39/c914445c321a845097ce4f6ac7de9a18228a77b766272125a1ce00d851eb/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf", size = 225157, upload-time = "2026-07-07T14:34:09.061Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/f2/c0d4b8508565a36bc5c624e88ed297f5b0b1095011034d7f5b83a69908b5/charset_normalizer-3.4.9-cp314-cp314-win32.whl", hash = "sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48", size = 151095, upload-time = "2026-07-07T14:34:10.901Z" },
+ { url = "https://files.pythonhosted.org/packages/49/fd/a1d26144398c67486422a72bf5812cda22cb4ccfcd95a290fb41ceb4b8e2/charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b", size = 162796, upload-time = "2026-07-07T14:34:12.47Z" },
+ { url = "https://files.pythonhosted.org/packages/20/95/d75e82f8ce9fd323ebf059c16c9aadefb22a1ecde13b7840b35835e4886c/charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519", size = 153334, upload-time = "2026-07-07T14:34:14.044Z" },
+ { url = "https://files.pythonhosted.org/packages/00/5e/17398df3a139985ba9d11ed072531986f408c8fca952835ef1ab1820c02b/charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198", size = 338848, upload-time = "2026-07-07T14:34:15.688Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/91/7253a32e86b7e1d1239b1b36ba6dd0f021a21107ab33054b53119cc083b9/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32", size = 223022, upload-time = "2026-07-07T14:34:17.248Z" },
+ { url = "https://files.pythonhosted.org/packages/cb/32/2e64bd2be10e89c61e57ebe6a93fd98ae88eb7ebe414b5121f22c96c69eb/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632", size = 241590, upload-time = "2026-07-07T14:34:18.813Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/ef/d96ec496cfea0c21db43b0ad03891308b02388d054cc902cf0e5a1ad6a88/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf", size = 239584, upload-time = "2026-07-07T14:34:20.52Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/ce/9af95f7876194bd7a14e3dfe4a4de2e0bff02666a3910d72beafd06cc297/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990", size = 230224, upload-time = "2026-07-07T14:34:22.189Z" },
+ { url = "https://files.pythonhosted.org/packages/52/94/af74dde74a3996bd959c350709bfe50e297823d70a8c1cbd54b838880863/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d", size = 212667, upload-time = "2026-07-07T14:34:23.857Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/f0/f1c4fe746c395922961b5916ed1d7d6e7d4c84851d19ed43cc89980ec953/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e", size = 227179, upload-time = "2026-07-07T14:34:25.586Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/56/6c745619ac397e8871e2bcd3cea1eec86b877488f33888b3aef5c3ed506e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c", size = 225372, upload-time = "2026-07-07T14:34:27.212Z" },
+ { url = "https://files.pythonhosted.org/packages/78/ad/98aae8630ac71f16711968e38a5acfecce41b778bf2f0312851020f565a8/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2", size = 215222, upload-time = "2026-07-07T14:34:28.774Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/40/9593d54209765207a7f11073c06494c1721e4ca4a0a426c597679bf7f91e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534", size = 231958, upload-time = "2026-07-07T14:34:30.345Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/27/693ee5e8a18191eb38647360c51cd505013e2bd3b366aa43fd5344c21e3c/charset_normalizer-3.4.9-cp314-cp314t-win32.whl", hash = "sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226", size = 155580, upload-time = "2026-07-07T14:34:31.884Z" },
+ { url = "https://files.pythonhosted.org/packages/80/3f/bd97d3d9c613013d07cb7733d299385b41df37f0471310f5a73dc359f0b8/charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177", size = 167620, upload-time = "2026-07-07T14:34:33.438Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/c6/eee9dca4439b1061f76373f06ea855678cc4a64c1c3c90b50e479edbb8eb/charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501", size = 158037, upload-time = "2026-07-07T14:34:35.018Z" },
+ { url = "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5", size = 64538, upload-time = "2026-07-07T14:34:56.993Z" },
+]
+
+[[package]]
+name = "cryptography"
+version = "49.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", size = 4032100, upload-time = "2026-06-12T20:02:32.143Z" },
+ { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" },
+ { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" },
+ { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" },
+ { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" },
+ { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" },
+ { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", size = 3810026, upload-time = "2026-06-12T20:02:39.262Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/9e/db72b3ae7fc9cfad53e630e56c6ae83b9b6ff0bf3718ffb8012d20b3aabf/cryptography-49.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:73a205dce83953d131a4aa1e0fd917a2fd1c5b1eef251e9d7152efefcbf5caf7", size = 4013892, upload-time = "2026-06-12T20:02:10.735Z" },
+ { url = "https://files.pythonhosted.org/packages/86/12/c48a424f38db03027be9f7ed5c7dc5de9933dbee992865f98b13727a009d/cryptography-49.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:196ecd6a36e4e9aa10270393bb98d8df88fccee0bf1e5128b91ae4eb4375896d", size = 4678835, upload-time = "2026-06-12T20:02:48.743Z" },
+ { url = "https://files.pythonhosted.org/packages/68/28/8a3ad4653662c93fc44dc4e5d8fd374c25c42e07b34bbfbadf49cf57a5a8/cryptography-49.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7abcee80084cda3f7691f3eb1ce480d8df49cec637b429aa35986c1de71738aa", size = 4697239, upload-time = "2026-06-12T20:02:56.03Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/b2/2193fc74f81aee4f9b62733133b73b5176718932ed8f2e4b03fa040480a6/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:4ae387c9cb68ea569ca17e490d66d8142b81c3cc814bf179974b7d146e490bbb", size = 4685593, upload-time = "2026-06-12T20:02:50.666Z" },
+ { url = "https://files.pythonhosted.org/packages/47/f1/1d3eaa243bfc5de4a187b22aa8c048b3e4980bfbe830ac46e6bac2e66947/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:f37d847238971164fdbc68ade6f6574aecc9c0af714190e2083429ff68f4ce9d", size = 5289961, upload-time = "2026-06-12T20:01:46.468Z" },
+ { url = "https://files.pythonhosted.org/packages/58/39/2d51306721330c486495853eda1c567880ff036de15a14c4b74f399934af/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:c2bc30226390d60ea19d9f82b19db005fe0452154a23c1c410c12ea801e43561", size = 4731145, upload-time = "2026-06-12T20:02:16.832Z" },
+ { url = "https://files.pythonhosted.org/packages/17/50/983e838c7fd0d87fd8c969bcdd328edaf5f756e38df5281637424c155873/cryptography-49.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:07cab27cc7b7e0fd28e5e26bb9eeedde5c135c868b46de4a27845abe94af6122", size = 4321719, upload-time = "2026-06-12T20:02:52.611Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/f5/8f571d7e27c55bce9f76f026143bcb1e040a4233149ecca0bea5fa5dd5f7/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:b20133d204d2bb56ba047642199603876c872026ca53e79c35b83772ab2cc505", size = 4685209, upload-time = "2026-06-12T20:02:07.282Z" },
+ { url = "https://files.pythonhosted.org/packages/e7/84/0e27016a6fc5a0886f797018b26aa42f40c09a82332bff77822a451deaaa/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b970c6da94d5bb18629db453d14f2a1300f6bf59b61e9b82377931ef95504866", size = 5246285, upload-time = "2026-06-12T20:01:32.439Z" },
+ { url = "https://files.pythonhosted.org/packages/11/2d/5e1fb307cb5931881516b464c98774b3f2c36b5d4bb9a2830253cf553cad/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d8ecde755e2e91bf773fc94e8c9d730cd7f2007004cb492263a794ec3899a1c8", size = 4730441, upload-time = "2026-06-12T20:02:01.469Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/c0/bff5a02ee731d207d6a1ed51732549d8c53d2bc8da1d10ec6f2844201d68/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e3fb64c420688e5319ae25113a354015abbd8dffbfbc41781a1ea66fc7622ac3", size = 4815869, upload-time = "2026-06-12T20:01:36.574Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/26/814681d14248d95d73d5c3eea0c39a94eb8302df966f670a2c60de90974b/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32703d93296f5c1f4b53349ad3a250c2cae0fdecd3a3dd5d47e616d8d616af27", size = 4960948, upload-time = "2026-06-12T20:02:18.688Z" },
+ { url = "https://files.pythonhosted.org/packages/4c/fe/93ecac273d3738939d023612ad12cca9a3740a5345d69fda04134c43fd96/cryptography-49.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:33cd0565932807baddb67b96dbee92f2c374b5c89dee09fd74079aeb8c8dba61", size = 3799153, upload-time = "2026-06-12T20:01:39.059Z" },
+ { url = "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", size = 4025947, upload-time = "2026-06-12T20:01:25.745Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" },
+ { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" },
+ { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" },
+ { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" },
+ { url = "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", size = 3785547, upload-time = "2026-06-12T20:02:26.847Z" },
+]
+
+[[package]]
+name = "github-copilot-sdk"
+version = "1.0.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "httpx" },
+ { name = "pydantic" },
+ { name = "python-dateutil" },
+]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d8/c1/a3ed7ef516e60d7847d2d51c8f4acf03e405b22afb29453d07cda898d315/github_copilot_sdk-1.0.6-py3-none-any.whl", hash = "sha256:0271ea019ebfc48c225777314925e11c1b27b48ad879cb612c935e474a893492", size = 395910, upload-time = "2026-07-08T16:00:58.853Z" },
+]
+
+[[package]]
+name = "h11"
+version = "0.16.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
+]
+
+[[package]]
+name = "httpcore"
+version = "1.0.9"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "certifi" },
+ { name = "h11" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
+]
+
+[[package]]
+name = "httpx"
+version = "0.28.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "anyio" },
+ { name = "certifi" },
+ { name = "httpcore" },
+ { name = "idna" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
+]
+
+[[package]]
+name = "idna"
+version = "3.18"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" },
+]
+
+[[package]]
+name = "markupsafe"
+version = "3.0.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" },
+ { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" },
+ { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" },
+ { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" },
+ { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" },
+ { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" },
+ { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" },
+ { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" },
+ { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" },
+ { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" },
+ { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" },
+ { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" },
+ { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" },
+ { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" },
+ { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" },
+ { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" },
+ { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" },
+ { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" },
+ { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" },
+ { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" },
+ { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
+]
+
+[[package]]
+name = "msal"
+version = "1.37.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "cryptography" },
+ { name = "pyjwt", extra = ["crypto"] },
+ { name = "requests" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/9a/99/d840198ecf6e8057bbc937f129ae940404485d736cda73253bbff9537f01/msal-1.37.0.tar.gz", hash = "sha256:1b1672a33ee467c1d70b341bb16cafd51bb3c817147a95b93263794b03971bec", size = 182444, upload-time = "2026-05-29T19:49:05.561Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/94/b0/d807279f4b55d16d1f120d5ac4344c6e39b56732e2a224d40bded7fd67ad/msal-1.37.0-py3-none-any.whl", hash = "sha256:dd17e95a7c71bce75e8108113438ba7c4a086b3bcad4f57a8c09b7af3d753c2d", size = 123725, upload-time = "2026-05-29T19:49:04.335Z" },
+]
+
+[[package]]
+name = "msal-extensions"
+version = "1.3.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "msal" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/01/99/5d239b6156eddf761a636bded1118414d161bd6b7b37a9335549ed159396/msal_extensions-1.3.1.tar.gz", hash = "sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4", size = 23315, upload-time = "2025-03-14T23:51:03.902Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5e/75/bd9b7bb966668920f06b200e84454c8f3566b102183bc55c5473d96cb2b9/msal_extensions-1.3.1-py3-none-any.whl", hash = "sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca", size = 20583, upload-time = "2025-03-14T23:51:03.016Z" },
+]
+
+[[package]]
+name = "pycparser"
+version = "3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
+]
+
+[[package]]
+name = "pydantic"
+version = "2.13.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "annotated-types" },
+ { name = "pydantic-core" },
+ { name = "typing-extensions" },
+ { name = "typing-inspection" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" },
+]
+
+[[package]]
+name = "pydantic-core"
+version = "2.46.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" },
+ { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" },
+ { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" },
+ { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" },
+ { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" },
+ { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" },
+ { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" },
+ { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" },
+ { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" },
+ { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" },
+ { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" },
+ { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" },
+ { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" },
+ { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" },
+ { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" },
+ { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" },
+ { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" },
+ { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" },
+ { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" },
+ { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" },
+ { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" },
+ { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" },
+ { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" },
+ { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" },
+ { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" },
+ { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" },
+]
+
+[[package]]
+name = "pyjwt"
+version = "2.13.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/3b/81/58d0ac84e1ef3a3843791d6954d94c0b33d526c75eeb1efbce9d0a4c4077/pyjwt-2.13.0.tar.gz", hash = "sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423", size = 107515, upload-time = "2026-05-21T19:54:36.618Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl", hash = "sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728", size = 31274, upload-time = "2026-05-21T19:54:35.362Z" },
+]
+
+[package.optional-dependencies]
+crypto = [
+ { name = "cryptography" },
+]
+
+[[package]]
+name = "python-dateutil"
+version = "2.9.0.post0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
+]
+
+[[package]]
+name = "requests"
+version = "2.34.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "certifi" },
+ { name = "charset-normalizer" },
+ { name = "idna" },
+ { name = "urllib3" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" },
+]
+
+[[package]]
+name = "simple-agent-functions-python"
+version = "1.0.0"
+source = { virtual = "." }
+dependencies = [
+ { name = "azure-functions" },
+ { name = "azure-identity" },
+ { name = "github-copilot-sdk" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "azure-functions" },
+ { name = "azure-identity" },
+ { name = "github-copilot-sdk" },
+]
+
+[[package]]
+name = "six"
+version = "1.17.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.16.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
+]
+
+[[package]]
+name = "typing-inspection"
+version = "0.4.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
+]
+
+[[package]]
+name = "urllib3"
+version = "2.7.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
+]
+
+[[package]]
+name = "werkzeug"
+version = "3.1.8"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "markupsafe" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/dd/b2/381be8cfdee792dd117872481b6e378f85c957dd7c5bca38897b08f765fd/werkzeug-3.1.8.tar.gz", hash = "sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44", size = 875852, upload-time = "2026-04-02T18:49:14.268Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/93/8c/2e650f2afeb7ee576912636c23ddb621c91ac6a98e66dc8d29c3c69446e1/werkzeug-3.1.8-py3-none-any.whl", hash = "sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50", size = 226459, upload-time = "2026-04-02T18:49:12.72Z" },
+]
From 469999ef9492092e97dc7772437d20bdc28511c0 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 01:58:25 -0700
Subject: [PATCH 04/13] Ignore generated Bicep output
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
.gitignore | 3 +
infra/main.json | 18462 ----------------------------------------------
2 files changed, 3 insertions(+), 18462 deletions(-)
delete mode 100644 infra/main.json
diff --git a/.gitignore b/.gitignore
index 3f8d142..1ccb1c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -150,3 +150,6 @@ __blobstorage__/
__queuestorage__/
__azurite_db*__.json
.python_packages/
+
+# Bicep build output
+infra/main.json
diff --git a/infra/main.json b/infra/main.json
deleted file mode 100644
index c262495..0000000
--- a/infra/main.json
+++ /dev/null
@@ -1,18462 +0,0 @@
-{
- "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "13649461923352592980"
- }
- },
- "parameters": {
- "environmentName": {
- "type": "string",
- "minLength": 1,
- "maxLength": 64,
- "metadata": {
- "description": "Name of the the environment which is used to generate a short unique hash used in all resources."
- }
- },
- "location": {
- "type": "string",
- "metadata": {
- "azd": {
- "type": "location"
- },
- "description": "Primary location for all resources & Flex Consumption Function App"
- },
- "minLength": 1
- },
- "vnetEnabled": {
- "type": "bool",
- "defaultValue": false
- },
- "apiServiceName": {
- "type": "string",
- "defaultValue": ""
- },
- "apiUserAssignedIdentityName": {
- "type": "string",
- "defaultValue": ""
- },
- "applicationInsightsName": {
- "type": "string",
- "defaultValue": ""
- },
- "appServicePlanName": {
- "type": "string",
- "defaultValue": ""
- },
- "logAnalyticsName": {
- "type": "string",
- "defaultValue": ""
- },
- "resourceGroupName": {
- "type": "string",
- "defaultValue": ""
- },
- "storageAccountName": {
- "type": "string",
- "defaultValue": ""
- },
- "principalId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional: Your Azure AD user/service principal object ID for development access. Leave empty for production. Local development should use \"azd up\" which sets this automatically."
- }
- },
- "aiProjectFriendlyName": {
- "type": "string",
- "defaultValue": "Simple AI Agent Project",
- "metadata": {
- "description": "Friendly name for your Azure AI resource"
- }
- },
- "aiProjectDescription": {
- "type": "string",
- "defaultValue": "This is a simple AI agent project for Azure Functions.",
- "metadata": {
- "description": "Description of your Azure AI resource displayed in AI studio"
- }
- },
- "enableAzureSearch": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Enable Azure AI Search for vector store and search capabilities"
- }
- },
- "aiSearchName": {
- "type": "string",
- "defaultValue": "agent-ai-search",
- "metadata": {
- "description": "Name of the Azure AI Search account"
- }
- },
- "enableCosmosDb": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Enable Cosmos DB for agent thread storage"
- }
- },
- "accountCapabilityHostName": {
- "type": "string",
- "defaultValue": "caphostacc",
- "metadata": {
- "description": "Name for capabilityHost."
- }
- },
- "projectCapabilityHostName": {
- "type": "string",
- "defaultValue": "caphostproj",
- "metadata": {
- "description": "Name for capabilityHost."
- }
- },
- "aiServicesName": {
- "type": "string",
- "defaultValue": "agent-ai-services",
- "metadata": {
- "description": "Name of the Azure AI Services account"
- }
- },
- "modelName": {
- "type": "string",
- "defaultValue": "gpt-5-mini",
- "metadata": {
- "description": "Model name for deployment"
- }
- },
- "modelFormat": {
- "type": "string",
- "defaultValue": "OpenAI",
- "metadata": {
- "description": "Model format for deployment"
- }
- },
- "modelVersion": {
- "type": "string",
- "defaultValue": "2025-08-07",
- "metadata": {
- "description": "Model version for deployment"
- }
- },
- "modelSkuName": {
- "type": "string",
- "defaultValue": "GlobalStandard",
- "metadata": {
- "description": "Model deployment SKU name"
- }
- },
- "modelCapacity": {
- "type": "int",
- "defaultValue": 50,
- "metadata": {
- "description": "Model deployment capacity"
- }
- },
- "modelDeploymentName": {
- "type": "string",
- "defaultValue": "chat",
- "metadata": {
- "description": "Name for the model deployment in Azure AI Services"
- }
- },
- "cosmosDbName": {
- "type": "string",
- "defaultValue": "agent-ai-cosmos",
- "metadata": {
- "description": "Name of the Cosmos DB account for agent thread storage"
- }
- },
- "aiServiceAccountResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "The AI Service Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- },
- "aiSearchServiceResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "The Ai Search Service full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- },
- "aiStorageAccountResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "The Ai Storage Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- },
- "aiCosmosDbAccountResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "The Cosmos DB Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- }
- },
- "variables": {
- "$fxv#0": {
- "analysisServicesServers": "as",
- "apiManagementService": "apim-",
- "appConfigurationConfigurationStores": "appcs-",
- "appManagedEnvironments": "cae-",
- "appContainerApps": "ca-",
- "authorizationPolicyDefinitions": "policy-",
- "automationAutomationAccounts": "aa-",
- "blueprintBlueprints": "bp-",
- "blueprintBlueprintsArtifacts": "bpa-",
- "cacheRedis": "redis-",
- "cdnProfiles": "cdnp-",
- "cdnProfilesEndpoints": "cdne-",
- "cognitiveServicesAccounts": "cog-",
- "cognitiveServicesFormRecognizer": "cog-fr-",
- "cognitiveServicesTextAnalytics": "cog-ta-",
- "computeAvailabilitySets": "avail-",
- "computeCloudServices": "cld-",
- "computeDiskEncryptionSets": "des",
- "computeDisks": "disk",
- "computeDisksOs": "osdisk",
- "computeGalleries": "gal",
- "computeSnapshots": "snap-",
- "computeVirtualMachines": "vm",
- "computeVirtualMachineScaleSets": "vmss-",
- "containerInstanceContainerGroups": "ci",
- "containerRegistryRegistries": "cr",
- "containerServiceManagedClusters": "aks-",
- "databricksWorkspaces": "dbw-",
- "dataFactoryFactories": "adf-",
- "dataLakeAnalyticsAccounts": "dla",
- "dataLakeStoreAccounts": "dls",
- "dataMigrationServices": "dms-",
- "dBforMySQLServers": "mysql-",
- "dBforPostgreSQLServers": "psql-",
- "devicesIotHubs": "iot-",
- "devicesProvisioningServices": "provs-",
- "devicesProvisioningServicesCertificates": "pcert-",
- "documentDBDatabaseAccounts": "cosmos-",
- "eventGridDomains": "evgd-",
- "eventGridDomainsTopics": "evgt-",
- "eventGridEventSubscriptions": "evgs-",
- "eventHubNamespaces": "evhns-",
- "eventHubNamespacesEventHubs": "evh-",
- "hdInsightClustersHadoop": "hadoop-",
- "hdInsightClustersHbase": "hbase-",
- "hdInsightClustersKafka": "kafka-",
- "hdInsightClustersMl": "mls-",
- "hdInsightClustersSpark": "spark-",
- "hdInsightClustersStorm": "storm-",
- "hybridComputeMachines": "arcs-",
- "insightsActionGroups": "ag-",
- "insightsComponents": "appi-",
- "keyVaultVaults": "kv-",
- "kubernetesConnectedClusters": "arck",
- "kustoClusters": "dec",
- "kustoClustersDatabases": "dedb",
- "logicIntegrationAccounts": "ia-",
- "logicWorkflows": "logic-",
- "machineLearningServicesWorkspaces": "mlw-",
- "managedIdentityUserAssignedIdentities": "id-",
- "managementManagementGroups": "mg-",
- "migrateAssessmentProjects": "migr-",
- "networkApplicationGateways": "agw-",
- "networkApplicationSecurityGroups": "asg-",
- "networkAzureFirewalls": "afw-",
- "networkBastionHosts": "bas-",
- "networkConnections": "con-",
- "networkDnsZones": "dnsz-",
- "networkExpressRouteCircuits": "erc-",
- "networkFirewallPolicies": "afwp-",
- "networkFirewallPoliciesWebApplication": "waf",
- "networkFirewallPoliciesRuleGroups": "wafrg",
- "networkFrontDoors": "fd-",
- "networkFrontdoorWebApplicationFirewallPolicies": "fdfp-",
- "networkLoadBalancersExternal": "lbe-",
- "networkLoadBalancersInternal": "lbi-",
- "networkLoadBalancersInboundNatRules": "rule-",
- "networkLocalNetworkGateways": "lgw-",
- "networkNatGateways": "ng-",
- "networkNetworkInterfaces": "nic-",
- "networkNetworkSecurityGroups": "nsg-",
- "networkNetworkSecurityGroupsSecurityRules": "nsgsr-",
- "networkNetworkWatchers": "nw-",
- "networkPrivateDnsZones": "pdnsz-",
- "networkPrivateLinkServices": "pl-",
- "networkPublicIPAddresses": "pip-",
- "networkPublicIPPrefixes": "ippre-",
- "networkRouteFilters": "rf-",
- "networkRouteTables": "rt-",
- "networkRouteTablesRoutes": "udr-",
- "networkTrafficManagerProfiles": "traf-",
- "networkVirtualNetworkGateways": "vgw-",
- "networkVirtualNetworks": "vnet-",
- "networkVirtualNetworksSubnets": "snet-",
- "networkVirtualNetworksVirtualNetworkPeerings": "peer-",
- "networkVirtualWans": "vwan-",
- "networkVpnGateways": "vpng-",
- "networkVpnGatewaysVpnConnections": "vcn-",
- "networkVpnGatewaysVpnSites": "vst-",
- "notificationHubsNamespaces": "ntfns-",
- "notificationHubsNamespacesNotificationHubs": "ntf-",
- "operationalInsightsWorkspaces": "log-",
- "portalDashboards": "dash-",
- "powerBIDedicatedCapacities": "pbi-",
- "purviewAccounts": "pview-",
- "recoveryServicesVaults": "rsv-",
- "resourcesResourceGroups": "rg-",
- "searchSearchServices": "srch-",
- "serviceBusNamespaces": "sb-",
- "serviceBusNamespacesQueues": "sbq-",
- "serviceBusNamespacesTopics": "sbt-",
- "serviceEndPointPolicies": "se-",
- "serviceFabricClusters": "sf-",
- "signalRServiceSignalR": "sigr",
- "sqlManagedInstances": "sqlmi-",
- "sqlServers": "sql-",
- "sqlServersDataWarehouse": "sqldw-",
- "sqlServersDatabases": "sqldb-",
- "sqlServersDatabasesStretch": "sqlstrdb-",
- "storageStorageAccounts": "st",
- "storageStorageAccountsVm": "stvm",
- "storSimpleManagers": "ssimp",
- "streamAnalyticsCluster": "asa-",
- "synapseWorkspaces": "syn",
- "synapseWorkspacesAnalyticsWorkspaces": "synw",
- "synapseWorkspacesSqlPoolsDedicated": "syndp",
- "synapseWorkspacesSqlPoolsSpark": "synsp",
- "timeSeriesInsightsEnvironments": "tsi-",
- "webServerFarms": "plan-",
- "webSitesAppService": "app-",
- "webSitesAppServiceEnvironment": "ase-",
- "webSitesFunctions": "func-",
- "webStaticSites": "stapp-"
- },
- "abbrs": "[variables('$fxv#0')]",
- "resourceToken": "[toLower(uniqueString(subscription().id, parameters('environmentName'), parameters('location')))]",
- "tags": {
- "azd-env-name": "[parameters('environmentName')]"
- },
- "functionAppName": "[if(not(empty(parameters('apiServiceName'))), parameters('apiServiceName'), format('{0}api-{1}', variables('abbrs').webSitesFunctions, variables('resourceToken')))]",
- "deploymentStorageContainerName": "[format('app-package-{0}-{1}', take(variables('functionAppName'), 32), take(toLower(uniqueString(variables('functionAppName'), variables('resourceToken'))), 7))]",
- "uniqueSuffix": "[toLower(uniqueString(subscription().id, parameters('environmentName'), parameters('location')))]",
- "projectName": "[toLower(format('{0}{1}', parameters('environmentName'), variables('uniqueSuffix')))]",
- "storageEndpointConfig": {
- "enableBlob": true,
- "enableQueue": true,
- "enableTable": false,
- "enableFiles": false,
- "allowUserIdentityPrincipal": "[not(empty(parameters('principalId')))]"
- }
- },
- "resources": [
- {
- "type": "Microsoft.Resources/resourceGroups",
- "apiVersion": "2021-04-01",
- "name": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "location": "[parameters('location')]",
- "tags": "[variables('tags')]"
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "apiUserAssignedIdentity",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[variables('tags')]"
- },
- "name": "[if(not(empty(parameters('apiUserAssignedIdentityName'))), createObject('value', parameters('apiUserAssignedIdentityName')), createObject('value', format('{0}api-{1}', variables('abbrs').managedIdentityUserAssignedIdentities, variables('resourceToken'))))]"
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.34.44.8038",
- "templateHash": "16707109626832623586"
- },
- "name": "User Assigned Identities",
- "description": "This module deploys a User Assigned Identity."
- },
- "definitions": {
- "federatedIdentityCredentialType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the federated identity credential."
- }
- },
- "audiences": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. The list of audiences that can appear in the issued token."
- }
- },
- "issuer": {
- "type": "string",
- "metadata": {
- "description": "Required. The URL of the issuer to be trusted."
- }
- },
- "subject": {
- "type": "string",
- "metadata": {
- "description": "Required. The identifier of the external identity."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true,
- "description": "The type for the federated identity credential."
- }
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a lock.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the User Assigned Identity."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all resources."
- }
- },
- "federatedIdentityCredentials": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/federatedIdentityCredentialType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The federated identity credentials list to indicate which token from the external IdP should be trusted by your application. Federated identity credentials are supported on applications only. A maximum of 20 federated identity credentials can be added per application object."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Managed Identity Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e40ec5ca-96e0-45a2-b4ff-59039f2c2b59')]",
- "Managed Identity Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f1a07417-d97a-45cb-824c-7a7467783830')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.managedidentity-userassignedidentity.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "userAssignedIdentity": {
- "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
- "apiVersion": "2024-11-30",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]"
- },
- "userAssignedIdentity_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.ManagedIdentity/userAssignedIdentities/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "userAssignedIdentity"
- ]
- },
- "userAssignedIdentity_roleAssignments": {
- "copy": {
- "name": "userAssignedIdentity_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.ManagedIdentity/userAssignedIdentities/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "userAssignedIdentity"
- ]
- },
- "userAssignedIdentity_federatedIdentityCredentials": {
- "copy": {
- "name": "userAssignedIdentity_federatedIdentityCredentials",
- "count": "[length(coalesce(parameters('federatedIdentityCredentials'), createArray()))]",
- "mode": "serial",
- "batchSize": 1
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-UserMSI-FederatedIdentityCred-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].name]"
- },
- "userAssignedIdentityName": {
- "value": "[parameters('name')]"
- },
- "audiences": {
- "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].audiences]"
- },
- "issuer": {
- "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].issuer]"
- },
- "subject": {
- "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].subject]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.34.44.8038",
- "templateHash": "13656021764446440473"
- },
- "name": "User Assigned Identity Federated Identity Credential",
- "description": "This module deploys a User Assigned Identity Federated Identity Credential."
- },
- "parameters": {
- "userAssignedIdentityName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent user assigned identity. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the secret."
- }
- },
- "audiences": {
- "type": "array",
- "metadata": {
- "description": "Required. The list of audiences that can appear in the issued token. Should be set to api://AzureADTokenExchange for Azure AD. It says what Microsoft identity platform should accept in the aud claim in the incoming token. This value represents Azure AD in your external identity provider and has no fixed value across identity providers - you might need to create a new application registration in your IdP to serve as the audience of this token."
- }
- },
- "issuer": {
- "type": "string",
- "metadata": {
- "description": "Required. The URL of the issuer to be trusted. Must match the issuer claim of the external token being exchanged."
- }
- },
- "subject": {
- "type": "string",
- "metadata": {
- "description": "Required. The identifier of the external software workload within the external identity provider. Like the audience value, it has no fixed format, as each IdP uses their own - sometimes a GUID, sometimes a colon delimited identifier, sometimes arbitrary strings. The value here must match the sub claim within the token presented to Azure AD."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials",
- "apiVersion": "2024-11-30",
- "name": "[format('{0}/{1}', parameters('userAssignedIdentityName'), parameters('name'))]",
- "properties": {
- "audiences": "[parameters('audiences')]",
- "issuer": "[parameters('issuer')]",
- "subject": "[parameters('subject')]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the federated identity credential."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the federated identity credential."
- },
- "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials', parameters('userAssignedIdentityName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the federated identity credential was created in."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "userAssignedIdentity"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the user assigned identity."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the user assigned identity."
- },
- "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name'))]"
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "The principal ID (object ID) of the user assigned identity."
- },
- "value": "[reference('userAssignedIdentity').principalId]"
- },
- "clientId": {
- "type": "string",
- "metadata": {
- "description": "The client ID (application ID) of the user assigned identity."
- },
- "value": "[reference('userAssignedIdentity').clientId]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the user assigned identity was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('userAssignedIdentity', '2024-11-30', 'full').location]"
- }
- }
- }
- },
- "dependsOn": [
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "appserviceplan",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": "[if(not(empty(parameters('appServicePlanName'))), createObject('value', parameters('appServicePlanName')), createObject('value', format('{0}{1}', variables('abbrs').webServerFarms, variables('resourceToken'))))]",
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[variables('tags')]"
- },
- "kind": {
- "value": "FunctionApp"
- },
- "sku": {
- "value": {
- "tier": "FlexConsumption",
- "name": "FC1"
- }
- },
- "reserved": {
- "value": true
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.25.53.49325",
- "templateHash": "14640671403143559618"
- },
- "name": "App Service Plan",
- "description": "This module deploys an App Service Plan.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "nullable": true
- },
- "roleAssignmentType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- }
- },
- "nullable": true
- },
- "diagnosticSettingType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of diagnostic setting."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- }
- },
- "nullable": true
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "minLength": 1,
- "maxLength": 60,
- "metadata": {
- "description": "Required. Name of the app service plan."
- }
- },
- "sku": {
- "type": "object",
- "metadata": {
- "example": " {\n name: 'P1v3'\n tier: 'Premium'\n size: 'P1v3'\n family: 'P'\n capacity: 3\n }\n ",
- "description": "Required. Defines the name, tier, size, family and capacity of the App Service Plan."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all resources."
- }
- },
- "kind": {
- "type": "string",
- "defaultValue": "App",
- "allowedValues": [
- "App",
- "Elastic",
- "FunctionApp",
- "Windows",
- "Linux"
- ],
- "metadata": {
- "description": "Optional. Kind of server OS."
- }
- },
- "reserved": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Conditional. Defaults to false when creating Windows/app App Service Plan. Required if creating a Linux App Service Plan and must be set to true."
- }
- },
- "appServiceEnvironmentId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The Resource ID of the App Service Environment to use for the App Service Plan."
- }
- },
- "workerTierName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Target worker tier assigned to the App Service plan."
- }
- },
- "perSiteScaling": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. If true, apps assigned to this App Service plan can be scaled independently. If false, apps assigned to this App Service plan will scale to all instances of the plan."
- }
- },
- "maximumElasticWorkerCount": {
- "type": "int",
- "defaultValue": 1,
- "metadata": {
- "description": "Optional. Maximum number of total workers allowed for this ElasticScaleEnabled App Service Plan."
- }
- },
- "targetWorkerCount": {
- "type": "int",
- "defaultValue": 0,
- "metadata": {
- "description": "Optional. Scaling worker count."
- }
- },
- "targetWorkerSize": {
- "type": "int",
- "defaultValue": 0,
- "allowedValues": [
- 0,
- 1,
- 2
- ],
- "metadata": {
- "description": "Optional. The instance size of the hosting plan (small, medium, or large)."
- }
- },
- "zoneRedundant": {
- "type": "bool",
- "defaultValue": "[if(or(equals(parameters('sku').tier, 'Premium'), equals(parameters('sku').tier, 'ElasticPremium')), true(), false())]",
- "metadata": {
- "description": "Optional. Zone Redundancy can only be used on Premium or ElasticPremium SKU Tiers within ZRS Supported regions (https://learn.microsoft.com/en-us/azure/storage/common/redundancy-regions-zrs)."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "roleAssignments": {
- "$ref": "#/definitions/roleAssignmentType",
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "diagnosticSettings": {
- "$ref": "#/definitions/diagnosticSettingType",
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- }
- },
- "variables": {
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]",
- "Web Plan Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b')]",
- "Website Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2023-07-01",
- "name": "[format('46d3xbcp.res.web-serverfarm.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "appServicePlan": {
- "type": "Microsoft.Web/serverfarms",
- "apiVersion": "2022-09-01",
- "name": "[parameters('name')]",
- "kind": "[parameters('kind')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "sku": "[parameters('sku')]",
- "properties": {
- "workerTierName": "[parameters('workerTierName')]",
- "hostingEnvironmentProfile": "[if(not(empty(parameters('appServiceEnvironmentId'))), createObject('id', parameters('appServiceEnvironmentId')), null())]",
- "perSiteScaling": "[parameters('perSiteScaling')]",
- "maximumElasticWorkerCount": "[parameters('maximumElasticWorkerCount')]",
- "reserved": "[parameters('reserved')]",
- "targetWorkerCount": "[parameters('targetWorkerCount')]",
- "targetWorkerSizeId": "[parameters('targetWorkerSize')]",
- "zoneRedundant": "[parameters('zoneRedundant')]"
- }
- },
- "appServicePlan_diagnosticSettings": {
- "copy": {
- "name": "appServicePlan_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Web/serverfarms/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "appServicePlan"
- ]
- },
- "appServicePlan_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Web/serverfarms/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "appServicePlan"
- ]
- },
- "appServicePlan_roleAssignments": {
- "copy": {
- "name": "appServicePlan_roleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Web/serverfarms/{0}', parameters('name'))]",
- "name": "[guid(resourceId('Microsoft.Web/serverfarms', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]",
- "properties": {
- "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]",
- "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "appServicePlan"
- ]
- }
- },
- "outputs": {
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the app service plan was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the app service plan."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the app service plan."
- },
- "value": "[resourceId('Microsoft.Web/serverfarms', parameters('name'))]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('appServicePlan', '2022-09-01', 'full').location]"
- }
- }
- }
- },
- "dependsOn": [
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "storage",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": "[if(not(empty(parameters('storageAccountName'))), createObject('value', parameters('storageAccountName')), createObject('value', format('{0}{1}', variables('abbrs').storageStorageAccounts, variables('resourceToken'))))]",
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[variables('tags')]"
- },
- "kind": {
- "value": "StorageV2"
- },
- "skuName": {
- "value": "Standard_LRS"
- },
- "allowBlobPublicAccess": {
- "value": false
- },
- "allowSharedKeyAccess": {
- "value": false
- },
- "publicNetworkAccess": {
- "value": "Enabled"
- },
- "networkAcls": {
- "value": {
- "bypass": "AzureServices",
- "defaultAction": "Allow"
- }
- },
- "blobServices": {
- "value": {
- "containers": [
- {
- "name": "[variables('deploymentStorageContainerName')]"
- }
- ]
- }
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "4784214957784927668"
- },
- "name": "Storage Accounts",
- "description": "This module deploys a Storage Account.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "networkAclsType": {
- "type": "object",
- "properties": {
- "resourceAccessRules": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "tenantId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of the tenant in which the resource resides in."
- }
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource ID of the target service. Can also contain a wildcard, if multiple services e.g. in a resource group should be included."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Sets the resource access rules. Array entries must consist of \"tenantId\" and \"resourceId\" fields only."
- }
- },
- "bypass": {
- "type": "string",
- "allowedValues": [
- "AzureServices",
- "AzureServices, Logging",
- "AzureServices, Logging, Metrics",
- "AzureServices, Metrics",
- "Logging",
- "Logging, Metrics",
- "Metrics",
- "None"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, \"Logging, Metrics\"), or None to bypass none of those traffics."
- }
- },
- "virtualNetworkRules": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Sets the virtual network rules."
- }
- },
- "ipRules": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Sets the IP ACL rules."
- }
- },
- "defaultAction": {
- "type": "string",
- "allowedValues": [
- "Allow",
- "Deny"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specifies the default action of allow or deny when no other rules match."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "secretsExportConfigurationType": {
- "type": "object",
- "properties": {
- "keyVaultResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The key vault name where to store the keys and connection strings generated by the modules."
- }
- },
- "accessKey1": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The accessKey1 secret name to create."
- }
- },
- "connectionString1": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The connectionString1 secret name to create."
- }
- },
- "accessKey2": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The accessKey2 secret name to create."
- }
- },
- "connectionString2": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The connectionString2 secret name to create."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "_1.privateEndpointCustomDnsConfigType": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. A list of private IP addresses of the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "_1.privateEndpointIpConfigurationType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource that is unique within a resource group."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to."
- }
- },
- "memberName": {
- "type": "string",
- "metadata": {
- "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to."
- }
- },
- "privateIPAddress": {
- "type": "string",
- "metadata": {
- "description": "Required. A private IP address obtained from the private endpoint's subnet."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private endpoint IP configurations."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "_1.privateEndpointPrivateDnsZoneGroupType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private DNS Zone Group."
- }
- },
- "privateDnsZoneGroupConfigs": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS Zone Group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- }
- },
- "metadata": {
- "description": "Required. The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "_1.secretSetOutputType": {
- "type": "object",
- "properties": {
- "secretResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resourceId of the exported secret."
- }
- },
- "secretUri": {
- "type": "string",
- "metadata": {
- "description": "The secret URI of the exported secret."
- }
- },
- "secretUriWithVersion": {
- "type": "string",
- "metadata": {
- "description": "The secret URI with version of the exported secret."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "customerManagedKeyType": {
- "type": "object",
- "properties": {
- "keyVaultResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from."
- }
- },
- "keyName": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the customer managed key to use for encryption."
- }
- },
- "keyVersion": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'."
- }
- },
- "userAssignedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a customer-managed key.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "diagnosticSettingFullType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a lock.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "managedIdentityAllType": {
- "type": "object",
- "properties": {
- "systemAssigned": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enables system assigned managed identity on the resource."
- }
- },
- "userAssignedResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "privateEndpointMultiServiceType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private endpoint."
- }
- },
- "location": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The location to deploy the private endpoint to."
- }
- },
- "privateLinkServiceConnectionName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private link connection to create."
- }
- },
- "service": {
- "type": "string",
- "metadata": {
- "description": "Required. The subresource to deploy the private endpoint for. For example \"blob\", \"table\", \"queue\" or \"file\" for a Storage Account's Private Endpoints."
- }
- },
- "subnetResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
- }
- },
- "privateDnsZoneGroup": {
- "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The private DNS zone group to configure for the private endpoint."
- }
- },
- "isManualConnection": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. If Manual Private Link Connection is required."
- }
- },
- "manualConnectionRequestMessage": {
- "type": "string",
- "nullable": true,
- "maxLength": 140,
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with the manual connection request."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Custom DNS configurations."
- }
- },
- "ipConfigurations": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/_1.privateEndpointIpConfigurationType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
- }
- },
- "applicationSecurityGroupResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Application security groups in which the private endpoint IP configuration is included."
- }
- },
- "customNetworkInterfaceName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The custom name of the network interface attached to the private endpoint."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to be applied on all resources/resource groups in this deployment."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "resourceGroupName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can NOT be assumed (i.e., for services that have more than one subresource, like Storage Account with Blob (blob, table, queue, file, ...).",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "secretsOutputType": {
- "type": "object",
- "properties": {},
- "additionalProperties": {
- "$ref": "#/definitions/_1.secretSetOutputType",
- "metadata": {
- "description": "An exported secret's references."
- }
- },
- "metadata": {
- "description": "A map of the exported secrets",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Required. Name of the Storage Account. Must be lower-case."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all resources."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "managedIdentities": {
- "$ref": "#/definitions/managedIdentityAllType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The managed identity definition for this resource."
- }
- },
- "kind": {
- "type": "string",
- "defaultValue": "StorageV2",
- "allowedValues": [
- "Storage",
- "StorageV2",
- "BlobStorage",
- "FileStorage",
- "BlockBlobStorage"
- ],
- "metadata": {
- "description": "Optional. Type of Storage Account to create."
- }
- },
- "skuName": {
- "type": "string",
- "defaultValue": "Standard_GRS",
- "allowedValues": [
- "Standard_LRS",
- "Standard_GRS",
- "Standard_RAGRS",
- "Standard_ZRS",
- "Premium_LRS",
- "Premium_ZRS",
- "Standard_GZRS",
- "Standard_RAGZRS"
- ],
- "metadata": {
- "description": "Optional. Storage Account Sku Name."
- }
- },
- "accessTier": {
- "type": "string",
- "defaultValue": "Hot",
- "allowedValues": [
- "Premium",
- "Hot",
- "Cool"
- ],
- "metadata": {
- "description": "Conditional. Required if the Storage Account kind is set to BlobStorage. The access tier is used for billing. The \"Premium\" access tier is the default value for premium block blobs storage account type and it cannot be changed for the premium block blobs storage account type."
- }
- },
- "largeFileSharesState": {
- "type": "string",
- "defaultValue": "Disabled",
- "allowedValues": [
- "Disabled",
- "Enabled"
- ],
- "metadata": {
- "description": "Optional. Allow large file shares if sets to 'Enabled'. It cannot be disabled once it is enabled. Only supported on locally redundant and zone redundant file shares. It cannot be set on FileStorage storage accounts (storage accounts for premium file shares)."
- }
- },
- "azureFilesIdentityBasedAuthentication": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Provides the identity based authentication settings for Azure Files."
- }
- },
- "defaultToOAuthAuthentication": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. A boolean flag which indicates whether the default authentication is OAuth or not."
- }
- },
- "allowSharedKeyAccess": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Azure Active Directory (Azure AD). The default value is null, which is equivalent to true."
- }
- },
- "privateEndpoints": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateEndpointMultiServiceType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible."
- }
- },
- "managementPolicyRules": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Storage Account ManagementPolicies Rules."
- }
- },
- "networkAcls": {
- "$ref": "#/definitions/networkAclsType",
- "nullable": true,
- "metadata": {
- "description": "Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny."
- }
- },
- "requireInfrastructureEncryption": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. A Boolean indicating whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest. For security reasons, it is recommended to set it to true."
- }
- },
- "allowCrossTenantReplication": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Allow or disallow cross AAD tenant object replication."
- }
- },
- "customDomainName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Sets the custom domain name assigned to the storage account. Name is the CNAME source."
- }
- },
- "customDomainUseSubDomainName": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Indicates whether indirect CName validation is enabled. This should only be set on updates."
- }
- },
- "dnsEndpointType": {
- "type": "string",
- "defaultValue": "",
- "allowedValues": [
- "",
- "AzureDnsZone",
- "Standard"
- ],
- "metadata": {
- "description": "Optional. Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier."
- }
- },
- "blobServices": {
- "type": "object",
- "defaultValue": "[if(not(equals(parameters('kind'), 'FileStorage')), createObject('containerDeleteRetentionPolicyEnabled', true(), 'containerDeleteRetentionPolicyDays', 7, 'deleteRetentionPolicyEnabled', true(), 'deleteRetentionPolicyDays', 6), createObject())]",
- "metadata": {
- "description": "Optional. Blob service and containers to deploy."
- }
- },
- "fileServices": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. File service and shares to deploy."
- }
- },
- "queueServices": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Queue service and queues to create."
- }
- },
- "tableServices": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Table service and tables to create."
- }
- },
- "allowBlobPublicAccess": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false."
- }
- },
- "minimumTlsVersion": {
- "type": "string",
- "defaultValue": "TLS1_2",
- "allowedValues": [
- "TLS1_2",
- "TLS1_3"
- ],
- "metadata": {
- "description": "Optional. Set the minimum TLS version on request to storage. The TLS versions 1.0 and 1.1 are deprecated and not supported anymore."
- }
- },
- "enableHierarchicalNamespace": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Conditional. If true, enables Hierarchical Namespace for the storage account. Required if enableSftp or enableNfsV3 is set to true."
- }
- },
- "enableSftp": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. If true, enables Secure File Transfer Protocol for the storage account. Requires enableHierarchicalNamespace to be true."
- }
- },
- "localUsers": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. Local users to deploy for SFTP authentication."
- }
- },
- "isLocalUserEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Enables local users feature, if set to true."
- }
- },
- "enableNfsV3": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true."
- }
- },
- "diagnosticSettings": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/diagnosticSettingFullType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "allowedCopyScope": {
- "type": "string",
- "defaultValue": "",
- "allowedValues": [
- "",
- "AAD",
- "PrivateLink"
- ],
- "metadata": {
- "description": "Optional. Restrict copy to and from Storage Accounts within an AAD tenant or with Private Links to the same VNet."
- }
- },
- "publicNetworkAccess": {
- "type": "string",
- "defaultValue": "",
- "allowedValues": [
- "",
- "Enabled",
- "Disabled"
- ],
- "metadata": {
- "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set."
- }
- },
- "supportsHttpsTrafficOnly": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Allows HTTPS traffic only to storage service if sets to true."
- }
- },
- "customerManagedKey": {
- "$ref": "#/definitions/customerManagedKeyType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The customer managed key definition."
- }
- },
- "sasExpirationPeriod": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The SAS expiration period. DD.HH:MM:SS."
- }
- },
- "keyType": {
- "type": "string",
- "nullable": true,
- "allowedValues": [
- "Account",
- "Service"
- ],
- "metadata": {
- "description": "Optional. The keyType to use with Queue & Table services."
- }
- },
- "secretsExportConfiguration": {
- "$ref": "#/definitions/secretsExportConfigurationType",
- "nullable": true,
- "metadata": {
- "description": "Optional. Key vault reference and secret settings for the module's secrets export."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "supportsBlobService": "[or(or(or(equals(parameters('kind'), 'BlockBlobStorage'), equals(parameters('kind'), 'BlobStorage')), equals(parameters('kind'), 'StorageV2')), equals(parameters('kind'), 'Storage'))]",
- "supportsFileService": "[or(or(equals(parameters('kind'), 'FileStorage'), equals(parameters('kind'), 'StorageV2')), equals(parameters('kind'), 'Storage'))]",
- "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]",
- "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]",
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]",
- "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]",
- "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]",
- "Storage Blob Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]",
- "Storage Blob Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]",
- "Storage Blob Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')]",
- "Storage Blob Delegator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a')]",
- "Storage File Data Privileged Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69566ab7-960f-475b-8e7c-b3118f30c6bd')]",
- "Storage File Data Privileged Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b8eda974-7b85-4f76-af95-65846b26df6d')]",
- "Storage File Data SMB Share Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb')]",
- "Storage File Data SMB Share Elevated Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7')]",
- "Storage File Data SMB Share Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314')]",
- "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]",
- "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]",
- "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]",
- "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]",
- "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]",
- "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "cMKKeyVault::cMKKey": {
- "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]",
- "existing": true,
- "type": "Microsoft.KeyVault/vaults/keys",
- "apiVersion": "2023-02-01",
- "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]",
- "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]",
- "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]",
- "dependsOn": [
- "cMKKeyVault"
- ]
- },
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.storage-storageaccount.{0}.{1}', replace('0.14.3', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "cMKKeyVault": {
- "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]",
- "existing": true,
- "type": "Microsoft.KeyVault/vaults",
- "apiVersion": "2023-02-01",
- "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]",
- "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]",
- "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]"
- },
- "cMKUserAssignedIdentity": {
- "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]",
- "existing": true,
- "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
- "apiVersion": "2023-01-31",
- "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]",
- "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]",
- "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]"
- },
- "storageAccount": {
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-05-01",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "kind": "[parameters('kind')]",
- "sku": {
- "name": "[parameters('skuName')]"
- },
- "identity": "[variables('identity')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "allowSharedKeyAccess": "[parameters('allowSharedKeyAccess')]",
- "defaultToOAuthAuthentication": "[parameters('defaultToOAuthAuthentication')]",
- "allowCrossTenantReplication": "[parameters('allowCrossTenantReplication')]",
- "allowedCopyScope": "[if(not(empty(parameters('allowedCopyScope'))), parameters('allowedCopyScope'), null())]",
- "customDomain": {
- "name": "[parameters('customDomainName')]",
- "useSubDomainName": "[parameters('customDomainUseSubDomainName')]"
- },
- "dnsEndpointType": "[if(not(empty(parameters('dnsEndpointType'))), parameters('dnsEndpointType'), null())]",
- "isLocalUserEnabled": "[parameters('isLocalUserEnabled')]",
- "encryption": "[union(createObject('keySource', if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage'), 'services', createObject('blob', if(variables('supportsBlobService'), createObject('enabled', true()), null()), 'file', if(variables('supportsFileService'), createObject('enabled', true()), null()), 'table', createObject('enabled', true(), 'keyType', parameters('keyType')), 'queue', createObject('enabled', true(), 'keyType', parameters('keyType'))), 'keyvaultproperties', if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')))), null()), 'identity', createObject('userAssignedIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null()))), if(parameters('requireInfrastructureEncryption'), createObject('requireInfrastructureEncryption', if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())), createObject()))]",
- "accessTier": "[if(and(not(equals(parameters('kind'), 'Storage')), not(equals(parameters('kind'), 'BlockBlobStorage'))), parameters('accessTier'), null())]",
- "sasPolicy": "[if(not(empty(parameters('sasExpirationPeriod'))), createObject('expirationAction', 'Log', 'sasExpirationPeriod', parameters('sasExpirationPeriod')), null())]",
- "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]",
- "isHnsEnabled": "[parameters('enableHierarchicalNamespace')]",
- "isSftpEnabled": "[parameters('enableSftp')]",
- "isNfsV3Enabled": "[if(parameters('enableNfsV3'), parameters('enableNfsV3'), '')]",
- "largeFileSharesState": "[if(or(equals(parameters('skuName'), 'Standard_LRS'), equals(parameters('skuName'), 'Standard_ZRS')), parameters('largeFileSharesState'), null())]",
- "minimumTlsVersion": "[parameters('minimumTlsVersion')]",
- "networkAcls": "[if(not(empty(parameters('networkAcls'))), union(createObject('resourceAccessRules', tryGet(parameters('networkAcls'), 'resourceAccessRules'), 'defaultAction', coalesce(tryGet(parameters('networkAcls'), 'defaultAction'), 'Deny'), 'virtualNetworkRules', tryGet(parameters('networkAcls'), 'virtualNetworkRules'), 'ipRules', tryGet(parameters('networkAcls'), 'ipRules')), if(contains(parameters('networkAcls'), 'bypass'), createObject('bypass', tryGet(parameters('networkAcls'), 'bypass')), createObject())), createObject('bypass', 'AzureServices', 'defaultAction', 'Deny'))]",
- "allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]",
- "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkAcls'))), 'Disabled', null()))]",
- "azureFilesIdentityBasedAuthentication": "[if(not(empty(parameters('azureFilesIdentityBasedAuthentication'))), parameters('azureFilesIdentityBasedAuthentication'), null())]"
- },
- "dependsOn": [
- "cMKKeyVault",
- "cMKUserAssignedIdentity"
- ]
- },
- "storageAccount_diagnosticSettings": {
- "copy": {
- "name": "storageAccount_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_roleAssignments": {
- "copy": {
- "name": "storageAccount_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_privateEndpoints": {
- "copy": {
- "name": "storageAccount_privateEndpoints",
- "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-storageAccount-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex()))]"
- },
- "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), createObject('value', null()))]",
- "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
- "subnetResourceId": {
- "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]"
- },
- "enableTelemetry": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]"
- },
- "location": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]"
- },
- "lock": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]"
- },
- "privateDnsZoneGroup": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]"
- },
- "roleAssignments": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]"
- },
- "tags": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
- },
- "customDnsConfigs": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]"
- },
- "ipConfigurations": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]"
- },
- "applicationSecurityGroupResourceIds": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]"
- },
- "customNetworkInterfaceName": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "1277254088602407590"
- },
- "name": "Private Endpoints",
- "description": "This module deploys a Private Endpoint.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "privateDnsZoneGroupType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private DNS Zone Group."
- }
- },
- "privateDnsZoneGroupConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateDnsZoneGroupConfigType"
- },
- "metadata": {
- "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones."
- }
- }
- }
- },
- "roleAssignmentType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- }
- },
- "nullable": true
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "nullable": true
- },
- "ipConfigurationsType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource that is unique within a resource group."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "memberName": {
- "type": "string",
- "metadata": {
- "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "privateIPAddress": {
- "type": "string",
- "metadata": {
- "description": "Required. A private IP address obtained from the private endpoint's subnet."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private endpoint IP configurations."
- }
- }
- }
- },
- "nullable": true
- },
- "manualPrivateLinkServiceConnectionsType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the private link service connection."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
- }
- },
- "privateLinkServiceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of private link service."
- }
- },
- "requestMessage": {
- "type": "string",
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private link service connection."
- }
- }
- }
- },
- "nullable": true
- },
- "privateLinkServiceConnectionsType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the private link service connection."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
- }
- },
- "privateLinkServiceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of private link service."
- }
- },
- "requestMessage": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private link service connection."
- }
- }
- }
- },
- "nullable": true
- },
- "customDnsConfigType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "metadata": {
- "description": "Required. Fqdn that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. A list of private IP addresses of the private endpoint."
- }
- }
- }
- },
- "nullable": true
- },
- "privateDnsZoneGroupConfigType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS zone group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "private-dns-zone-group/main.bicep"
- }
- }
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the private endpoint resource to create."
- }
- },
- "subnetResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
- }
- },
- "applicationSecurityGroupResourceIds": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Application security groups in which the private endpoint IP configuration is included."
- }
- },
- "customNetworkInterfaceName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The custom name of the network interface attached to the private endpoint."
- }
- },
- "ipConfigurations": {
- "$ref": "#/definitions/ipConfigurationsType",
- "metadata": {
- "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
- }
- },
- "privateDnsZoneGroup": {
- "$ref": "#/definitions/privateDnsZoneGroupType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The private DNS zone group to configure for the private endpoint."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "roleAssignments": {
- "$ref": "#/definitions/roleAssignmentType",
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to be applied on all resources/resource groups in this deployment."
- }
- },
- "customDnsConfigs": {
- "$ref": "#/definitions/customDnsConfigType",
- "metadata": {
- "description": "Optional. Custom DNS configurations."
- }
- },
- "manualPrivateLinkServiceConnections": {
- "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType",
- "metadata": {
- "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource."
- }
- },
- "privateLinkServiceConnections": {
- "$ref": "#/definitions/privateLinkServiceConnectionsType",
- "metadata": {
- "description": "Optional. A grouping of information about the connection to the remote resource."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]",
- "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]",
- "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]",
- "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]",
- "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "privateEndpoint": {
- "type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2023-11-01",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "copy": [
- {
- "name": "applicationSecurityGroups",
- "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]",
- "input": {
- "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]"
- }
- }
- ],
- "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]",
- "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]",
- "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]",
- "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]",
- "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]",
- "subnet": {
- "id": "[parameters('subnetResourceId')]"
- }
- }
- },
- "privateEndpoint_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- },
- "privateEndpoint_roleAssignments": {
- "copy": {
- "name": "privateEndpoint_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- },
- "privateEndpoint_privateDnsZoneGroup": {
- "condition": "[not(empty(parameters('privateDnsZoneGroup')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]"
- },
- "privateEndpointName": {
- "value": "[parameters('name')]"
- },
- "privateDnsZoneConfigs": {
- "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "5805178546717255803"
- },
- "name": "Private Endpoint Private DNS Zone Groups",
- "description": "This module deploys a Private Endpoint Private DNS Zone Group.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "privateDnsZoneGroupConfigType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS zone group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- }
- },
- "parameters": {
- "privateEndpointName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment."
- }
- },
- "privateDnsZoneConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateDnsZoneGroupConfigType"
- },
- "minLength": 1,
- "maxLength": 5,
- "metadata": {
- "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones."
- }
- },
- "name": {
- "type": "string",
- "defaultValue": "default",
- "metadata": {
- "description": "Optional. The name of the private DNS zone group."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "privateDnsZoneConfigsVar",
- "count": "[length(parameters('privateDnsZoneConfigs'))]",
- "input": {
- "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]",
- "properties": {
- "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]"
- }
- }
- }
- ]
- },
- "resources": {
- "privateEndpoint": {
- "existing": true,
- "type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2023-11-01",
- "name": "[parameters('privateEndpointName')]"
- },
- "privateDnsZoneGroup": {
- "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
- "apiVersion": "2023-11-01",
- "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]",
- "properties": {
- "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]"
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint DNS zone group."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint DNS zone group."
- },
- "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the private endpoint DNS zone group was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- }
- },
- "outputs": {
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the private endpoint was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint."
- },
- "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint."
- },
- "value": "[parameters('name')]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]"
- },
- "customDnsConfig": {
- "$ref": "#/definitions/customDnsConfigType",
- "metadata": {
- "description": "The custom DNS configurations of the private endpoint."
- },
- "value": "[reference('privateEndpoint').customDnsConfigs]"
- },
- "networkInterfaceIds": {
- "type": "array",
- "metadata": {
- "description": "The IDs of the network interfaces associated with the private endpoint."
- },
- "value": "[reference('privateEndpoint').networkInterfaces]"
- },
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "The group Id for the private endpoint Group."
- },
- "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_managementPolicies": {
- "condition": "[not(empty(coalesce(parameters('managementPolicyRules'), createArray())))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Storage-ManagementPolicies', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('name')]"
- },
- "rules": {
- "value": "[coalesce(parameters('managementPolicyRules'), createArray())]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "16749766572958481061"
- },
- "name": "Storage Account Management Policies",
- "description": "This module deploys a Storage Account Management Policy.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "rules": {
- "type": "array",
- "metadata": {
- "description": "Required. The Storage Account ManagementPolicies Rules."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Storage/storageAccounts/managementPolicies",
- "apiVersion": "2023-01-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]",
- "properties": {
- "policy": {
- "rules": "[parameters('rules')]"
- }
- }
- }
- ],
- "outputs": {
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed management policy."
- },
- "value": "default"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed management policy."
- },
- "value": "default"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed management policy."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount",
- "storageAccount_blobServices"
- ]
- },
- "storageAccount_localUsers": {
- "copy": {
- "name": "storageAccount_localUsers",
- "count": "[length(parameters('localUsers'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Storage-LocalUsers-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[parameters('localUsers')[copyIndex()].name]"
- },
- "hasSshKey": {
- "value": "[parameters('localUsers')[copyIndex()].hasSshKey]"
- },
- "hasSshPassword": {
- "value": "[parameters('localUsers')[copyIndex()].hasSshPassword]"
- },
- "permissionScopes": {
- "value": "[parameters('localUsers')[copyIndex()].permissionScopes]"
- },
- "hasSharedKey": {
- "value": "[tryGet(parameters('localUsers')[copyIndex()], 'hasSharedKey')]"
- },
- "homeDirectory": {
- "value": "[tryGet(parameters('localUsers')[copyIndex()], 'homeDirectory')]"
- },
- "sshAuthorizedKeys": {
- "value": "[tryGet(parameters('localUsers')[copyIndex()], 'sshAuthorizedKeys')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "4771770611168248415"
- },
- "name": "Storage Account Local Users",
- "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "sshAuthorizedKeysType": {
- "type": "secureObject",
- "properties": {
- "secureList": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Description used to store the function/usage of the key."
- }
- },
- "key": {
- "type": "string",
- "metadata": {
- "description": "Required. SSH public key base64 encoded. The format should be: '{keyType} {keyData}', e.g. ssh-rsa AAAABBBB."
- }
- }
- }
- },
- "metadata": {
- "description": "Optional. The list of SSH authorized keys."
- }
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the local user used for SFTP Authentication."
- }
- },
- "hasSharedKey": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Indicates whether shared key exists. Set it to false to remove existing shared key."
- }
- },
- "hasSshKey": {
- "type": "bool",
- "metadata": {
- "description": "Required. Indicates whether SSH key exists. Set it to false to remove existing SSH key."
- }
- },
- "hasSshPassword": {
- "type": "bool",
- "metadata": {
- "description": "Required. Indicates whether SSH password exists. Set it to false to remove existing SSH password."
- }
- },
- "homeDirectory": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The local user home directory."
- }
- },
- "permissionScopes": {
- "type": "array",
- "metadata": {
- "description": "Required. The permission scopes of the local user."
- }
- },
- "sshAuthorizedKeys": {
- "$ref": "#/definitions/sshAuthorizedKeysType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The local user SSH authorized keys for SFTP."
- }
- }
- },
- "resources": {
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-04-01",
- "name": "[parameters('storageAccountName')]"
- },
- "localUsers": {
- "type": "Microsoft.Storage/storageAccounts/localUsers",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]",
- "properties": {
- "hasSharedKey": "[parameters('hasSharedKey')]",
- "hasSshKey": "[parameters('hasSshKey')]",
- "hasSshPassword": "[parameters('hasSshPassword')]",
- "homeDirectory": "[parameters('homeDirectory')]",
- "permissionScopes": "[parameters('permissionScopes')]",
- "sshAuthorizedKeys": "[tryGet(parameters('sshAuthorizedKeys'), 'secureList')]"
- },
- "dependsOn": [
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed local user."
- },
- "value": "[parameters('name')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed local user."
- },
- "value": "[resourceGroup().name]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed local user."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/localUsers', parameters('storageAccountName'), parameters('name'))]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_blobServices": {
- "condition": "[not(empty(parameters('blobServices')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Storage-BlobServices', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('name')]"
- },
- "containers": {
- "value": "[tryGet(parameters('blobServices'), 'containers')]"
- },
- "automaticSnapshotPolicyEnabled": {
- "value": "[tryGet(parameters('blobServices'), 'automaticSnapshotPolicyEnabled')]"
- },
- "changeFeedEnabled": {
- "value": "[tryGet(parameters('blobServices'), 'changeFeedEnabled')]"
- },
- "changeFeedRetentionInDays": {
- "value": "[tryGet(parameters('blobServices'), 'changeFeedRetentionInDays')]"
- },
- "containerDeleteRetentionPolicyEnabled": {
- "value": "[tryGet(parameters('blobServices'), 'containerDeleteRetentionPolicyEnabled')]"
- },
- "containerDeleteRetentionPolicyDays": {
- "value": "[tryGet(parameters('blobServices'), 'containerDeleteRetentionPolicyDays')]"
- },
- "containerDeleteRetentionPolicyAllowPermanentDelete": {
- "value": "[tryGet(parameters('blobServices'), 'containerDeleteRetentionPolicyAllowPermanentDelete')]"
- },
- "corsRules": {
- "value": "[tryGet(parameters('blobServices'), 'corsRules')]"
- },
- "defaultServiceVersion": {
- "value": "[tryGet(parameters('blobServices'), 'defaultServiceVersion')]"
- },
- "deleteRetentionPolicyAllowPermanentDelete": {
- "value": "[tryGet(parameters('blobServices'), 'deleteRetentionPolicyAllowPermanentDelete')]"
- },
- "deleteRetentionPolicyEnabled": {
- "value": "[tryGet(parameters('blobServices'), 'deleteRetentionPolicyEnabled')]"
- },
- "deleteRetentionPolicyDays": {
- "value": "[tryGet(parameters('blobServices'), 'deleteRetentionPolicyDays')]"
- },
- "isVersioningEnabled": {
- "value": "[tryGet(parameters('blobServices'), 'isVersioningEnabled')]"
- },
- "lastAccessTimeTrackingPolicyEnabled": {
- "value": "[tryGet(parameters('blobServices'), 'lastAccessTimeTrackingPolicyEnabled')]"
- },
- "restorePolicyEnabled": {
- "value": "[tryGet(parameters('blobServices'), 'restorePolicyEnabled')]"
- },
- "restorePolicyDays": {
- "value": "[tryGet(parameters('blobServices'), 'restorePolicyDays')]"
- },
- "diagnosticSettings": {
- "value": "[tryGet(parameters('blobServices'), 'diagnosticSettings')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "12420339026638684809"
- },
- "name": "Storage Account blob Services",
- "description": "This module deploys a Storage Account Blob Service.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "diagnosticSettingFullType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "automaticSnapshotPolicyEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Automatic Snapshot is enabled if set to true."
- }
- },
- "changeFeedEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. The blob service properties for change feed events. Indicates whether change feed event logging is enabled for the Blob service."
- }
- },
- "changeFeedRetentionInDays": {
- "type": "int",
- "nullable": true,
- "minValue": 1,
- "maxValue": 146000,
- "metadata": {
- "description": "Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. If left blank, it indicates an infinite retention of the change feed."
- }
- },
- "containerDeleteRetentionPolicyEnabled": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. The blob service properties for container soft delete. Indicates whether DeleteRetentionPolicy is enabled."
- }
- },
- "containerDeleteRetentionPolicyDays": {
- "type": "int",
- "nullable": true,
- "minValue": 1,
- "maxValue": 365,
- "metadata": {
- "description": "Optional. Indicates the number of days that the deleted item should be retained."
- }
- },
- "containerDeleteRetentionPolicyAllowPermanentDelete": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. This property when set to true allows deletion of the soft deleted blob versions and snapshots. This property cannot be used with blob restore policy. This property only applies to blob service and does not apply to containers or file share."
- }
- },
- "corsRules": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. Specifies CORS rules for the Blob service. You can include up to five CorsRule elements in the request. If no CorsRule elements are included in the request body, all CORS rules will be deleted, and CORS will be disabled for the Blob service."
- }
- },
- "defaultServiceVersion": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Indicates the default version to use for requests to the Blob service if an incoming request's version is not specified. Possible values include version 2008-10-27 and all more recent versions."
- }
- },
- "deleteRetentionPolicyEnabled": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. The blob service properties for blob soft delete."
- }
- },
- "deleteRetentionPolicyDays": {
- "type": "int",
- "defaultValue": 7,
- "minValue": 1,
- "maxValue": 365,
- "metadata": {
- "description": "Optional. Indicates the number of days that the deleted blob should be retained."
- }
- },
- "deleteRetentionPolicyAllowPermanentDelete": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. This property when set to true allows deletion of the soft deleted blob versions and snapshots. This property cannot be used with blob restore policy. This property only applies to blob service and does not apply to containers or file share."
- }
- },
- "isVersioningEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Use versioning to automatically maintain previous versions of your blobs."
- }
- },
- "lastAccessTimeTrackingPolicyEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. The blob service property to configure last access time based tracking policy. When set to true last access time based tracking is enabled."
- }
- },
- "restorePolicyEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. The blob service properties for blob restore policy. If point-in-time restore is enabled, then versioning, change feed, and blob soft delete must also be enabled."
- }
- },
- "restorePolicyDays": {
- "type": "int",
- "defaultValue": 6,
- "minValue": 1,
- "metadata": {
- "description": "Optional. How long this blob can be restored. It should be less than DeleteRetentionPolicy days."
- }
- },
- "containers": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Blob containers to create."
- }
- },
- "diagnosticSettings": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/diagnosticSettingFullType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- }
- },
- "variables": {
- "name": "default"
- },
- "resources": {
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2022-09-01",
- "name": "[parameters('storageAccountName')]"
- },
- "blobServices": {
- "type": "Microsoft.Storage/storageAccounts/blobServices",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]",
- "properties": {
- "automaticSnapshotPolicyEnabled": "[parameters('automaticSnapshotPolicyEnabled')]",
- "changeFeed": "[if(parameters('changeFeedEnabled'), createObject('enabled', true(), 'retentionInDays', parameters('changeFeedRetentionInDays')), null())]",
- "containerDeleteRetentionPolicy": {
- "enabled": "[parameters('containerDeleteRetentionPolicyEnabled')]",
- "days": "[parameters('containerDeleteRetentionPolicyDays')]",
- "allowPermanentDelete": "[if(equals(parameters('containerDeleteRetentionPolicyEnabled'), true()), parameters('containerDeleteRetentionPolicyAllowPermanentDelete'), null())]"
- },
- "cors": {
- "corsRules": "[parameters('corsRules')]"
- },
- "defaultServiceVersion": "[if(not(empty(parameters('defaultServiceVersion'))), parameters('defaultServiceVersion'), null())]",
- "deleteRetentionPolicy": {
- "enabled": "[parameters('deleteRetentionPolicyEnabled')]",
- "days": "[parameters('deleteRetentionPolicyDays')]",
- "allowPermanentDelete": "[if(and(parameters('deleteRetentionPolicyEnabled'), parameters('deleteRetentionPolicyAllowPermanentDelete')), true(), null())]"
- },
- "isVersioningEnabled": "[parameters('isVersioningEnabled')]",
- "lastAccessTimeTrackingPolicy": "[if(not(equals(reference('storageAccount', '2022-09-01', 'full').kind, 'Storage')), createObject('enable', parameters('lastAccessTimeTrackingPolicyEnabled'), 'name', if(equals(parameters('lastAccessTimeTrackingPolicyEnabled'), true()), 'AccessTimeTracking', null()), 'trackingGranularityInDays', if(equals(parameters('lastAccessTimeTrackingPolicyEnabled'), true()), 1, null())), null())]",
- "restorePolicy": "[if(parameters('restorePolicyEnabled'), createObject('enabled', true(), 'days', parameters('restorePolicyDays')), null())]"
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "blobServices_diagnosticSettings": {
- "copy": {
- "name": "blobServices_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', parameters('storageAccountName'), variables('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "blobServices"
- ]
- },
- "blobServices_container": {
- "copy": {
- "name": "blobServices_container",
- "count": "[length(coalesce(parameters('containers'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Container-{1}', deployment().name, copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('storageAccountName')]"
- },
- "blobServiceName": {
- "value": "[variables('name')]"
- },
- "name": {
- "value": "[coalesce(parameters('containers'), createArray())[copyIndex()].name]"
- },
- "defaultEncryptionScope": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'defaultEncryptionScope')]"
- },
- "denyEncryptionScopeOverride": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'denyEncryptionScopeOverride')]"
- },
- "enableNfsV3AllSquash": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'enableNfsV3AllSquash')]"
- },
- "enableNfsV3RootSquash": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'enableNfsV3RootSquash')]"
- },
- "immutableStorageWithVersioningEnabled": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'immutableStorageWithVersioningEnabled')]"
- },
- "metadata": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'metadata')]"
- },
- "publicAccess": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'publicAccess')]"
- },
- "roleAssignments": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'roleAssignments')]"
- },
- "immutabilityPolicyProperties": {
- "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'immutabilityPolicyProperties')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "2340678191837281561"
- },
- "name": "Storage Account Blob Containers",
- "description": "This module deploys a Storage Account Blob Container.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "blobServiceName": {
- "type": "string",
- "defaultValue": "default",
- "metadata": {
- "description": "Optional. The name of the parent Blob Service. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the storage container to deploy."
- }
- },
- "defaultEncryptionScope": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Default the container to use specified encryption scope for all writes."
- }
- },
- "denyEncryptionScopeOverride": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Block override of encryption scope from the container default."
- }
- },
- "enableNfsV3AllSquash": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Enable NFSv3 all squash on blob container."
- }
- },
- "enableNfsV3RootSquash": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Enable NFSv3 root squash on blob container."
- }
- },
- "immutableStorageWithVersioningEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. This is an immutable property, when set to true it enables object level immutability at the container level. The property is immutable and can only be set to true at the container creation time. Existing containers must undergo a migration process."
- }
- },
- "immutabilityPolicyName": {
- "type": "string",
- "defaultValue": "default",
- "metadata": {
- "description": "Optional. Name of the immutable policy."
- }
- },
- "immutabilityPolicyProperties": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Configure immutability policy."
- }
- },
- "metadata": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. A name-value pair to associate with the container as metadata."
- }
- },
- "publicAccess": {
- "type": "string",
- "defaultValue": "None",
- "allowedValues": [
- "Container",
- "Blob",
- "None"
- ],
- "metadata": {
- "description": "Optional. Specifies whether data in the container may be accessed publicly and the level of access."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]",
- "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]",
- "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]",
- "Storage Blob Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]",
- "Storage Blob Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]",
- "Storage Blob Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')]",
- "Storage Blob Delegator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "storageAccount::blobServices": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts/blobServices",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('blobServiceName'))]",
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2022-09-01",
- "name": "[parameters('storageAccountName')]"
- },
- "container": {
- "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), parameters('blobServiceName'), parameters('name'))]",
- "properties": {
- "defaultEncryptionScope": "[if(not(empty(parameters('defaultEncryptionScope'))), parameters('defaultEncryptionScope'), null())]",
- "denyEncryptionScopeOverride": "[if(equals(parameters('denyEncryptionScopeOverride'), true()), parameters('denyEncryptionScopeOverride'), null())]",
- "enableNfsV3AllSquash": "[if(equals(parameters('enableNfsV3AllSquash'), true()), parameters('enableNfsV3AllSquash'), null())]",
- "enableNfsV3RootSquash": "[if(equals(parameters('enableNfsV3RootSquash'), true()), parameters('enableNfsV3RootSquash'), null())]",
- "immutableStorageWithVersioning": "[if(equals(parameters('immutableStorageWithVersioningEnabled'), true()), createObject('enabled', parameters('immutableStorageWithVersioningEnabled')), null())]",
- "metadata": "[parameters('metadata')]",
- "publicAccess": "[parameters('publicAccess')]"
- },
- "dependsOn": [
- "storageAccount::blobServices"
- ]
- },
- "container_roleAssignments": {
- "copy": {
- "name": "container_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}/containers/{2}', parameters('storageAccountName'), parameters('blobServiceName'), parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), parameters('blobServiceName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "container"
- ]
- },
- "immutabilityPolicy": {
- "condition": "[not(empty(coalesce(parameters('immutabilityPolicyProperties'), createObject())))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[parameters('immutabilityPolicyName')]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('storageAccountName')]"
- },
- "containerName": {
- "value": "[parameters('name')]"
- },
- "immutabilityPeriodSinceCreationInDays": {
- "value": "[tryGet(parameters('immutabilityPolicyProperties'), 'immutabilityPeriodSinceCreationInDays')]"
- },
- "allowProtectedAppendWrites": {
- "value": "[tryGet(parameters('immutabilityPolicyProperties'), 'allowProtectedAppendWrites')]"
- },
- "allowProtectedAppendWritesAll": {
- "value": "[tryGet(parameters('immutabilityPolicyProperties'), 'allowProtectedAppendWritesAll')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "17642721918788484059"
- },
- "name": "Storage Account Blob Container Immutability Policies",
- "description": "This module deploys a Storage Account Blob Container Immutability Policy.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "containerName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent container to apply the policy to. Required if the template is used in a standalone deployment."
- }
- },
- "immutabilityPeriodSinceCreationInDays": {
- "type": "int",
- "defaultValue": 365,
- "metadata": {
- "description": "Optional. The immutability period for the blobs in the container since the policy creation, in days."
- }
- },
- "allowProtectedAppendWrites": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. This property can only be changed for unlocked time-based retention policies. When enabled, new blocks can be written to an append blob while maintaining immutability protection and compliance. Only new blocks can be added and any existing blocks cannot be modified or deleted. This property cannot be changed with ExtendImmutabilityPolicy API."
- }
- },
- "allowProtectedAppendWritesAll": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. This property can only be changed for unlocked time-based retention policies. When enabled, new blocks can be written to both \"Append and Block Blobs\" while maintaining immutability protection and compliance. Only new blocks can be added and any existing blocks cannot be modified or deleted. This property cannot be changed with ExtendImmutabilityPolicy API. The \"allowProtectedAppendWrites\" and \"allowProtectedAppendWritesAll\" properties are mutually exclusive."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}/{1}/{2}/{3}', parameters('storageAccountName'), 'default', parameters('containerName'), 'default')]",
- "properties": {
- "immutabilityPeriodSinceCreationInDays": "[parameters('immutabilityPeriodSinceCreationInDays')]",
- "allowProtectedAppendWrites": "[parameters('allowProtectedAppendWrites')]",
- "allowProtectedAppendWritesAll": "[parameters('allowProtectedAppendWritesAll')]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed immutability policy."
- },
- "value": "default"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed immutability policy."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies', parameters('storageAccountName'), 'default', parameters('containerName'), 'default')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed immutability policy."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "container",
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed container."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed container."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), parameters('blobServiceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed container."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "blobServices",
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed blob service."
- },
- "value": "[variables('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed blob service."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccountName'), variables('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed blob service."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_fileServices": {
- "condition": "[not(empty(parameters('fileServices')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Storage-FileServices', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('name')]"
- },
- "diagnosticSettings": {
- "value": "[tryGet(parameters('fileServices'), 'diagnosticSettings')]"
- },
- "protocolSettings": {
- "value": "[tryGet(parameters('fileServices'), 'protocolSettings')]"
- },
- "shareDeleteRetentionPolicy": {
- "value": "[tryGet(parameters('fileServices'), 'shareDeleteRetentionPolicy')]"
- },
- "shares": {
- "value": "[tryGet(parameters('fileServices'), 'shares')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "11334292387756483860"
- },
- "name": "Storage Account File Share Services",
- "description": "This module deploys a Storage Account File Share Service.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "diagnosticSettingFullType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "defaultValue": "default",
- "metadata": {
- "description": "Optional. The name of the file service."
- }
- },
- "protocolSettings": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Protocol settings for file service."
- }
- },
- "shareDeleteRetentionPolicy": {
- "type": "object",
- "defaultValue": {
- "enabled": true,
- "days": 7
- },
- "metadata": {
- "description": "Optional. The service properties for soft delete."
- }
- },
- "diagnosticSettings": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/diagnosticSettingFullType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- },
- "shares": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. File shares to create."
- }
- }
- },
- "resources": {
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-04-01",
- "name": "[parameters('storageAccountName')]"
- },
- "fileServices": {
- "type": "Microsoft.Storage/storageAccounts/fileServices",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]",
- "properties": {
- "protocolSettings": "[parameters('protocolSettings')]",
- "shareDeleteRetentionPolicy": "[parameters('shareDeleteRetentionPolicy')]"
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "fileServices_diagnosticSettings": {
- "copy": {
- "name": "fileServices_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}/fileServices/{1}', parameters('storageAccountName'), parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "fileServices"
- ]
- },
- "fileServices_shares": {
- "copy": {
- "name": "fileServices_shares",
- "count": "[length(coalesce(parameters('shares'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-shares-{1}', deployment().name, copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('storageAccountName')]"
- },
- "fileServicesName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[coalesce(parameters('shares'), createArray())[copyIndex()].name]"
- },
- "accessTier": {
- "value": "[coalesce(tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'accessTier'), if(equals(reference('storageAccount', '2023-04-01', 'full').kind, 'FileStorage'), 'Premium', 'TransactionOptimized'))]"
- },
- "enabledProtocols": {
- "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'enabledProtocols')]"
- },
- "rootSquash": {
- "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'rootSquash')]"
- },
- "shareQuota": {
- "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'shareQuota')]"
- },
- "roleAssignments": {
- "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'roleAssignments')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "6729752654389555660"
- },
- "name": "Storage Account File Shares",
- "description": "This module deploys a Storage Account File Share.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "fileServicesName": {
- "type": "string",
- "defaultValue": "default",
- "metadata": {
- "description": "Conditional. The name of the parent file service. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the file share to create."
- }
- },
- "accessTier": {
- "type": "string",
- "defaultValue": "TransactionOptimized",
- "allowedValues": [
- "Premium",
- "Hot",
- "Cool",
- "TransactionOptimized"
- ],
- "metadata": {
- "description": "Conditional. Access tier for specific share. Required if the Storage Account kind is set to FileStorage (should be set to \"Premium\"). GpV2 account can choose between TransactionOptimized (default), Hot, and Cool."
- }
- },
- "shareQuota": {
- "type": "int",
- "defaultValue": 5120,
- "metadata": {
- "description": "Optional. The maximum size of the share, in gigabytes. Must be greater than 0, and less than or equal to 5120 (5TB). For Large File Shares, the maximum size is 102400 (100TB)."
- }
- },
- "enabledProtocols": {
- "type": "string",
- "defaultValue": "SMB",
- "allowedValues": [
- "NFS",
- "SMB"
- ],
- "metadata": {
- "description": "Optional. The authentication protocol that is used for the file share. Can only be specified when creating a share."
- }
- },
- "rootSquash": {
- "type": "string",
- "defaultValue": "NoRootSquash",
- "allowedValues": [
- "AllSquash",
- "NoRootSquash",
- "RootSquash"
- ],
- "metadata": {
- "description": "Optional. Permissions for NFS file shares are enforced by the client OS rather than the Azure Files service. Toggling the root squash behavior reduces the rights of the root user for NFS shares."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- }
- },
- "resources": {
- "storageAccount::fileService": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts/fileServices",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('fileServicesName'))]",
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-04-01",
- "name": "[parameters('storageAccountName')]"
- },
- "fileShare": {
- "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
- "apiVersion": "2023-01-01",
- "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), parameters('fileServicesName'), parameters('name'))]",
- "properties": {
- "accessTier": "[parameters('accessTier')]",
- "shareQuota": "[parameters('shareQuota')]",
- "rootSquash": "[if(equals(parameters('enabledProtocols'), 'NFS'), parameters('rootSquash'), null())]",
- "enabledProtocols": "[parameters('enabledProtocols')]"
- },
- "dependsOn": [
- "storageAccount::fileService"
- ]
- },
- "fileShare_roleAssignments": {
- "condition": "[not(empty(parameters('roleAssignments')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Share-Rbac', uniqueString(deployment().name))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "fileShareResourceId": {
- "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', parameters('storageAccountName'), parameters('fileServicesName'), parameters('name'))]"
- },
- "roleAssignments": {
- "value": "[parameters('roleAssignments')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "11498628270290452072"
- }
- },
- "parameters": {
- "roleAssignments": {
- "type": "array",
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "fileShareResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the file share to assign the roles to."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "$fxv#0": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "parameters": {
- "scope": {
- "type": "string",
- "metadata": {
- "description": "Required. The scope to deploy the role assignment to."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the role assignment."
- }
- },
- "roleDefinitionId": {
- "type": "string",
- "metadata": {
- "description": "Required. The role definition Id to assign."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User",
- ""
- ],
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\""
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "defaultValue": "2.0",
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[[parameters('scope')]",
- "name": "[[parameters('name')]",
- "properties": {
- "roleDefinitionId": "[[parameters('roleDefinitionId')]",
- "principalId": "[[parameters('principalId')]",
- "description": "[[parameters('description')]",
- "principalType": "[[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]",
- "condition": "[[if(not(empty(parameters('condition'))), parameters('condition'), null())]",
- "conditionVersion": "[[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]",
- "delegatedManagedIdentityResourceId": "[[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]"
- }
- }
- ]
- },
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]",
- "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]",
- "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]",
- "Storage File Data SMB Share Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb')]",
- "Storage File Data SMB Share Elevated Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7')]",
- "Storage File Data SMB Share Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": [
- {
- "copy": {
- "name": "fileShare_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2021-04-01",
- "name": "[format('{0}-Share-Rbac-{1}', uniqueString(deployment().name), copyIndex())]",
- "properties": {
- "mode": "Incremental",
- "expressionEvaluationOptions": {
- "scope": "Outer"
- },
- "template": "[variables('$fxv#0')]",
- "parameters": {
- "scope": {
- "value": "[replace(parameters('fileShareResourceId'), '/shares/', '/fileShares/')]"
- },
- "name": {
- "value": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(parameters('fileShareResourceId'), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId, 'tyfa'))]"
- },
- "roleDefinitionId": {
- "value": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]"
- },
- "principalId": {
- "value": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]"
- },
- "principalType": {
- "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]"
- },
- "description": {
- "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]"
- },
- "condition": {
- "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]"
- },
- "conditionVersion": {
- "value": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]"
- },
- "delegatedManagedIdentityResourceId": {
- "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- }
- }
- }
- }
- ]
- }
- },
- "dependsOn": [
- "fileShare"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed file share."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed file share."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', parameters('storageAccountName'), parameters('fileServicesName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed file share."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "fileServices",
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed file share service."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed file share service."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', parameters('storageAccountName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed file share service."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_queueServices": {
- "condition": "[not(empty(parameters('queueServices')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Storage-QueueServices', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('name')]"
- },
- "diagnosticSettings": {
- "value": "[tryGet(parameters('queueServices'), 'diagnosticSettings')]"
- },
- "queues": {
- "value": "[tryGet(parameters('queueServices'), 'queues')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "8427226755569651235"
- },
- "name": "Storage Account Queue Services",
- "description": "This module deploys a Storage Account Queue Service.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "diagnosticSettingFullType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "queues": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Queues to create."
- }
- },
- "diagnosticSettings": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/diagnosticSettingFullType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- }
- },
- "variables": {
- "name": "default"
- },
- "resources": {
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-04-01",
- "name": "[parameters('storageAccountName')]"
- },
- "queueServices": {
- "type": "Microsoft.Storage/storageAccounts/queueServices",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]",
- "properties": {},
- "dependsOn": [
- "storageAccount"
- ]
- },
- "queueServices_diagnosticSettings": {
- "copy": {
- "name": "queueServices_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}', parameters('storageAccountName'), variables('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "queueServices"
- ]
- },
- "queueServices_queues": {
- "copy": {
- "name": "queueServices_queues",
- "count": "[length(coalesce(parameters('queues'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Queue-{1}', deployment().name, copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('storageAccountName')]"
- },
- "name": {
- "value": "[coalesce(parameters('queues'), createArray())[copyIndex()].name]"
- },
- "metadata": {
- "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'metadata')]"
- },
- "roleAssignments": {
- "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'roleAssignments')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "17434851913053254324"
- },
- "name": "Storage Account Queues",
- "description": "This module deploys a Storage Account Queue.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the storage queue to deploy."
- }
- },
- "metadata": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. A name-value pair that represents queue metadata."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]",
- "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]",
- "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]",
- "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]",
- "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]",
- "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]",
- "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "storageAccount::queueServices": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts/queueServices",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]",
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-04-01",
- "name": "[parameters('storageAccountName')]"
- },
- "queue": {
- "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]",
- "properties": {
- "metadata": "[parameters('metadata')]"
- },
- "dependsOn": [
- "storageAccount::queueServices"
- ]
- },
- "queue_roleAssignments": {
- "copy": {
- "name": "queue_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}/queues/{2}', parameters('storageAccountName'), 'default', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "queue"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed queue."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed queue."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed queue."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed file share service."
- },
- "value": "[variables('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed file share service."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccountName'), variables('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed file share service."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount_tableServices": {
- "condition": "[not(empty(parameters('tableServices')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Storage-TableServices', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[parameters('name')]"
- },
- "diagnosticSettings": {
- "value": "[tryGet(parameters('tableServices'), 'diagnosticSettings')]"
- },
- "tables": {
- "value": "[tryGet(parameters('tableServices'), 'tables')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "8854918982965924242"
- },
- "name": "Storage Account Table Services",
- "description": "This module deploys a Storage Account Table Service.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "diagnosticSettingFullType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "tables": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. tables to create."
- }
- },
- "diagnosticSettings": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/diagnosticSettingFullType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- }
- },
- "variables": {
- "name": "default"
- },
- "resources": {
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-04-01",
- "name": "[parameters('storageAccountName')]"
- },
- "tableServices": {
- "type": "Microsoft.Storage/storageAccounts/tableServices",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]",
- "properties": {},
- "dependsOn": [
- "storageAccount"
- ]
- },
- "tableServices_diagnosticSettings": {
- "copy": {
- "name": "tableServices_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}', parameters('storageAccountName'), variables('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "tableServices"
- ]
- },
- "tableServices_tables": {
- "copy": {
- "name": "tableServices_tables",
- "count": "[length(parameters('tables'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Table-{1}', deployment().name, copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[parameters('tables')[copyIndex()].name]"
- },
- "storageAccountName": {
- "value": "[parameters('storageAccountName')]"
- },
- "roleAssignments": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'roleAssignments')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "14487041808457984428"
- },
- "name": "Storage Account Table",
- "description": "This module deploys a Storage Account Table.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string",
- "maxLength": 24,
- "metadata": {
- "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the table."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]",
- "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]",
- "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]",
- "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]",
- "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "storageAccount::tableServices": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts/tableServices",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]",
- "dependsOn": [
- "storageAccount"
- ]
- },
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-04-01",
- "name": "[parameters('storageAccountName')]"
- },
- "table": {
- "type": "Microsoft.Storage/storageAccounts/tableServices/tables",
- "apiVersion": "2023-04-01",
- "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]",
- "dependsOn": [
- "storageAccount::tableServices"
- ]
- },
- "table_roleAssignments": {
- "copy": {
- "name": "table_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}/tables/{2}', parameters('storageAccountName'), 'default', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "table"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed file share service."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed file share service."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed file share service."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed table service."
- },
- "value": "[variables('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed table service."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccountName'), variables('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed table service."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- },
- "secretsExport": {
- "condition": "[not(equals(parameters('secretsExportConfiguration'), null()))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-secrets-kv', uniqueString(deployment().name, parameters('location')))]",
- "subscriptionId": "[split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '//'), '/')[2]]",
- "resourceGroup": "[split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '////'), '/')[4]]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "keyVaultName": {
- "value": "[last(split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '//'), '/'))]"
- },
- "secretsToSet": {
- "value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'accessKey1'), createArray(createObject('name', parameters('secretsExportConfiguration').accessKey1, 'value', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[0].value)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'connectionString1'), createArray(createObject('name', parameters('secretsExportConfiguration').connectionString1, 'value', format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix=core.windows.net', parameters('name'), listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[0].value))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'accessKey2'), createArray(createObject('name', parameters('secretsExportConfiguration').accessKey2, 'value', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[1].value)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'connectionString2'), createArray(createObject('name', parameters('secretsExportConfiguration').connectionString2, 'value', format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix=core.windows.net', parameters('name'), listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[1].value))), createArray()))]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "13337765828606873307"
- }
- },
- "definitions": {
- "secretSetOutputType": {
- "type": "object",
- "properties": {
- "secretResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resourceId of the exported secret."
- }
- },
- "secretUri": {
- "type": "string",
- "metadata": {
- "description": "The secret URI of the exported secret."
- }
- },
- "secretUriWithVersion": {
- "type": "string",
- "metadata": {
- "description": "The secret URI with version of the exported secret."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- },
- "secretToSetType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the secret to set."
- }
- },
- "value": {
- "type": "securestring",
- "metadata": {
- "description": "Required. The value of the secret to set."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for the secret to set via the secrets export feature.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1"
- }
- }
- }
- },
- "parameters": {
- "keyVaultName": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the Key Vault to set the ecrets in."
- }
- },
- "secretsToSet": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/secretToSetType"
- },
- "metadata": {
- "description": "Required. The secrets to set in the Key Vault."
- }
- }
- },
- "resources": {
- "keyVault": {
- "existing": true,
- "type": "Microsoft.KeyVault/vaults",
- "apiVersion": "2022-07-01",
- "name": "[parameters('keyVaultName')]"
- },
- "secrets": {
- "copy": {
- "name": "secrets",
- "count": "[length(parameters('secretsToSet'))]"
- },
- "type": "Microsoft.KeyVault/vaults/secrets",
- "apiVersion": "2023-07-01",
- "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('secretsToSet')[copyIndex()].name)]",
- "properties": {
- "value": "[parameters('secretsToSet')[copyIndex()].value]"
- },
- "dependsOn": [
- "keyVault"
- ]
- }
- },
- "outputs": {
- "secretsSet": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/secretSetOutputType"
- },
- "metadata": {
- "description": "The references to the secrets exported to the provided Key Vault."
- },
- "copy": {
- "count": "[length(range(0, length(coalesce(parameters('secretsToSet'), createArray()))))]",
- "input": {
- "secretResourceId": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretsToSet')[range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()]].name)]",
- "secretUri": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUri]",
- "secretUriWithVersion": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUriWithVersion]"
- }
- }
- }
- }
- }
- },
- "dependsOn": [
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed storage account."
- },
- "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('name'))]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed storage account."
- },
- "value": "[parameters('name')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed storage account."
- },
- "value": "[resourceGroup().name]"
- },
- "primaryBlobEndpoint": {
- "type": "string",
- "metadata": {
- "description": "The primary blob endpoint reference if blob services are deployed."
- },
- "value": "[if(and(not(empty(parameters('blobServices'))), contains(parameters('blobServices'), 'containers')), reference(format('Microsoft.Storage/storageAccounts/{0}', parameters('name')), '2019-04-01').primaryEndpoints.blob, '')]"
- },
- "systemAssignedMIPrincipalId": {
- "type": "string",
- "metadata": {
- "description": "The principal ID of the system assigned identity."
- },
- "value": "[coalesce(tryGet(tryGet(reference('storageAccount', '2023-05-01', 'full'), 'identity'), 'principalId'), '')]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('storageAccount', '2023-05-01', 'full').location]"
- },
- "serviceEndpoints": {
- "type": "object",
- "metadata": {
- "description": "All service endpoints of the deployed storage account, Note Standard_LRS and Standard_ZRS accounts only have a blob service endpoint."
- },
- "value": "[reference('storageAccount').primaryEndpoints]"
- },
- "privateEndpoints": {
- "type": "array",
- "metadata": {
- "description": "The private endpoints of the Storage Account."
- },
- "copy": {
- "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]",
- "input": {
- "name": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.name.value]",
- "resourceId": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]",
- "groupId": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]",
- "customDnsConfig": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]",
- "networkInterfaceIds": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]"
- }
- }
- },
- "exportedSecrets": {
- "$ref": "#/definitions/secretsOutputType",
- "metadata": {
- "description": "A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret's name."
- },
- "value": "[if(not(equals(parameters('secretsExportConfiguration'), null())), toObject(reference('secretsExport').outputs.secretsSet.value, lambda('secret', last(split(lambdaVariables('secret').secretResourceId, '/'))), lambda('secret', lambdaVariables('secret'))), createObject())]"
- }
- }
- }
- },
- "dependsOn": [
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "monitoring",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "logAnalyticsName": "[if(not(empty(parameters('logAnalyticsName'))), createObject('value', parameters('logAnalyticsName')), createObject('value', format('{0}{1}', variables('abbrs').operationalInsightsWorkspaces, variables('resourceToken'))))]",
- "applicationInsightsName": "[if(not(empty(parameters('applicationInsightsName'))), createObject('value', parameters('applicationInsightsName')), createObject('value', format('{0}{1}', variables('abbrs').insightsComponents, variables('resourceToken'))))]",
- "applicationInsightsDashboardName": {
- "value": ""
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[variables('tags')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.30.23.60470",
- "templateHash": "10958835295881470966"
- },
- "name": "Azd Azure Monitoring",
- "description": "Creates an Application Insights instance and a Log Analytics workspace.\n\n**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "logAnalyticsName": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource operational insights workspaces name."
- }
- },
- "applicationInsightsName": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource insights components name."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "applicationInsightsDashboardName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The resource portal dashboards name."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ",
- "description": "Optional. Tags of the resource."
- }
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.ptn.azd-monitoring.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "logAnalytics": {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "loganalytics",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[parameters('logAnalyticsName')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[parameters('tags')]"
- },
- "dataRetention": {
- "value": 30
- },
- "enableTelemetry": {
- "value": "[parameters('enableTelemetry')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "11627784326487264389"
- },
- "name": "Log Analytics Workspaces",
- "description": "This module deploys a Log Analytics Workspace.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "managedIdentitiesType": {
- "type": "object",
- "properties": {
- "systemAssigned": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enables system assigned managed identity on the resource."
- }
- },
- "userAssignedResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID(s) to assign to the resource."
- }
- }
- },
- "nullable": true
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "nullable": true
- },
- "roleAssignmentType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- }
- },
- "nullable": true
- },
- "diagnosticSettingType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "useThisWorkspace": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Instead of using an external reference, use the deployed instance as the target for its diagnostic settings. If set to `true`, the `workspaceResourceId` property is ignored."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- }
- },
- "nullable": true
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the Log Analytics workspace."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all resources."
- }
- },
- "skuName": {
- "type": "string",
- "defaultValue": "PerGB2018",
- "allowedValues": [
- "CapacityReservation",
- "Free",
- "LACluster",
- "PerGB2018",
- "PerNode",
- "Premium",
- "Standalone",
- "Standard"
- ],
- "metadata": {
- "description": "Optional. The name of the SKU."
- }
- },
- "skuCapacityReservationLevel": {
- "type": "int",
- "defaultValue": 100,
- "minValue": 100,
- "maxValue": 5000,
- "metadata": {
- "description": "Optional. The capacity reservation level in GB for this workspace, when CapacityReservation sku is selected. Must be in increments of 100 between 100 and 5000."
- }
- },
- "storageInsightsConfigs": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. List of storage accounts to be read by the workspace."
- }
- },
- "linkedServices": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. List of services to be linked."
- }
- },
- "linkedStorageAccounts": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Conditional. List of Storage Accounts to be linked. Required if 'forceCmkForQuery' is set to 'true' and 'savedSearches' is not empty."
- }
- },
- "savedSearches": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. Kusto Query Language searches to save."
- }
- },
- "dataExports": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. LAW data export instances to be deployed."
- }
- },
- "dataSources": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. LAW data sources to configure."
- }
- },
- "tables": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. LAW custom tables to be deployed."
- }
- },
- "gallerySolutions": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. List of gallerySolutions to be created in the log analytics workspace."
- }
- },
- "dataRetention": {
- "type": "int",
- "defaultValue": 365,
- "minValue": 0,
- "maxValue": 730,
- "metadata": {
- "description": "Optional. Number of days data will be retained for."
- }
- },
- "dailyQuotaGb": {
- "type": "int",
- "defaultValue": -1,
- "minValue": -1,
- "metadata": {
- "description": "Optional. The workspace daily quota for ingestion."
- }
- },
- "publicNetworkAccessForIngestion": {
- "type": "string",
- "defaultValue": "Enabled",
- "allowedValues": [
- "Enabled",
- "Disabled"
- ],
- "metadata": {
- "description": "Optional. The network access type for accessing Log Analytics ingestion."
- }
- },
- "publicNetworkAccessForQuery": {
- "type": "string",
- "defaultValue": "Enabled",
- "allowedValues": [
- "Enabled",
- "Disabled"
- ],
- "metadata": {
- "description": "Optional. The network access type for accessing Log Analytics query."
- }
- },
- "managedIdentities": {
- "$ref": "#/definitions/managedIdentitiesType",
- "metadata": {
- "description": "Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both."
- }
- },
- "useResourcePermissions": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Set to 'true' to use resource or workspace permissions and 'false' (or leave empty) to require workspace permissions."
- }
- },
- "diagnosticSettings": {
- "$ref": "#/definitions/diagnosticSettingType",
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- },
- "forceCmkForQuery": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Indicates whether customer managed storage is mandatory for query management."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "roleAssignments": {
- "$ref": "#/definitions/roleAssignmentType",
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]",
- "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), 'SystemAssigned', if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]",
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]",
- "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]",
- "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]",
- "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "Security Admin": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb1c8493-542b-48eb-b624-b4c8fea62acd')]",
- "Security Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '39bc4728-0917-49c7-9d2c-d95423bc2eb4')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.operationalinsights-workspace.{0}.{1}', replace('0.7.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "logAnalyticsWorkspace": {
- "type": "Microsoft.OperationalInsights/workspaces",
- "apiVersion": "2022-10-01",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "features": {
- "searchVersion": 1,
- "enableLogAccessUsingOnlyResourcePermissions": "[parameters('useResourcePermissions')]"
- },
- "sku": {
- "name": "[parameters('skuName')]",
- "capacityReservationLevel": "[if(equals(parameters('skuName'), 'CapacityReservation'), parameters('skuCapacityReservationLevel'), null())]"
- },
- "retentionInDays": "[parameters('dataRetention')]",
- "workspaceCapping": {
- "dailyQuotaGb": "[parameters('dailyQuotaGb')]"
- },
- "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]",
- "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]",
- "forceCmkForQuery": "[parameters('forceCmkForQuery')]"
- },
- "identity": "[variables('identity')]"
- },
- "logAnalyticsWorkspace_diagnosticSettings": {
- "copy": {
- "name": "logAnalyticsWorkspace_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[if(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'useThisWorkspace'), false()), resourceId('Microsoft.OperationalInsights/workspaces', parameters('name')), tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId'))]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_roleAssignments": {
- "copy": {
- "name": "logAnalyticsWorkspace_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.OperationalInsights/workspaces', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_storageInsightConfigs": {
- "copy": {
- "name": "logAnalyticsWorkspace_storageInsightConfigs",
- "count": "[length(parameters('storageInsightsConfigs'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-StorageInsightsConfig-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "value": "[parameters('name')]"
- },
- "containers": {
- "value": "[tryGet(parameters('storageInsightsConfigs')[copyIndex()], 'containers')]"
- },
- "tables": {
- "value": "[tryGet(parameters('storageInsightsConfigs')[copyIndex()], 'tables')]"
- },
- "storageAccountResourceId": {
- "value": "[parameters('storageInsightsConfigs')[copyIndex()].storageAccountResourceId]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "1745671120474305926"
- },
- "name": "Log Analytics Workspace Storage Insight Configs",
- "description": "This module deploys a Log Analytics Workspace Storage Insight Config.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "defaultValue": "[format('{0}-stinsconfig', last(split(parameters('storageAccountResourceId'), '/')))]",
- "metadata": {
- "description": "Optional. The name of the storage insights config."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The Azure Resource Manager ID of the storage account resource."
- }
- },
- "containers": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. The names of the blob containers that the workspace should read."
- }
- },
- "tables": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. The names of the Azure tables that the workspace should read."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to configure in the resource."
- }
- }
- },
- "resources": {
- "storageAccount": {
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2022-09-01",
- "name": "[last(split(parameters('storageAccountResourceId'), '/'))]"
- },
- "workspace": {
- "existing": true,
- "type": "Microsoft.OperationalInsights/workspaces",
- "apiVersion": "2022-10-01",
- "name": "[parameters('logAnalyticsWorkspaceName')]"
- },
- "storageinsightconfig": {
- "type": "Microsoft.OperationalInsights/workspaces/storageInsightConfigs",
- "apiVersion": "2020-08-01",
- "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]",
- "tags": "[parameters('tags')]",
- "properties": {
- "containers": "[parameters('containers')]",
- "tables": "[parameters('tables')]",
- "storageAccount": {
- "id": "[parameters('storageAccountResourceId')]",
- "key": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', last(split(parameters('storageAccountResourceId'), '/'))), '2022-09-01').keys[0].value]"
- }
- },
- "dependsOn": [
- "storageAccount",
- "workspace"
- ]
- }
- },
- "outputs": {
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed storage insights configuration."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces/storageInsightConfigs', parameters('logAnalyticsWorkspaceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group where the storage insight configuration is deployed."
- },
- "value": "[resourceGroup().name]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the storage insights configuration."
- },
- "value": "[parameters('name')]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_linkedServices": {
- "copy": {
- "name": "logAnalyticsWorkspace_linkedServices",
- "count": "[length(parameters('linkedServices'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-LinkedService-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[parameters('linkedServices')[copyIndex()].name]"
- },
- "resourceId": {
- "value": "[tryGet(parameters('linkedServices')[copyIndex()], 'resourceId')]"
- },
- "writeAccessResourceId": {
- "value": "[tryGet(parameters('linkedServices')[copyIndex()], 'writeAccessResourceId')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "12032441371027552374"
- },
- "name": "Log Analytics Workspace Linked Services",
- "description": "This module deploys a Log Analytics Workspace Linked Service.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the link."
- }
- },
- "resourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Required. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require read access."
- }
- },
- "writeAccessResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require write access."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to configure in the resource."
- }
- }
- },
- "resources": {
- "workspace": {
- "existing": true,
- "type": "Microsoft.OperationalInsights/workspaces",
- "apiVersion": "2022-10-01",
- "name": "[parameters('logAnalyticsWorkspaceName')]"
- },
- "linkedService": {
- "type": "Microsoft.OperationalInsights/workspaces/linkedServices",
- "apiVersion": "2020-08-01",
- "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]",
- "tags": "[parameters('tags')]",
- "properties": {
- "resourceId": "[parameters('resourceId')]",
- "writeAccessResourceId": "[if(empty(parameters('writeAccessResourceId')), null(), parameters('writeAccessResourceId'))]"
- },
- "dependsOn": [
- "workspace"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed linked service."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed linked service."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces/linkedServices', parameters('logAnalyticsWorkspaceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group where the linked service is deployed."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_linkedStorageAccounts": {
- "copy": {
- "name": "logAnalyticsWorkspace_linkedStorageAccounts",
- "count": "[length(parameters('linkedStorageAccounts'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-LinkedStorageAccount-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[parameters('linkedStorageAccounts')[copyIndex()].name]"
- },
- "resourceId": {
- "value": "[parameters('linkedStorageAccounts')[copyIndex()].resourceId]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "12623216644328477682"
- },
- "name": "Log Analytics Workspace Linked Storage Accounts",
- "description": "This module deploys a Log Analytics Workspace Linked Storage Account.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "allowedValues": [
- "Query",
- "Alerts",
- "CustomLogs",
- "AzureWatson"
- ],
- "metadata": {
- "description": "Required. Name of the link."
- }
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require read access."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/workspaces/linkedStorageAccounts",
- "apiVersion": "2020-08-01",
- "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]",
- "properties": {
- "storageAccountIds": [
- "[parameters('resourceId')]"
- ]
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed linked storage account."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed linked storage account."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces/linkedStorageAccounts', parameters('logAnalyticsWorkspaceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group where the linked storage account is deployed."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_savedSearches": {
- "copy": {
- "name": "logAnalyticsWorkspace_savedSearches",
- "count": "[length(parameters('savedSearches'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-SavedSearch-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[format('{0}{1}', parameters('savedSearches')[copyIndex()].name, uniqueString(deployment().name))]"
- },
- "etag": {
- "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'etag')]"
- },
- "displayName": {
- "value": "[parameters('savedSearches')[copyIndex()].displayName]"
- },
- "category": {
- "value": "[parameters('savedSearches')[copyIndex()].category]"
- },
- "query": {
- "value": "[parameters('savedSearches')[copyIndex()].query]"
- },
- "functionAlias": {
- "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'functionAlias')]"
- },
- "functionParameters": {
- "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'functionParameters')]"
- },
- "version": {
- "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'version')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "7683333179440464721"
- },
- "name": "Log Analytics Workspace Saved Searches",
- "description": "This module deploys a Log Analytics Workspace Saved Search.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the saved search."
- }
- },
- "displayName": {
- "type": "string",
- "metadata": {
- "description": "Required. Display name for the search."
- }
- },
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Query category."
- }
- },
- "query": {
- "type": "string",
- "metadata": {
- "description": "Required. Kusto Query to be stored."
- }
- },
- "tags": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to configure in the resource."
- }
- },
- "functionAlias": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The function alias if query serves as a function."
- }
- },
- "functionParameters": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The optional function parameters if query serves as a function. Value should be in the following format: \"param-name1:type1 = default_value1, param-name2:type2 = default_value2\". For more examples and proper syntax please refer to /azure/kusto/query/functions/user-defined-functions."
- }
- },
- "version": {
- "type": "int",
- "nullable": true,
- "metadata": {
- "description": "Optional. The version number of the query language."
- }
- },
- "etag": {
- "type": "string",
- "defaultValue": "*",
- "metadata": {
- "description": "Optional. The ETag of the saved search. To override an existing saved search, use \"*\" or specify the current Etag."
- }
- }
- },
- "resources": {
- "workspace": {
- "existing": true,
- "type": "Microsoft.OperationalInsights/workspaces",
- "apiVersion": "2022-10-01",
- "name": "[parameters('logAnalyticsWorkspaceName')]"
- },
- "savedSearch": {
- "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
- "apiVersion": "2020-08-01",
- "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]",
- "properties": {
- "etag": "[parameters('etag')]",
- "tags": "[coalesce(parameters('tags'), createArray())]",
- "displayName": "[parameters('displayName')]",
- "category": "[parameters('category')]",
- "query": "[parameters('query')]",
- "functionAlias": "[parameters('functionAlias')]",
- "functionParameters": "[parameters('functionParameters')]",
- "version": "[parameters('version')]"
- },
- "dependsOn": [
- "workspace"
- ]
- }
- },
- "outputs": {
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed saved search."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('logAnalyticsWorkspaceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group where the saved search is deployed."
- },
- "value": "[resourceGroup().name]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed saved search."
- },
- "value": "[parameters('name')]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace",
- "logAnalyticsWorkspace_linkedStorageAccounts"
- ]
- },
- "logAnalyticsWorkspace_dataExports": {
- "copy": {
- "name": "logAnalyticsWorkspace_dataExports",
- "count": "[length(parameters('dataExports'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-DataExport-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "workspaceName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[parameters('dataExports')[copyIndex()].name]"
- },
- "destination": {
- "value": "[tryGet(parameters('dataExports')[copyIndex()], 'destination')]"
- },
- "enable": {
- "value": "[tryGet(parameters('dataExports')[copyIndex()], 'enable')]"
- },
- "tableNames": {
- "value": "[tryGet(parameters('dataExports')[copyIndex()], 'tableNames')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "5765609820817623497"
- },
- "name": "Log Analytics Workspace Data Exports",
- "description": "This module deploys a Log Analytics Workspace Data Export.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "name": {
- "type": "string",
- "minLength": 4,
- "maxLength": 63,
- "metadata": {
- "description": "Required. The data export rule name."
- }
- },
- "workspaceName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent workspaces. Required if the template is used in a standalone deployment."
- }
- },
- "destination": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Destination properties."
- }
- },
- "enable": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Active when enabled."
- }
- },
- "tableNames": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. An array of tables to export, for example: ['Heartbeat', 'SecurityEvent']."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/workspaces/dataExports",
- "apiVersion": "2020-08-01",
- "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]",
- "properties": {
- "destination": "[parameters('destination')]",
- "enable": "[parameters('enable')]",
- "tableNames": "[parameters('tableNames')]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the data export."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the data export."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces/dataExports', parameters('workspaceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the data export was created in."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_dataSources": {
- "copy": {
- "name": "logAnalyticsWorkspace_dataSources",
- "count": "[length(parameters('dataSources'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-DataSource-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[parameters('dataSources')[copyIndex()].name]"
- },
- "kind": {
- "value": "[parameters('dataSources')[copyIndex()].kind]"
- },
- "linkedResourceId": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'linkedResourceId')]"
- },
- "eventLogName": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'eventLogName')]"
- },
- "eventTypes": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'eventTypes')]"
- },
- "objectName": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'objectName')]"
- },
- "instanceName": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'instanceName')]"
- },
- "intervalSeconds": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'intervalSeconds')]"
- },
- "counterName": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'counterName')]"
- },
- "state": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'state')]"
- },
- "syslogName": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'syslogName')]"
- },
- "syslogSeverities": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'syslogSeverities')]"
- },
- "performanceCounters": {
- "value": "[tryGet(parameters('dataSources')[copyIndex()], 'performanceCounters')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "13460038983765020046"
- },
- "name": "Log Analytics Workspace Datasources",
- "description": "This module deploys a Log Analytics Workspace Data Source.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "logAnalyticsWorkspaceName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment."
- }
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the solution."
- }
- },
- "kind": {
- "type": "string",
- "defaultValue": "AzureActivityLog",
- "allowedValues": [
- "AzureActivityLog",
- "WindowsEvent",
- "WindowsPerformanceCounter",
- "IISLogs",
- "LinuxSyslog",
- "LinuxSyslogCollection",
- "LinuxPerformanceObject",
- "LinuxPerformanceCollection"
- ],
- "metadata": {
- "description": "Required. The kind of the DataSource."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to configure in the resource."
- }
- },
- "linkedResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Resource ID of the resource to be linked."
- }
- },
- "eventLogName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Windows event log name to configure when kind is WindowsEvent."
- }
- },
- "eventTypes": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. Windows event types to configure when kind is WindowsEvent."
- }
- },
- "objectName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Name of the object to configure when kind is WindowsPerformanceCounter or LinuxPerformanceObject."
- }
- },
- "instanceName": {
- "type": "string",
- "defaultValue": "*",
- "metadata": {
- "description": "Optional. Name of the instance to configure when kind is WindowsPerformanceCounter or LinuxPerformanceObject."
- }
- },
- "intervalSeconds": {
- "type": "int",
- "defaultValue": 60,
- "metadata": {
- "description": "Optional. Interval in seconds to configure when kind is WindowsPerformanceCounter or LinuxPerformanceObject."
- }
- },
- "performanceCounters": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. List of counters to configure when the kind is LinuxPerformanceObject."
- }
- },
- "counterName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Counter name to configure when kind is WindowsPerformanceCounter."
- }
- },
- "state": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. State to configure when kind is IISLogs or LinuxSyslogCollection or LinuxPerformanceCollection."
- }
- },
- "syslogName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. System log to configure when kind is LinuxSyslog."
- }
- },
- "syslogSeverities": {
- "type": "array",
- "defaultValue": [],
- "metadata": {
- "description": "Optional. Severities to configure when kind is LinuxSyslog."
- }
- }
- },
- "resources": {
- "workspace": {
- "existing": true,
- "type": "Microsoft.OperationalInsights/workspaces",
- "apiVersion": "2022-10-01",
- "name": "[parameters('logAnalyticsWorkspaceName')]"
- },
- "dataSource": {
- "type": "Microsoft.OperationalInsights/workspaces/dataSources",
- "apiVersion": "2020-08-01",
- "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]",
- "kind": "[parameters('kind')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "linkedResourceId": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'AzureActivityLog')), parameters('linkedResourceId'), null())]",
- "eventLogName": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'WindowsEvent')), parameters('eventLogName'), null())]",
- "eventTypes": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'WindowsEvent')), parameters('eventTypes'), null())]",
- "objectName": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'WindowsPerformanceCounter'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('objectName'), null())]",
- "instanceName": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'WindowsPerformanceCounter'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('instanceName'), null())]",
- "intervalSeconds": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'WindowsPerformanceCounter'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('intervalSeconds'), null())]",
- "counterName": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'WindowsPerformanceCounter')), parameters('counterName'), null())]",
- "state": "[if(and(not(empty(parameters('kind'))), or(or(equals(parameters('kind'), 'IISLogs'), equals(parameters('kind'), 'LinuxSyslogCollection')), equals(parameters('kind'), 'LinuxPerformanceCollection'))), parameters('state'), null())]",
- "syslogName": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'LinuxSyslog')), parameters('syslogName'), null())]",
- "syslogSeverities": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'LinuxSyslog'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('syslogSeverities'), null())]",
- "performanceCounters": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'LinuxPerformanceObject')), parameters('performanceCounters'), null())]"
- },
- "dependsOn": [
- "workspace"
- ]
- }
- },
- "outputs": {
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed data source."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces/dataSources', parameters('logAnalyticsWorkspaceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group where the data source is deployed."
- },
- "value": "[resourceGroup().name]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed data source."
- },
- "value": "[parameters('name')]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_tables": {
- "copy": {
- "name": "logAnalyticsWorkspace_tables",
- "count": "[length(parameters('tables'))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-Table-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "workspaceName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[parameters('tables')[copyIndex()].name]"
- },
- "plan": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'plan')]"
- },
- "schema": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'schema')]"
- },
- "retentionInDays": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'retentionInDays')]"
- },
- "totalRetentionInDays": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'totalRetentionInDays')]"
- },
- "restoredLogs": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'restoredLogs')]"
- },
- "searchResults": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'searchResults')]"
- },
- "roleAssignments": {
- "value": "[tryGet(parameters('tables')[copyIndex()], 'roleAssignments')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "10380077652898392916"
- },
- "name": "Log Analytics Workspace Tables",
- "description": "This module deploys a Log Analytics Workspace Table.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "roleAssignmentType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- }
- },
- "nullable": true
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the table."
- }
- },
- "workspaceName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent workspaces. Required if the template is used in a standalone deployment."
- }
- },
- "plan": {
- "type": "string",
- "defaultValue": "Analytics",
- "allowedValues": [
- "Basic",
- "Analytics"
- ],
- "metadata": {
- "description": "Optional. Instruct the system how to handle and charge the logs ingested to this table."
- }
- },
- "restoredLogs": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Restore parameters."
- }
- },
- "retentionInDays": {
- "type": "int",
- "defaultValue": -1,
- "minValue": -1,
- "maxValue": 730,
- "metadata": {
- "description": "Optional. The table retention in days, between 4 and 730. Setting this property to -1 will default to the workspace retention."
- }
- },
- "schema": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Table's schema."
- }
- },
- "searchResults": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. Parameters of the search job that initiated this table."
- }
- },
- "totalRetentionInDays": {
- "type": "int",
- "defaultValue": -1,
- "minValue": -1,
- "maxValue": 2555,
- "metadata": {
- "description": "Optional. The table total retention in days, between 4 and 2555. Setting this property to -1 will default to table retention."
- }
- },
- "roleAssignments": {
- "$ref": "#/definitions/roleAssignmentType",
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]",
- "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]",
- "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]",
- "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "workspace": {
- "existing": true,
- "type": "Microsoft.OperationalInsights/workspaces",
- "apiVersion": "2022-10-01",
- "name": "[parameters('workspaceName')]"
- },
- "table": {
- "type": "Microsoft.OperationalInsights/workspaces/tables",
- "apiVersion": "2022-10-01",
- "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]",
- "properties": {
- "plan": "[parameters('plan')]",
- "restoredLogs": "[parameters('restoredLogs')]",
- "retentionInDays": "[parameters('retentionInDays')]",
- "schema": "[parameters('schema')]",
- "searchResults": "[parameters('searchResults')]",
- "totalRetentionInDays": "[parameters('totalRetentionInDays')]"
- },
- "dependsOn": [
- "workspace"
- ]
- },
- "table_roleAssignments": {
- "copy": {
- "name": "table_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}/tables/{1}', parameters('workspaceName'), parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "table"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the table."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the table."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the table was created in."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- },
- "logAnalyticsWorkspace_solutions": {
- "copy": {
- "name": "logAnalyticsWorkspace_solutions",
- "count": "[length(parameters('gallerySolutions'))]"
- },
- "condition": "[not(empty(parameters('gallerySolutions')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-LAW-Solution-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[parameters('gallerySolutions')[copyIndex()].name]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "logAnalyticsWorkspaceName": {
- "value": "[parameters('name')]"
- },
- "product": {
- "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'product')]"
- },
- "publisher": {
- "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'publisher')]"
- },
- "enableTelemetry": {
- "value": "[coalesce(tryGet(parameters('gallerySolutions')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.23.1.45101",
- "templateHash": "18444780972506374592"
- },
- "name": "Operations Management Solutions",
- "description": "This module deploys an Operations Management Solution.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`."
- }
- },
- "logAnalyticsWorkspaceName": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the Log Analytics workspace where the solution will be deployed/enabled."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all resources."
- }
- },
- "product": {
- "type": "string",
- "defaultValue": "OMSGallery",
- "metadata": {
- "description": "Optional. The product of the deployed solution. For Microsoft published gallery solution it should be `OMSGallery` and the target solution resource product will be composed as `OMSGallery/{name}`. For third party solution, it can be anything. This is case sensitive."
- }
- },
- "publisher": {
- "type": "string",
- "defaultValue": "Microsoft",
- "metadata": {
- "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "variables": {
- "solutionName": "[if(equals(parameters('publisher'), 'Microsoft'), format('{0}({1})', parameters('name'), parameters('logAnalyticsWorkspaceName')), parameters('name'))]",
- "solutionProduct": "[if(equals(parameters('publisher'), 'Microsoft'), format('OMSGallery/{0}', parameters('name')), parameters('product'))]"
- },
- "resources": [
- {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2023-07-01",
- "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- {
- "type": "Microsoft.OperationsManagement/solutions",
- "apiVersion": "2015-11-01-preview",
- "name": "[variables('solutionName')]",
- "location": "[parameters('location')]",
- "properties": {
- "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]"
- },
- "plan": {
- "name": "[variables('solutionName')]",
- "promotionCode": "",
- "product": "[variables('solutionProduct')]",
- "publisher": "[parameters('publisher')]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed solution."
- },
- "value": "[variables('solutionName')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed solution."
- },
- "value": "[resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group where the solution is deployed."
- },
- "value": "[resourceGroup().name]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference(resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName')), '2015-11-01-preview', 'full').location]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalyticsWorkspace"
- ]
- }
- },
- "outputs": {
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed log analytics workspace."
- },
- "value": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group of the deployed log analytics workspace."
- },
- "value": "[resourceGroup().name]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed log analytics workspace."
- },
- "value": "[parameters('name')]"
- },
- "logAnalyticsWorkspaceId": {
- "type": "string",
- "metadata": {
- "description": "The ID associated with the workspace."
- },
- "value": "[reference('logAnalyticsWorkspace').customerId]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('logAnalyticsWorkspace', '2022-10-01', 'full').location]"
- },
- "systemAssignedMIPrincipalId": {
- "type": "string",
- "metadata": {
- "description": "The principal ID of the system assigned identity."
- },
- "value": "[coalesce(tryGet(tryGet(reference('logAnalyticsWorkspace', '2022-10-01', 'full'), 'identity'), 'principalId'), '')]"
- }
- }
- }
- }
- },
- "applicationInsights": {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "applicationinsights",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "logAnalyticsWorkspaceResourceId": {
- "value": "[reference('logAnalytics').outputs.resourceId.value]"
- },
- "name": {
- "value": "[parameters('applicationInsightsName')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[parameters('tags')]"
- },
- "dashboardName": {
- "value": "[parameters('applicationInsightsDashboardName')]"
- },
- "enableTelemetry": {
- "value": "[parameters('enableTelemetry')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "17156187352453961206"
- },
- "name": "Application Insights Components",
- "description": "Creates an Application Insights instance based on an existing Log Analytics workspace.\n\n**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource insights components name."
- }
- },
- "dashboardName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The resource portal dashboards name."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "logAnalyticsWorkspaceResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource ID of the loganalytics workspace."
- }
- },
- "kind": {
- "type": "string",
- "defaultValue": "web",
- "metadata": {
- "description": "Optional. The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone."
- }
- },
- "applicationType": {
- "type": "string",
- "defaultValue": "web",
- "allowedValues": [
- "web",
- "other"
- ],
- "metadata": {
- "description": "Optional. Application type."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ",
- "description": "Optional. Tags of the resource."
- }
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.ptn.azd-insightsdashboard.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "applicationInsights": {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-appinsights', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[parameters('name')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[parameters('tags')]"
- },
- "kind": {
- "value": "[parameters('kind')]"
- },
- "applicationType": {
- "value": "[parameters('applicationType')]"
- },
- "workspaceResourceId": {
- "value": "[parameters('logAnalyticsWorkspaceResourceId')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "10653241142071426932"
- },
- "name": "Application Insights",
- "description": "This component deploys an Application Insights instance.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "roleAssignmentType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- }
- },
- "nullable": true
- },
- "diagnosticSettingType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- }
- },
- "nullable": true
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the Application Insights."
- }
- },
- "applicationType": {
- "type": "string",
- "defaultValue": "web",
- "allowedValues": [
- "web",
- "other"
- ],
- "metadata": {
- "description": "Optional. Application type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Resource ID of the log analytics workspace which the data will be ingested to. This property is required to create an application with this API version. Applications from older versions will not have this property."
- }
- },
- "disableIpMasking": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Disable IP masking. Default value is set to true."
- }
- },
- "disableLocalAuth": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Disable Non-AAD based Auth. Default value is set to false."
- }
- },
- "forceCustomerStorageForProfiler": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Force users to create their own storage account for profiler and debugger."
- }
- },
- "linkedStorageAccountResourceId": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. Linked storage account resource ID."
- }
- },
- "publicNetworkAccessForIngestion": {
- "type": "string",
- "defaultValue": "Enabled",
- "allowedValues": [
- "Enabled",
- "Disabled"
- ],
- "metadata": {
- "description": "Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled."
- }
- },
- "publicNetworkAccessForQuery": {
- "type": "string",
- "defaultValue": "Enabled",
- "allowedValues": [
- "Enabled",
- "Disabled"
- ],
- "metadata": {
- "description": "Optional. The network access type for accessing Application Insights query. - Enabled or Disabled."
- }
- },
- "retentionInDays": {
- "type": "int",
- "defaultValue": 365,
- "allowedValues": [
- 30,
- 60,
- 90,
- 120,
- 180,
- 270,
- 365,
- 550,
- 730
- ],
- "metadata": {
- "description": "Optional. Retention period in days."
- }
- },
- "samplingPercentage": {
- "type": "int",
- "defaultValue": 100,
- "minValue": 0,
- "maxValue": 100,
- "metadata": {
- "description": "Optional. Percentage of the data produced by the application being monitored that is being sampled for Application Insights telemetry."
- }
- },
- "kind": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Optional. The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "roleAssignments": {
- "$ref": "#/definitions/roleAssignmentType",
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "diagnosticSettings": {
- "$ref": "#/definitions/diagnosticSettingType",
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]",
- "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]",
- "Application Insights Component Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ae349356-3a1b-4a5e-921d-050484c6347e')]",
- "Application Insights Snapshot Debugger": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '08954f03-6346-4c2e-81c0-ec3a5cfae23b')]",
- "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.insights-component.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "appInsights": {
- "type": "Microsoft.Insights/components",
- "apiVersion": "2020-02-02",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "kind": "[parameters('kind')]",
- "properties": {
- "Application_Type": "[parameters('applicationType')]",
- "DisableIpMasking": "[parameters('disableIpMasking')]",
- "DisableLocalAuth": "[parameters('disableLocalAuth')]",
- "ForceCustomerStorageForProfiler": "[parameters('forceCustomerStorageForProfiler')]",
- "WorkspaceResourceId": "[parameters('workspaceResourceId')]",
- "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]",
- "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]",
- "RetentionInDays": "[parameters('retentionInDays')]",
- "SamplingPercentage": "[parameters('samplingPercentage')]"
- }
- },
- "appInsights_roleAssignments": {
- "copy": {
- "name": "appInsights_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Insights/components/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Insights/components', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "appInsights"
- ]
- },
- "appInsights_diagnosticSettings": {
- "copy": {
- "name": "appInsights_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Insights/components/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "appInsights"
- ]
- },
- "linkedStorageAccount": {
- "condition": "[not(empty(parameters('linkedStorageAccountResourceId')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-appInsights-linkedStorageAccount', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appInsightsName": {
- "value": "[parameters('name')]"
- },
- "storageAccountResourceId": {
- "value": "[parameters('linkedStorageAccountResourceId')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "216781367921725873"
- },
- "name": "Application Insights Linked Storage Account",
- "description": "This component deploys an Application Insights Linked Storage Account.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "appInsightsName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent Application Insights instance. Required if the template is used in a standalone deployment."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Linked storage account resource ID."
- }
- }
- },
- "resources": [
- {
- "type": "microsoft.insights/components/linkedStorageAccounts",
- "apiVersion": "2020-03-01-preview",
- "name": "[format('{0}/{1}', parameters('appInsightsName'), 'ServiceProfiler')]",
- "properties": {
- "linkedStorageAccount": "[parameters('storageAccountResourceId')]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the Linked Storage Account."
- },
- "value": "ServiceProfiler"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the Linked Storage Account."
- },
- "value": "[resourceId('microsoft.insights/components/linkedStorageAccounts', parameters('appInsightsName'), 'ServiceProfiler')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the agent pool was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "appInsights"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the application insights component."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the application insights component."
- },
- "value": "[resourceId('Microsoft.Insights/components', parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the application insights component was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "applicationId": {
- "type": "string",
- "metadata": {
- "description": "The application ID of the application insights component."
- },
- "value": "[reference('appInsights').AppId]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('appInsights', '2020-02-02', 'full').location]"
- },
- "instrumentationKey": {
- "type": "string",
- "metadata": {
- "description": "Application Insights Instrumentation key. A read-only value that applications can use to identify the destination for all telemetry sent to Azure Application Insights. This value will be supplied upon construction of each new Application Insights component."
- },
- "value": "[reference('appInsights').InstrumentationKey]"
- },
- "connectionString": {
- "type": "string",
- "metadata": {
- "description": "Application Insights Connection String."
- },
- "value": "[reference('appInsights').ConnectionString]"
- }
- }
- }
- }
- },
- "applicationInsightsDashboard": {
- "condition": "[not(empty(parameters('dashboardName')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "application-insights-dashboard",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[parameters('dashboardName')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "applicationInsightsName": {
- "value": "[reference('applicationInsights').outputs.name.value]"
- },
- "applicationInsightsResourceId": {
- "value": "[reference('applicationInsights').outputs.resourceId.value]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.29.47.4906",
- "templateHash": "9856731218551847403"
- },
- "name": "Azure Portal Dashboard",
- "description": "Creates a dashboard for an Application Insights instance.",
- "owner": "Azure/module-maintainers"
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The portal dashboard name."
- }
- },
- "applicationInsightsName": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource insights components name."
- }
- },
- "applicationInsightsResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource insights components ID."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ",
- "description": "Optional. Tags of the resource."
- }
- }
- },
- "resources": {
- "dashboard": {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "dashboard-deployment",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[parameters('name')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[parameters('tags')]"
- },
- "lenses": {
- "value": [
- {
- "order": 0,
- "parts": [
- {
- "position": {
- "x": 0,
- "y": 0,
- "colSpan": 2,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "id",
- "value": "[parameters('applicationInsightsResourceId')]"
- },
- {
- "name": "Version",
- "value": "1.0"
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/AspNetOverviewPinnedPart",
- "asset": {
- "idInputName": "id",
- "type": "ApplicationInsights"
- },
- "defaultMenuItemId": "overview"
- }
- },
- {
- "position": {
- "x": 2,
- "y": 0,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ComponentId",
- "value": {
- "Name": "[parameters('applicationInsightsName')]",
- "SubscriptionId": "[subscription().subscriptionId]",
- "ResourceGroup": "[resourceGroup().name]"
- }
- },
- {
- "name": "Version",
- "value": "1.0"
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/ProactiveDetectionAsyncPart",
- "asset": {
- "idInputName": "ComponentId",
- "type": "ApplicationInsights"
- },
- "defaultMenuItemId": "ProactiveDetection"
- }
- },
- {
- "position": {
- "x": 3,
- "y": 0,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ComponentId",
- "value": {
- "Name": "[parameters('applicationInsightsName')]",
- "SubscriptionId": "[subscription().subscriptionId]",
- "ResourceGroup": "[resourceGroup().name]"
- }
- },
- {
- "name": "ResourceId",
- "value": "[parameters('applicationInsightsResourceId')]"
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/QuickPulseButtonSmallPart",
- "asset": {
- "idInputName": "ComponentId",
- "type": "ApplicationInsights"
- }
- }
- },
- {
- "position": {
- "x": 4,
- "y": 0,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ComponentId",
- "value": {
- "Name": "[parameters('applicationInsightsName')]",
- "SubscriptionId": "[subscription().subscriptionId]",
- "ResourceGroup": "[resourceGroup().name]"
- }
- },
- {
- "name": "TimeContext",
- "value": {
- "durationMs": 86400000,
- "endTime": null,
- "createdTime": "2018-05-04T01:20:33.345Z",
- "isInitialTime": true,
- "grain": 1,
- "useDashboardTimeRange": false
- }
- },
- {
- "name": "Version",
- "value": "1.0"
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/AvailabilityNavButtonPart",
- "asset": {
- "idInputName": "ComponentId",
- "type": "ApplicationInsights"
- }
- }
- },
- {
- "position": {
- "x": 5,
- "y": 0,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ComponentId",
- "value": {
- "Name": "[parameters('applicationInsightsName')]",
- "SubscriptionId": "[subscription().subscriptionId]",
- "ResourceGroup": "[resourceGroup().name]"
- }
- },
- {
- "name": "TimeContext",
- "value": {
- "durationMs": 86400000,
- "endTime": null,
- "createdTime": "2018-05-08T18:47:35.237Z",
- "isInitialTime": true,
- "grain": 1,
- "useDashboardTimeRange": false
- }
- },
- {
- "name": "ConfigurationId",
- "value": "78ce933e-e864-4b05-a27b-71fd55a6afad"
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/AppMapButtonPart",
- "asset": {
- "idInputName": "ComponentId",
- "type": "ApplicationInsights"
- }
- }
- },
- {
- "position": {
- "x": 0,
- "y": 1,
- "colSpan": 3,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [],
- "type": "Extension/HubsExtension/PartType/MarkdownPart",
- "settings": {
- "content": {
- "settings": {
- "content": "# Usage",
- "title": "",
- "subtitle": ""
- }
- }
- }
- }
- },
- {
- "position": {
- "x": 3,
- "y": 1,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ComponentId",
- "value": {
- "Name": "[parameters('applicationInsightsName')]",
- "SubscriptionId": "[subscription().subscriptionId]",
- "ResourceGroup": "[resourceGroup().name]"
- }
- },
- {
- "name": "TimeContext",
- "value": {
- "durationMs": 86400000,
- "endTime": null,
- "createdTime": "2018-05-04T01:22:35.782Z",
- "isInitialTime": true,
- "grain": 1,
- "useDashboardTimeRange": false
- }
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/UsageUsersOverviewPart",
- "asset": {
- "idInputName": "ComponentId",
- "type": "ApplicationInsights"
- }
- }
- },
- {
- "position": {
- "x": 4,
- "y": 1,
- "colSpan": 3,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [],
- "type": "Extension/HubsExtension/PartType/MarkdownPart",
- "settings": {
- "content": {
- "settings": {
- "content": "# Reliability",
- "title": "",
- "subtitle": ""
- }
- }
- }
- }
- },
- {
- "position": {
- "x": 7,
- "y": 1,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ResourceId",
- "value": "[parameters('applicationInsightsResourceId')]"
- },
- {
- "name": "DataModel",
- "value": {
- "version": "1.0.0",
- "timeContext": {
- "durationMs": 86400000,
- "createdTime": "2018-05-04T23:42:40.072Z",
- "isInitialTime": false,
- "grain": 1,
- "useDashboardTimeRange": false
- }
- },
- "isOptional": true
- },
- {
- "name": "ConfigurationId",
- "value": "8a02f7bf-ac0f-40e1-afe9-f0e72cfee77f",
- "isOptional": true
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/CuratedBladeFailuresPinnedPart",
- "isAdapter": true,
- "asset": {
- "idInputName": "ResourceId",
- "type": "ApplicationInsights"
- },
- "defaultMenuItemId": "failures"
- }
- },
- {
- "position": {
- "x": 8,
- "y": 1,
- "colSpan": 3,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [],
- "type": "Extension/HubsExtension/PartType/MarkdownPart",
- "settings": {
- "content": {
- "settings": {
- "content": "# Responsiveness\r\n",
- "title": "",
- "subtitle": ""
- }
- }
- }
- }
- },
- {
- "position": {
- "x": 11,
- "y": 1,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ResourceId",
- "value": "[parameters('applicationInsightsResourceId')]"
- },
- {
- "name": "DataModel",
- "value": {
- "version": "1.0.0",
- "timeContext": {
- "durationMs": 86400000,
- "createdTime": "2018-05-04T23:43:37.804Z",
- "isInitialTime": false,
- "grain": 1,
- "useDashboardTimeRange": false
- }
- },
- "isOptional": true
- },
- {
- "name": "ConfigurationId",
- "value": "2a8ede4f-2bee-4b9c-aed9-2db0e8a01865",
- "isOptional": true
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/CuratedBladePerformancePinnedPart",
- "isAdapter": true,
- "asset": {
- "idInputName": "ResourceId",
- "type": "ApplicationInsights"
- },
- "defaultMenuItemId": "performance"
- }
- },
- {
- "position": {
- "x": 12,
- "y": 1,
- "colSpan": 3,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [],
- "type": "Extension/HubsExtension/PartType/MarkdownPart",
- "settings": {
- "content": {
- "settings": {
- "content": "# Browser",
- "title": "",
- "subtitle": ""
- }
- }
- }
- }
- },
- {
- "position": {
- "x": 15,
- "y": 1,
- "colSpan": 1,
- "rowSpan": 1
- },
- "metadata": {
- "inputs": [
- {
- "name": "ComponentId",
- "value": {
- "Name": "[parameters('applicationInsightsName')]",
- "SubscriptionId": "[subscription().subscriptionId]",
- "ResourceGroup": "[resourceGroup().name]"
- }
- },
- {
- "name": "MetricsExplorerJsonDefinitionId",
- "value": "BrowserPerformanceTimelineMetrics"
- },
- {
- "name": "TimeContext",
- "value": {
- "durationMs": 86400000,
- "createdTime": "2018-05-08T12:16:27.534Z",
- "isInitialTime": false,
- "grain": 1,
- "useDashboardTimeRange": false
- }
- },
- {
- "name": "CurrentFilter",
- "value": {
- "eventTypes": [
- 4,
- 1,
- 3,
- 5,
- 2,
- 6,
- 13
- ],
- "typeFacets": {},
- "isPermissive": false
- }
- },
- {
- "name": "id",
- "value": {
- "Name": "[parameters('applicationInsightsName')]",
- "SubscriptionId": "[subscription().subscriptionId]",
- "ResourceGroup": "[resourceGroup().name]"
- }
- },
- {
- "name": "Version",
- "value": "1.0"
- }
- ],
- "type": "Extension/AppInsightsExtension/PartType/MetricsExplorerBladePinnedPart",
- "asset": {
- "idInputName": "ComponentId",
- "type": "ApplicationInsights"
- },
- "defaultMenuItemId": "browser"
- }
- },
- {
- "position": {
- "x": 0,
- "y": 2,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "sessions/count",
- "aggregationType": 5,
- "namespace": "microsoft.insights/components/kusto",
- "metricVisualization": {
- "displayName": "Sessions",
- "color": "#47BDF5"
- }
- },
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "users/count",
- "aggregationType": 5,
- "namespace": "microsoft.insights/components/kusto",
- "metricVisualization": {
- "displayName": "Users",
- "color": "#7E58FF"
- }
- }
- ],
- "title": "Unique sessions and users",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- },
- "openBladeOnClick": {
- "openBlade": true,
- "destinationBlade": {
- "extensionName": "HubsExtension",
- "bladeName": "ResourceMenuBlade",
- "parameters": {
- "id": "[parameters('applicationInsightsResourceId')]",
- "menuid": "segmentationUsers"
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 4,
- "y": 2,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "requests/failed",
- "aggregationType": 7,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Failed requests",
- "color": "#EC008C"
- }
- }
- ],
- "title": "Failed requests",
- "visualization": {
- "chartType": 3,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- },
- "openBladeOnClick": {
- "openBlade": true,
- "destinationBlade": {
- "extensionName": "HubsExtension",
- "bladeName": "ResourceMenuBlade",
- "parameters": {
- "id": "[parameters('applicationInsightsResourceId')]",
- "menuid": "failures"
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 8,
- "y": 2,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "requests/duration",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Server response time",
- "color": "#00BCF2"
- }
- }
- ],
- "title": "Server response time",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- },
- "openBladeOnClick": {
- "openBlade": true,
- "destinationBlade": {
- "extensionName": "HubsExtension",
- "bladeName": "ResourceMenuBlade",
- "parameters": {
- "id": "[parameters('applicationInsightsResourceId')]",
- "menuid": "performance"
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 12,
- "y": 2,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "browserTimings/networkDuration",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Page load network connect time",
- "color": "#7E58FF"
- }
- },
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "browserTimings/processingDuration",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Client processing time",
- "color": "#44F1C8"
- }
- },
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "browserTimings/sendDuration",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Send request time",
- "color": "#EB9371"
- }
- },
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "browserTimings/receiveDuration",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Receiving response time",
- "color": "#0672F1"
- }
- }
- ],
- "title": "Average page load time breakdown",
- "visualization": {
- "chartType": 3,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 0,
- "y": 5,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "availabilityResults/availabilityPercentage",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Availability",
- "color": "#47BDF5"
- }
- }
- ],
- "title": "Average availability",
- "visualization": {
- "chartType": 3,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- },
- "openBladeOnClick": {
- "openBlade": true,
- "destinationBlade": {
- "extensionName": "HubsExtension",
- "bladeName": "ResourceMenuBlade",
- "parameters": {
- "id": "[parameters('applicationInsightsResourceId')]",
- "menuid": "availability"
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 4,
- "y": 5,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "exceptions/server",
- "aggregationType": 7,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Server exceptions",
- "color": "#47BDF5"
- }
- },
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "dependencies/failed",
- "aggregationType": 7,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Dependency failures",
- "color": "#7E58FF"
- }
- }
- ],
- "title": "Server exceptions and Dependency failures",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 8,
- "y": 5,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "performanceCounters/processorCpuPercentage",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Processor time",
- "color": "#47BDF5"
- }
- },
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "performanceCounters/processCpuPercentage",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Process CPU",
- "color": "#7E58FF"
- }
- }
- ],
- "title": "Average processor and process CPU utilization",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 12,
- "y": 5,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "exceptions/browser",
- "aggregationType": 7,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Browser exceptions",
- "color": "#47BDF5"
- }
- }
- ],
- "title": "Browser exceptions",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 0,
- "y": 8,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "availabilityResults/count",
- "aggregationType": 7,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Availability test results count",
- "color": "#47BDF5"
- }
- }
- ],
- "title": "Availability test results count",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 4,
- "y": 8,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "performanceCounters/processIOBytesPerSecond",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Process IO rate",
- "color": "#47BDF5"
- }
- }
- ],
- "title": "Average process I/O rate",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- },
- {
- "position": {
- "x": 8,
- "y": 8,
- "colSpan": 4,
- "rowSpan": 3
- },
- "metadata": {
- "inputs": [
- {
- "name": "options",
- "value": {
- "chart": {
- "metrics": [
- {
- "resourceMetadata": {
- "id": "[parameters('applicationInsightsResourceId')]"
- },
- "name": "performanceCounters/memoryAvailableBytes",
- "aggregationType": 4,
- "namespace": "microsoft.insights/components",
- "metricVisualization": {
- "displayName": "Available memory",
- "color": "#47BDF5"
- }
- }
- ],
- "title": "Average available memory",
- "visualization": {
- "chartType": 2,
- "legendVisualization": {
- "isVisible": true,
- "position": 2,
- "hideSubtitle": false
- },
- "axisVisualization": {
- "x": {
- "isVisible": true,
- "axisType": 2
- },
- "y": {
- "isVisible": true,
- "axisType": 1
- }
- }
- }
- }
- }
- },
- {
- "name": "sharedTimeRange",
- "isOptional": true
- }
- ],
- "type": "Extension/HubsExtension/PartType/MonitorChartPart",
- "settings": {}
- }
- }
- ]
- }
- ]
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.28.1.47646",
- "templateHash": "12676032921679464791"
- },
- "name": "Portal Dashboards",
- "description": "This module deploys a Portal Dashboard.",
- "owner": "Azure/module-maintainers"
- },
- "definitions": {
- "roleAssignmentType": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- }
- },
- "nullable": true
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "nullable": true
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the dashboard to create."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "roleAssignments": {
- "$ref": "#/definitions/roleAssignmentType",
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "lenses": {
- "type": "array",
- "items": {
- "type": "object"
- },
- "defaultValue": [],
- "metadata": {
- "description": "Optional. The dashboard lenses."
- }
- },
- "metadata": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The dashboard metadata."
- }
- }
- },
- "variables": {
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2023-07-01",
- "name": "[format('46d3xbcp.res.portal-dashboard.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "dashboard": {
- "type": "Microsoft.Portal/dashboards",
- "apiVersion": "2020-09-01-preview",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "lenses": "[parameters('lenses')]",
- "metadata": "[parameters('metadata')]"
- }
- },
- "dashboard_roleAssignments": {
- "copy": {
- "name": "dashboard_roleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Portal/dashboards/{0}', parameters('name'))]",
- "name": "[guid(resourceId('Microsoft.Portal/dashboards', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]",
- "properties": {
- "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]",
- "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "dashboard"
- ]
- },
- "dashboard_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Portal/dashboards/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "dashboard"
- ]
- }
- },
- "outputs": {
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the dashboard."
- },
- "value": "[resourceId('Microsoft.Portal/dashboards', parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the dashboard was created in."
- },
- "value": "[resourceGroup().name]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the dashboard."
- },
- "value": "[parameters('name')]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the dashboard was deployed into."
- },
- "value": "[reference('dashboard', '2020-09-01-preview', 'full').location]"
- }
- }
- }
- }
- }
- },
- "outputs": {
- "dashboardResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the dashboard."
- },
- "value": "[reference('dashboard').outputs.resourceId.value]"
- },
- "dashboardName": {
- "type": "string",
- "metadata": {
- "description": "The resource name of the dashboard."
- },
- "value": "[reference('dashboard').outputs.name.value]"
- }
- }
- }
- },
- "dependsOn": [
- "applicationInsights"
- ]
- }
- },
- "outputs": {
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the application insights components were deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "applicationInsightsName": {
- "type": "string",
- "metadata": {
- "description": "The name of the application insights."
- },
- "value": "[reference('applicationInsights').outputs.name.value]"
- },
- "dashboardName": {
- "type": "string",
- "metadata": {
- "description": "The resource name of the dashboard."
- },
- "value": "[if(not(empty(parameters('dashboardName'))), reference('applicationInsightsDashboard').outputs.dashboardName.value, '')]"
- },
- "applicationInsightsResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the application insights."
- },
- "value": "[reference('applicationInsights').outputs.resourceId.value]"
- },
- "dashboardResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the dashboard."
- },
- "value": "[if(not(empty(parameters('dashboardName'))), reference('applicationInsightsDashboard').outputs.dashboardResourceId.value, '')]"
- },
- "applicationInsightsConnectionString": {
- "type": "string",
- "metadata": {
- "description": "The connection string of the application insights."
- },
- "value": "[reference('applicationInsights').outputs.connectionString.value]"
- },
- "applicationInsightsInstrumentationKey": {
- "type": "string",
- "metadata": {
- "description": "The instrumentation key of the application insights."
- },
- "value": "[reference('applicationInsights').outputs.instrumentationKey.value]"
- }
- }
- }
- },
- "dependsOn": [
- "logAnalytics"
- ]
- }
- },
- "outputs": {
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the operational-insights monitoring was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "applicationInsightsConnectionString": {
- "type": "string",
- "metadata": {
- "description": "The connection string of the application insights."
- },
- "value": "[reference('applicationInsights').outputs.applicationInsightsConnectionString.value]"
- },
- "applicationInsightsResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the application insights."
- },
- "value": "[reference('applicationInsights').outputs.applicationInsightsResourceId.value]"
- },
- "applicationInsightsInstrumentationKey": {
- "type": "string",
- "metadata": {
- "description": "The instrumentation key for the application insights."
- },
- "value": "[reference('applicationInsights').outputs.applicationInsightsInstrumentationKey.value]"
- },
- "applicationInsightsName": {
- "type": "string",
- "metadata": {
- "description": "The name of the application insights."
- },
- "value": "[reference('applicationInsights').outputs.applicationInsightsName.value]"
- },
- "logAnalyticsWorkspaceResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the loganalytics workspace."
- },
- "value": "[reference('logAnalytics').outputs.resourceId.value]"
- },
- "logAnalyticsWorkspaceName": {
- "type": "string",
- "metadata": {
- "description": "The name of the log analytics workspace."
- },
- "value": "[reference('logAnalytics').outputs.name.value]"
- }
- }
- }
- },
- "dependsOn": [
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "api",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[variables('functionAppName')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[variables('tags')]"
- },
- "applicationInsightsName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'monitoring'), '2025-04-01').outputs.applicationInsightsName.value]"
- },
- "appServicePlanId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'appserviceplan'), '2025-04-01').outputs.resourceId.value]"
- },
- "runtimeName": {
- "value": "python"
- },
- "runtimeVersion": {
- "value": "3.13"
- },
- "storageAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage'), '2025-04-01').outputs.name.value]"
- },
- "deploymentStorageContainerName": {
- "value": "[variables('deploymentStorageContainerName')]"
- },
- "identityId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity'), '2025-04-01').outputs.resourceId.value]"
- },
- "identityClientId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity'), '2025-04-01').outputs.clientId.value]"
- },
- "enableBlob": {
- "value": true
- },
- "enableQueue": {
- "value": true
- },
- "appSettings": {
- "value": {
- "AZURE_CLIENT_ID": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity'), '2025-04-01').outputs.clientId.value]",
- "AZURE_AI_PROJECT_ENDPOINT": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.projectEndpoint.value]",
- "AZURE_AI_MODEL_DEPLOYMENT_NAME": "[parameters('modelDeploymentName')]",
- "AZURE_OPENAI_ENDPOINT": "[format('https://{0}.openai.azure.com/', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiServicesName.value)]",
- "AZURE_OPENAI_DEPLOYMENT_NAME": "[parameters('modelDeploymentName')]"
- }
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "10042534433781864103"
- }
- },
- "parameters": {
- "name": {
- "type": "string"
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Primary location for all resources & Flex Consumption Function App"
- }
- },
- "tags": {
- "type": "object",
- "defaultValue": {}
- },
- "applicationInsightsName": {
- "type": "string",
- "defaultValue": ""
- },
- "appServicePlanId": {
- "type": "string"
- },
- "appSettings": {
- "type": "object",
- "defaultValue": {}
- },
- "runtimeName": {
- "type": "string"
- },
- "runtimeVersion": {
- "type": "string"
- },
- "serviceName": {
- "type": "string",
- "defaultValue": "api"
- },
- "storageAccountName": {
- "type": "string"
- },
- "deploymentStorageContainerName": {
- "type": "string"
- },
- "virtualNetworkSubnetId": {
- "type": "string",
- "defaultValue": ""
- },
- "instanceMemoryMB": {
- "type": "int",
- "defaultValue": 2048
- },
- "maximumInstanceCount": {
- "type": "int",
- "defaultValue": 100
- },
- "identityId": {
- "type": "string",
- "defaultValue": ""
- },
- "identityClientId": {
- "type": "string",
- "defaultValue": ""
- },
- "enableBlob": {
- "type": "bool",
- "defaultValue": true
- },
- "enableQueue": {
- "type": "bool",
- "defaultValue": false
- },
- "enableTable": {
- "type": "bool",
- "defaultValue": false
- },
- "enableFile": {
- "type": "bool",
- "defaultValue": false
- },
- "identityType": {
- "type": "string",
- "defaultValue": "UserAssigned",
- "allowedValues": [
- "SystemAssigned",
- "UserAssigned"
- ]
- }
- },
- "variables": {
- "applicationInsightsIdentity": "[format('ClientId={0};Authorization=AAD', parameters('identityClientId'))]",
- "kind": "functionapp"
- },
- "resources": [
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "[format('{0}-flex-consumption', parameters('serviceName'))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "kind": {
- "value": "[variables('kind')]"
- },
- "name": {
- "value": "[parameters('name')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[union(parameters('tags'), createObject('azd-service-name', parameters('serviceName')))]"
- },
- "serverFarmResourceId": {
- "value": "[parameters('appServicePlanId')]"
- },
- "managedIdentities": {
- "value": {
- "systemAssigned": "[equals(parameters('identityType'), 'SystemAssigned')]",
- "userAssignedResourceIds": [
- "[format('{0}', parameters('identityId'))]"
- ]
- }
- },
- "functionAppConfig": {
- "value": {
- "deployment": {
- "storage": {
- "type": "blobContainer",
- "value": "[format('{0}{1}', reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2022-09-01').primaryEndpoints.blob, parameters('deploymentStorageContainerName'))]",
- "authentication": {
- "type": "[if(equals(parameters('identityType'), 'SystemAssigned'), 'SystemAssignedIdentity', 'UserAssignedIdentity')]",
- "userAssignedIdentityResourceId": "[if(equals(parameters('identityType'), 'UserAssigned'), parameters('identityId'), '')]"
- }
- }
- },
- "scaleAndConcurrency": {
- "instanceMemoryMB": "[parameters('instanceMemoryMB')]",
- "maximumInstanceCount": "[parameters('maximumInstanceCount')]"
- },
- "runtime": {
- "name": "[parameters('runtimeName')]",
- "version": "[parameters('runtimeVersion')]"
- }
- }
- },
- "siteConfig": {
- "value": {
- "alwaysOn": false
- }
- },
- "virtualNetworkSubnetId": "[if(not(empty(parameters('virtualNetworkSubnetId'))), createObject('value', parameters('virtualNetworkSubnetId')), createObject('value', null()))]",
- "appSettingsKeyValuePairs": {
- "value": "[union(parameters('appSettings'), if(parameters('enableBlob'), createObject('AzureWebJobsStorage__blobServiceUri', reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2022-09-01').primaryEndpoints.blob), createObject()), if(parameters('enableQueue'), createObject('AzureWebJobsStorage__queueServiceUri', reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2022-09-01').primaryEndpoints.queue), createObject()), if(parameters('enableTable'), createObject('AzureWebJobsStorage__tableServiceUri', reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2022-09-01').primaryEndpoints.table), createObject()), if(parameters('enableFile'), createObject('AzureWebJobsStorage__fileServiceUri', reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2022-09-01').primaryEndpoints.file), createObject()), createObject('AzureWebJobsStorage__credential', 'managedidentity', 'AzureWebJobsStorage__clientId', parameters('identityClientId'), 'APPLICATIONINSIGHTS_AUTHENTICATION_STRING', variables('applicationInsightsIdentity'), 'APPLICATIONINSIGHTS_CONNECTION_STRING', reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), '2020-02-02').ConnectionString))]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "2522527858358792357"
- },
- "name": "Web/Function Apps",
- "description": "This module deploys a Web or Function App."
- },
- "definitions": {
- "privateEndpointOutputType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint."
- }
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint."
- }
- },
- "groupId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "The group Id for the private endpoint Group."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "A list of private IP addresses of the private endpoint."
- }
- }
- }
- },
- "metadata": {
- "description": "The custom DNS configurations of the private endpoint."
- }
- },
- "networkInterfaceResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "The IDs of the network interfaces associated with the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "_1.privateEndpointCustomDnsConfigType": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. A list of private IP addresses of the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "_1.privateEndpointIpConfigurationType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource that is unique within a resource group."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to."
- }
- },
- "memberName": {
- "type": "string",
- "metadata": {
- "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to."
- }
- },
- "privateIPAddress": {
- "type": "string",
- "metadata": {
- "description": "Required. A private IP address obtained from the private endpoint's subnet."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private endpoint IP configurations."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "_1.privateEndpointPrivateDnsZoneGroupType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private DNS Zone Group."
- }
- },
- "privateDnsZoneGroupConfigs": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS Zone Group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- }
- },
- "metadata": {
- "description": "Required. The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "diagnosticSettingFullType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a lock.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "managedIdentityAllType": {
- "type": "object",
- "properties": {
- "systemAssigned": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enables system assigned managed identity on the resource."
- }
- },
- "userAssignedResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "privateEndpointSingleServiceType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private Endpoint."
- }
- },
- "location": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The location to deploy the Private Endpoint to."
- }
- },
- "privateLinkServiceConnectionName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private link connection to create."
- }
- },
- "service": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The subresource to deploy the Private Endpoint for. For example \"vault\" for a Key Vault Private Endpoint."
- }
- },
- "subnetResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
- }
- },
- "resourceGroupResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used."
- }
- },
- "privateDnsZoneGroup": {
- "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The private DNS Zone Group to configure for the Private Endpoint."
- }
- },
- "isManualConnection": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. If Manual Private Link Connection is required."
- }
- },
- "manualConnectionRequestMessage": {
- "type": "string",
- "nullable": true,
- "maxLength": 140,
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with the manual connection request."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Custom DNS configurations."
- }
- },
- "ipConfigurations": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/_1.privateEndpointIpConfigurationType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints."
- }
- },
- "applicationSecurityGroupResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Application security groups in which the Private Endpoint IP configuration is included."
- }
- },
- "customNetworkInterfaceName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The custom name of the network interface attached to the Private Endpoint."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to be applied on all resources/Resource Groups in this deployment."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the site."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "functionapp",
- "functionapp,linux",
- "functionapp,workflowapp",
- "functionapp,workflowapp,linux",
- "functionapp,linux,container",
- "functionapp,linux,container,azurecontainerapps",
- "app,linux",
- "app",
- "linux,api",
- "api",
- "app,linux,container",
- "app,container,windows"
- ],
- "metadata": {
- "description": "Required. Type of site to deploy."
- }
- },
- "serverFarmResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource ID of the app service plan to use for the site."
- }
- },
- "managedEnvironmentId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Azure Resource Manager ID of the customers selected Managed Environment on which to host this app."
- }
- },
- "httpsOnly": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Configures a site to accept only HTTPS requests. Issues redirect for HTTP requests."
- }
- },
- "clientAffinityEnabled": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. If client affinity is enabled."
- }
- },
- "appServiceEnvironmentResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID of the app service environment to use for this resource."
- }
- },
- "managedIdentities": {
- "$ref": "#/definitions/managedIdentityAllType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The managed identity definition for this resource."
- }
- },
- "keyVaultAccessIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID of the assigned identity to be used to access a key vault with."
- }
- },
- "storageAccountRequired": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Checks if Customer provided storage account is required."
- }
- },
- "virtualNetworkSubnetId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Azure Resource Manager ID of the Virtual network and subnet to be joined by Regional VNET Integration. This must be of the form /subscriptions/{subscriptionName}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}/subnets/{subnetName}."
- }
- },
- "vnetContentShareEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. To enable accessing content over virtual network."
- }
- },
- "vnetImagePullEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. To enable pulling image over Virtual Network."
- }
- },
- "vnetRouteAllEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Virtual Network Route All enabled. This causes all outbound traffic to have Virtual Network Security Groups and User Defined Routes applied."
- }
- },
- "scmSiteAlsoStopped": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Stop SCM (KUDU) site when the app is stopped."
- }
- },
- "siteConfig": {
- "type": "object",
- "defaultValue": {
- "alwaysOn": true,
- "minTlsVersion": "1.2",
- "ftpsState": "FtpsOnly"
- },
- "metadata": {
- "description": "Optional. The site config object. The defaults are set to the following values: alwaysOn: true, minTlsVersion: '1.2', ftpsState: 'FtpsOnly'."
- }
- },
- "functionAppConfig": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Function App configuration object."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions."
- }
- },
- "storageAccountUseIdentityAuthentication": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. If the provided storage account requires Identity based authentication ('allowSharedKeyAccess' is set to false). When set to true, the minimum role assignment required for the App Service Managed Identity to the storage account is 'Storage Blob Data Owner'."
- }
- },
- "webConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Site Config, Web settings to deploy."
- }
- },
- "msDeployConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The extension MSDeployment configuration."
- }
- },
- "appInsightResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the app insight to leverage for this resource."
- }
- },
- "appSettingsKeyValuePairs": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING."
- }
- },
- "authSettingV2Configuration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The auth settings V2 configuration."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "logsConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The logs settings configuration."
- }
- },
- "privateEndpoints": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateEndpointSingleServiceType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible."
- }
- },
- "slots": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Configuration for deployment slots for an app."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "diagnosticSettings": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/diagnosticSettingFullType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- },
- "clientCertEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. To enable client certificate authentication (TLS mutual authentication)."
- }
- },
- "clientCertExclusionPaths": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Client certificate authentication comma-separated exclusion paths."
- }
- },
- "clientCertMode": {
- "type": "string",
- "defaultValue": "Optional",
- "allowedValues": [
- "Optional",
- "OptionalInteractiveUser",
- "Required"
- ],
- "metadata": {
- "description": "Optional. This composes with ClientCertEnabled setting.\n- ClientCertEnabled=false means ClientCert is ignored.\n- ClientCertEnabled=true and ClientCertMode=Required means ClientCert is required.\n- ClientCertEnabled=true and ClientCertMode=Optional means ClientCert is optional or accepted.\n"
- }
- },
- "cloningInfo": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. If specified during app creation, the app is cloned from a source app."
- }
- },
- "containerSize": {
- "type": "int",
- "nullable": true,
- "metadata": {
- "description": "Optional. Size of the function container."
- }
- },
- "dailyMemoryTimeQuota": {
- "type": "int",
- "nullable": true,
- "metadata": {
- "description": "Optional. Maximum allowed daily memory-time quota (applicable on dynamic apps only)."
- }
- },
- "enabled": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Setting this value to false disables the app (takes the app offline)."
- }
- },
- "hostNameSslStates": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Hostname SSL states are used to manage the SSL bindings for app's hostnames."
- }
- },
- "hyperV": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Hyper-V sandbox."
- }
- },
- "redundancyMode": {
- "type": "string",
- "defaultValue": "None",
- "allowedValues": [
- "ActiveActive",
- "Failover",
- "GeoRedundant",
- "Manual",
- "None"
- ],
- "metadata": {
- "description": "Optional. Site redundancy mode."
- }
- },
- "basicPublishingCredentialsPolicies": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. The site publishing credential policy names which are associated with the sites."
- }
- },
- "hybridConnectionRelays": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Names of hybrid connection relays to connect app with."
- }
- },
- "publicNetworkAccess": {
- "type": "string",
- "nullable": true,
- "allowedValues": [
- "Enabled",
- "Disabled"
- ],
- "metadata": {
- "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set."
- }
- },
- "e2eEncryptionEnabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. End to End Encryption Setting."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "enableReferencedModulesTelemetry": false,
- "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]",
- "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned, UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]",
- "builtInRoleNames": {
- "App Compliance Automation Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f37683f-2463-46b6-9ce7-9b788b988ba2')]",
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]",
- "Web Plan Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b')]",
- "Website Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.web-site.{0}.{1}', replace('0.15.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "app": {
- "type": "Microsoft.Web/sites",
- "apiVersion": "2024-04-01",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "kind": "[parameters('kind')]",
- "tags": "[parameters('tags')]",
- "identity": "[variables('identity')]",
- "properties": {
- "managedEnvironmentId": "[if(not(empty(parameters('managedEnvironmentId'))), parameters('managedEnvironmentId'), null())]",
- "serverFarmId": "[parameters('serverFarmResourceId')]",
- "clientAffinityEnabled": "[parameters('clientAffinityEnabled')]",
- "httpsOnly": "[parameters('httpsOnly')]",
- "hostingEnvironmentProfile": "[if(not(empty(parameters('appServiceEnvironmentResourceId'))), createObject('id', parameters('appServiceEnvironmentResourceId')), null())]",
- "storageAccountRequired": "[parameters('storageAccountRequired')]",
- "keyVaultReferenceIdentity": "[parameters('keyVaultAccessIdentityResourceId')]",
- "virtualNetworkSubnetId": "[parameters('virtualNetworkSubnetId')]",
- "siteConfig": "[parameters('siteConfig')]",
- "functionAppConfig": "[parameters('functionAppConfig')]",
- "clientCertEnabled": "[parameters('clientCertEnabled')]",
- "clientCertExclusionPaths": "[parameters('clientCertExclusionPaths')]",
- "clientCertMode": "[parameters('clientCertMode')]",
- "cloningInfo": "[parameters('cloningInfo')]",
- "containerSize": "[parameters('containerSize')]",
- "dailyMemoryTimeQuota": "[parameters('dailyMemoryTimeQuota')]",
- "enabled": "[parameters('enabled')]",
- "hostNameSslStates": "[parameters('hostNameSslStates')]",
- "hyperV": "[parameters('hyperV')]",
- "redundancyMode": "[parameters('redundancyMode')]",
- "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(not(empty(parameters('privateEndpoints'))), 'Disabled', 'Enabled'))]",
- "vnetContentShareEnabled": "[parameters('vnetContentShareEnabled')]",
- "vnetImagePullEnabled": "[parameters('vnetImagePullEnabled')]",
- "vnetRouteAllEnabled": "[parameters('vnetRouteAllEnabled')]",
- "scmSiteAlsoStopped": "[parameters('scmSiteAlsoStopped')]",
- "endToEndEncryptionEnabled": "[parameters('e2eEncryptionEnabled')]"
- }
- },
- "app_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Web/sites/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_diagnosticSettings": {
- "copy": {
- "name": "app_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Web/sites/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_roleAssignments": {
- "copy": {
- "name": "app_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Web/sites/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Web/sites', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_appsettings": {
- "condition": "[or(or(not(empty(parameters('appSettingsKeyValuePairs'))), not(empty(parameters('appInsightResourceId')))), not(empty(parameters('storageAccountResourceId'))))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Site-Config-AppSettings', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appName": {
- "value": "[parameters('name')]"
- },
- "kind": {
- "value": "[parameters('kind')]"
- },
- "storageAccountResourceId": {
- "value": "[parameters('storageAccountResourceId')]"
- },
- "storageAccountUseIdentityAuthentication": {
- "value": "[parameters('storageAccountUseIdentityAuthentication')]"
- },
- "appInsightResourceId": {
- "value": "[parameters('appInsightResourceId')]"
- },
- "appSettingsKeyValuePairs": {
- "value": "[parameters('appSettingsKeyValuePairs')]"
- },
- "currentAppSettings": "[if(not(empty(resourceId('Microsoft.Web/sites', parameters('name')))), createObject('value', list(format('{0}/config/appsettings', resourceId('Microsoft.Web/sites', parameters('name'))), '2023-12-01').properties), createObject('value', createObject()))]"
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "12262977018813780856"
- },
- "name": "Site App Settings",
- "description": "This module deploys a Site App Setting."
- },
- "parameters": {
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent site resource. Required if the template is used in a standalone deployment."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "functionapp",
- "functionapp,linux",
- "functionapp,workflowapp",
- "functionapp,workflowapp,linux",
- "functionapp,linux,container",
- "functionapp,linux,container,azurecontainerapps",
- "app,linux",
- "app",
- "linux,api",
- "api",
- "app,linux,container",
- "app,container,windows"
- ],
- "metadata": {
- "description": "Required. Type of site to deploy."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions."
- }
- },
- "storageAccountUseIdentityAuthentication": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. If the provided storage account requires Identity based authentication ('allowSharedKeyAccess' is set to false). When set to true, the minimum role assignment required for the App Service Managed Identity to the storage account is 'Storage Blob Data Owner'."
- }
- },
- "appInsightResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the app insight to leverage for this resource."
- }
- },
- "appSettingsKeyValuePairs": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The app settings key-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING."
- }
- },
- "currentAppSettings": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. The current app settings."
- }
- }
- },
- "resources": {
- "app": {
- "existing": true,
- "type": "Microsoft.Web/sites",
- "apiVersion": "2023-12-01",
- "name": "[parameters('appName')]"
- },
- "appInsight": {
- "condition": "[not(empty(parameters('appInsightResourceId')))]",
- "existing": true,
- "type": "Microsoft.Insights/components",
- "apiVersion": "2020-02-02",
- "subscriptionId": "[split(parameters('appInsightResourceId'), '/')[2]]",
- "resourceGroup": "[split(parameters('appInsightResourceId'), '/')[4]]",
- "name": "[last(split(parameters('appInsightResourceId'), '/'))]"
- },
- "storageAccount": {
- "condition": "[not(empty(parameters('storageAccountResourceId')))]",
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-05-01",
- "subscriptionId": "[split(parameters('storageAccountResourceId'), '/')[2]]",
- "resourceGroup": "[split(parameters('storageAccountResourceId'), '/')[4]]",
- "name": "[last(split(parameters('storageAccountResourceId'), '/'))]"
- },
- "appSettings": {
- "type": "Microsoft.Web/sites/config",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), 'appsettings')]",
- "kind": "[parameters('kind')]",
- "properties": "[union(coalesce(parameters('currentAppSettings'), createObject()), coalesce(parameters('appSettingsKeyValuePairs'), createObject()), if(and(not(empty(parameters('storageAccountResourceId'))), not(parameters('storageAccountUseIdentityAuthentication'))), createObject('AzureWebJobsStorage', format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}', last(split(parameters('storageAccountResourceId'), '/')), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('storageAccountResourceId'), '/')[2], split(parameters('storageAccountResourceId'), '/')[4]), 'Microsoft.Storage/storageAccounts', last(split(parameters('storageAccountResourceId'), '/'))), '2023-05-01').keys[0].value, environment().suffixes.storage)), if(and(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountUseIdentityAuthentication')), union(createObject('AzureWebJobsStorage__accountName', last(split(parameters('storageAccountResourceId'), '/'))), createObject('AzureWebJobsStorage__blobServiceUri', reference('storageAccount').primaryEndpoints.blob), createObject('AzureWebJobsStorage__queueServiceUri', reference('storageAccount').primaryEndpoints.queue), createObject('AzureWebJobsStorage__tableServiceUri', reference('storageAccount').primaryEndpoints.table)), createObject())), if(not(empty(parameters('appInsightResourceId'))), createObject('APPLICATIONINSIGHTS_CONNECTION_STRING', reference('appInsight').ConnectionString), createObject()))]",
- "dependsOn": [
- "appInsight",
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the site config."
- },
- "value": "appsettings"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the site config."
- },
- "value": "[resourceId('Microsoft.Web/sites/config', parameters('appName'), 'appsettings')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the site config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_authsettingsv2": {
- "condition": "[not(empty(parameters('authSettingV2Configuration')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Site-Config-AuthSettingsV2', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appName": {
- "value": "[parameters('name')]"
- },
- "kind": {
- "value": "[parameters('kind')]"
- },
- "authSettingV2Configuration": {
- "value": "[coalesce(parameters('authSettingV2Configuration'), createObject())]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "1129994114817101549"
- },
- "name": "Site Auth Settings V2 Config",
- "description": "This module deploys a Site Auth Settings V2 Configuration."
- },
- "parameters": {
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent site resource. Required if the template is used in a standalone deployment."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "functionapp",
- "functionapp,linux",
- "functionapp,workflowapp",
- "functionapp,workflowapp,linux",
- "functionapp,linux,container",
- "functionapp,linux,container,azurecontainerapps",
- "app,linux",
- "app",
- "linux,api",
- "api",
- "app,linux,container",
- "app,container,windows"
- ],
- "metadata": {
- "description": "Required. Type of site to deploy."
- }
- },
- "authSettingV2Configuration": {
- "type": "object",
- "metadata": {
- "description": "Required. The auth settings V2 configuration."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Web/sites/config",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), 'authsettingsV2')]",
- "kind": "[parameters('kind')]",
- "properties": "[parameters('authSettingV2Configuration')]"
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the site config."
- },
- "value": "authsettingsV2"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the site config."
- },
- "value": "[resourceId('Microsoft.Web/sites/config', parameters('appName'), 'authsettingsV2')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the site config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_logssettings": {
- "condition": "[not(empty(coalesce(parameters('logsConfiguration'), createObject())))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Site-Config-Logs', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appName": {
- "value": "[parameters('name')]"
- },
- "logsConfiguration": {
- "value": "[parameters('logsConfiguration')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "17967336872376441757"
- },
- "name": "Site logs Config",
- "description": "This module deploys a Site logs Configuration."
- },
- "parameters": {
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the parent site resource."
- }
- },
- "logsConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The logs settings configuration."
- }
- }
- },
- "resources": {
- "app": {
- "existing": true,
- "type": "Microsoft.Web/sites",
- "apiVersion": "2024-04-01",
- "name": "[parameters('appName')]"
- },
- "webSettings": {
- "type": "Microsoft.Web/sites/config",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), 'logs')]",
- "kind": "string",
- "properties": "[parameters('logsConfiguration')]"
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the site config."
- },
- "value": "logs"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the site config."
- },
- "value": "[resourceId('Microsoft.Web/sites/config', parameters('appName'), 'logs')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the site config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "app",
- "app_appsettings"
- ]
- },
- "app_websettings": {
- "condition": "[not(empty(coalesce(parameters('webConfiguration'), createObject())))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Site-Config-Web', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appName": {
- "value": "[parameters('name')]"
- },
- "webConfiguration": {
- "value": "[parameters('webConfiguration')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "15058680643544097487"
- },
- "name": "Site Web Config",
- "description": "This module deploys web settings configuration available under sites/config name: web."
- },
- "parameters": {
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the parent site resource."
- }
- },
- "webConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Site Config, Web settings to deploy."
- }
- }
- },
- "resources": {
- "app": {
- "existing": true,
- "type": "Microsoft.Web/sites",
- "apiVersion": "2024-04-01",
- "name": "[parameters('appName')]"
- },
- "webSettings": {
- "type": "Microsoft.Web/sites/config",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), 'web')]",
- "kind": "string",
- "properties": "[parameters('webConfiguration')]"
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the site config."
- },
- "value": "web"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the site config."
- },
- "value": "[resourceId('Microsoft.Web/sites/config', parameters('appName'), 'web')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the site config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- },
- "extension_msdeploy": {
- "condition": "[not(empty(parameters('msDeployConfiguration')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Site-Extension-MSDeploy', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appName": {
- "value": "[parameters('name')]"
- },
- "msDeployConfiguration": {
- "value": "[coalesce(parameters('msDeployConfiguration'), createObject())]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "14895622660217616811"
- },
- "name": "Site Deployment Extension ",
- "description": "This module deploys a Site extension for MSDeploy."
- },
- "parameters": {
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the parent site resource."
- }
- },
- "msDeployConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Sets the MSDeployment Properties."
- }
- }
- },
- "resources": {
- "app": {
- "existing": true,
- "type": "Microsoft.Web/sites",
- "apiVersion": "2024-04-01",
- "name": "[parameters('appName')]"
- },
- "msdeploy": {
- "type": "Microsoft.Web/sites/extensions",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), 'MSDeploy')]",
- "kind": "MSDeploy",
- "properties": "[parameters('msDeployConfiguration')]"
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the MSDeploy Package."
- },
- "value": "MSDeploy"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the Site Extension."
- },
- "value": "[resourceId('Microsoft.Web/sites/extensions', parameters('appName'), 'MSDeploy')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the site config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_slots": {
- "copy": {
- "name": "app_slots",
- "count": "[length(coalesce(parameters('slots'), createArray()))]",
- "mode": "serial",
- "batchSize": 1
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Slot-{1}', uniqueString(deployment().name, parameters('location')), coalesce(parameters('slots'), createArray())[copyIndex()].name)]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[coalesce(parameters('slots'), createArray())[copyIndex()].name]"
- },
- "appName": {
- "value": "[parameters('name')]"
- },
- "location": {
- "value": "[parameters('location')]"
- },
- "kind": {
- "value": "[parameters('kind')]"
- },
- "serverFarmResourceId": {
- "value": "[parameters('serverFarmResourceId')]"
- },
- "httpsOnly": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'httpsOnly'), parameters('httpsOnly'))]"
- },
- "appServiceEnvironmentResourceId": {
- "value": "[parameters('appServiceEnvironmentResourceId')]"
- },
- "clientAffinityEnabled": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'clientAffinityEnabled'), parameters('clientAffinityEnabled'))]"
- },
- "managedIdentities": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'managedIdentities'), parameters('managedIdentities'))]"
- },
- "keyVaultAccessIdentityResourceId": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'keyVaultAccessIdentityResourceId'), parameters('keyVaultAccessIdentityResourceId'))]"
- },
- "storageAccountRequired": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'storageAccountRequired'), parameters('storageAccountRequired'))]"
- },
- "virtualNetworkSubnetId": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'virtualNetworkSubnetId'), parameters('virtualNetworkSubnetId'))]"
- },
- "siteConfig": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'siteConfig'), parameters('siteConfig'))]"
- },
- "functionAppConfig": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'functionAppConfig'), parameters('functionAppConfig'))]"
- },
- "storageAccountResourceId": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'storageAccountResourceId'), parameters('storageAccountResourceId'))]"
- },
- "storageAccountUseIdentityAuthentication": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'storageAccountUseIdentityAuthentication'), parameters('storageAccountUseIdentityAuthentication'))]"
- },
- "appInsightResourceId": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'appInsightResourceId'), parameters('appInsightResourceId'))]"
- },
- "authSettingV2Configuration": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'authSettingV2Configuration'), parameters('authSettingV2Configuration'))]"
- },
- "msDeployConfiguration": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'msDeployConfiguration'), parameters('msDeployConfiguration'))]"
- },
- "diagnosticSettings": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'diagnosticSettings')]"
- },
- "roleAssignments": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'roleAssignments')]"
- },
- "appSettingsKeyValuePairs": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'appSettingsKeyValuePairs'), parameters('appSettingsKeyValuePairs'))]"
- },
- "basicPublishingCredentialsPolicies": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'basicPublishingCredentialsPolicies'), parameters('basicPublishingCredentialsPolicies'))]"
- },
- "lock": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'lock'), parameters('lock'))]"
- },
- "privateEndpoints": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'privateEndpoints'), createArray())]"
- },
- "tags": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
- },
- "clientCertEnabled": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'clientCertEnabled')]"
- },
- "clientCertExclusionPaths": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'clientCertExclusionPaths')]"
- },
- "clientCertMode": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'clientCertMode')]"
- },
- "cloningInfo": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'cloningInfo')]"
- },
- "containerSize": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'containerSize')]"
- },
- "customDomainVerificationId": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'customDomainVerificationId')]"
- },
- "dailyMemoryTimeQuota": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'dailyMemoryTimeQuota')]"
- },
- "enabled": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'enabled')]"
- },
- "hostNameSslStates": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'hostNameSslStates')]"
- },
- "hyperV": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'hyperV')]"
- },
- "publicNetworkAccess": {
- "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'publicNetworkAccess'), if(or(not(empty(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'privateEndpoints'))), not(empty(parameters('privateEndpoints')))), 'Disabled', 'Enabled'))]"
- },
- "redundancyMode": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'redundancyMode')]"
- },
- "vnetContentShareEnabled": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'vnetContentShareEnabled')]"
- },
- "vnetImagePullEnabled": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'vnetImagePullEnabled')]"
- },
- "vnetRouteAllEnabled": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'vnetRouteAllEnabled')]"
- },
- "hybridConnectionRelays": {
- "value": "[tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'hybridConnectionRelays')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "4067755327331248181"
- },
- "name": "Web/Function App Deployment Slots",
- "description": "This module deploys a Web or Function App Deployment Slot."
- },
- "definitions": {
- "privateEndpointOutputType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint."
- }
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint."
- }
- },
- "groupId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "The group Id for the private endpoint Group."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "A list of private IP addresses of the private endpoint."
- }
- }
- }
- },
- "metadata": {
- "description": "The custom DNS configurations of the private endpoint."
- }
- },
- "networkInterfaceResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "The IDs of the network interfaces associated with the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "_1.privateEndpointCustomDnsConfigType": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. A list of private IP addresses of the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "_1.privateEndpointIpConfigurationType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource that is unique within a resource group."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to."
- }
- },
- "memberName": {
- "type": "string",
- "metadata": {
- "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to."
- }
- },
- "privateIPAddress": {
- "type": "string",
- "metadata": {
- "description": "Required. A private IP address obtained from the private endpoint's subnet."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private endpoint IP configurations."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "_1.privateEndpointPrivateDnsZoneGroupType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private DNS Zone Group."
- }
- },
- "privateDnsZoneGroupConfigs": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS Zone Group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- }
- },
- "metadata": {
- "description": "Required. The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "diagnosticSettingFullType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the diagnostic setting."
- }
- },
- "logCategoriesAndGroups": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here."
- }
- },
- "categoryGroup": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection."
- }
- },
- "metricCategories": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "category": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics."
- }
- },
- "enabled": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable or disable the category explicitly. Default is `true`."
- }
- }
- }
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection."
- }
- },
- "logAnalyticsDestinationType": {
- "type": "string",
- "allowedValues": [
- "AzureDiagnostics",
- "Dedicated"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type."
- }
- },
- "workspaceResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "eventHubAuthorizationRuleResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
- }
- },
- "eventHubName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
- }
- },
- "marketplacePartnerResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a lock.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "managedIdentityAllType": {
- "type": "object",
- "properties": {
- "systemAssigned": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enables system assigned managed identity on the resource."
- }
- },
- "userAssignedResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "privateEndpointSingleServiceType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private Endpoint."
- }
- },
- "location": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The location to deploy the Private Endpoint to."
- }
- },
- "privateLinkServiceConnectionName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private link connection to create."
- }
- },
- "service": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The subresource to deploy the Private Endpoint for. For example \"vault\" for a Key Vault Private Endpoint."
- }
- },
- "subnetResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
- }
- },
- "resourceGroupResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used."
- }
- },
- "privateDnsZoneGroup": {
- "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The private DNS Zone Group to configure for the Private Endpoint."
- }
- },
- "isManualConnection": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. If Manual Private Link Connection is required."
- }
- },
- "manualConnectionRequestMessage": {
- "type": "string",
- "nullable": true,
- "maxLength": 140,
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with the manual connection request."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Custom DNS configurations."
- }
- },
- "ipConfigurations": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/_1.privateEndpointIpConfigurationType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints."
- }
- },
- "applicationSecurityGroupResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Application security groups in which the Private Endpoint IP configuration is included."
- }
- },
- "customNetworkInterfaceName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The custom name of the network interface attached to the Private Endpoint."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to be applied on all resources/Resource Groups in this deployment."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the slot."
- }
- },
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent site resource. Required if the template is used in a standalone deployment."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "functionapp",
- "functionapp,linux",
- "functionapp,workflowapp",
- "functionapp,workflowapp,linux",
- "functionapp,linux,container",
- "functionapp,linux,container,azurecontainerapps",
- "app,linux",
- "app",
- "linux,api",
- "api",
- "app,linux,container",
- "app,container,windows"
- ],
- "metadata": {
- "description": "Required. Type of site to deploy."
- }
- },
- "serverFarmResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID of the app service plan to use for the slot."
- }
- },
- "httpsOnly": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Configures a slot to accept only HTTPS requests. Issues redirect for HTTP requests."
- }
- },
- "clientAffinityEnabled": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. If client affinity is enabled."
- }
- },
- "appServiceEnvironmentResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID of the app service environment to use for this resource."
- }
- },
- "managedIdentities": {
- "$ref": "#/definitions/managedIdentityAllType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The managed identity definition for this resource."
- }
- },
- "keyVaultAccessIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource ID of the assigned identity to be used to access a key vault with."
- }
- },
- "storageAccountRequired": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Checks if Customer provided storage account is required."
- }
- },
- "virtualNetworkSubnetId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Azure Resource Manager ID of the Virtual network and subnet to be joined by Regional VNET Integration. This must be of the form /subscriptions/{subscriptionName}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}/subnets/{subnetName}."
- }
- },
- "siteConfig": {
- "type": "object",
- "defaultValue": {
- "alwaysOn": true
- },
- "metadata": {
- "description": "Optional. The site config object."
- }
- },
- "functionAppConfig": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Function App config object."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions."
- }
- },
- "storageAccountUseIdentityAuthentication": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. If the provided storage account requires Identity based authentication ('allowSharedKeyAccess' is set to false). When set to true, the minimum role assignment required for the App Service Managed Identity to the storage account is 'Storage Blob Data Owner'."
- }
- },
- "appInsightResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the app insight to leverage for this resource."
- }
- },
- "appSettingsKeyValuePairs": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING."
- }
- },
- "authSettingV2Configuration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The auth settings V2 configuration."
- }
- },
- "msDeployConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The extension MSDeployment configuration."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "privateEndpoints": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateEndpointSingleServiceType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Configuration details for private endpoints."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags of the resource."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "diagnosticSettings": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/diagnosticSettingFullType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The diagnostic settings of the service."
- }
- },
- "clientCertEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. To enable client certificate authentication (TLS mutual authentication)."
- }
- },
- "clientCertExclusionPaths": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Client certificate authentication comma-separated exclusion paths."
- }
- },
- "clientCertMode": {
- "type": "string",
- "defaultValue": "Optional",
- "allowedValues": [
- "Optional",
- "OptionalInteractiveUser",
- "Required"
- ],
- "metadata": {
- "description": "Optional. This composes with ClientCertEnabled setting.
- ClientCertEnabled: false means ClientCert is ignored.- ClientCertEnabled: true and ClientCertMode: Required means ClientCert is required.- ClientCertEnabled: true and ClientCertMode: Optional means ClientCert is optional or accepted."
- }
- },
- "cloningInfo": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. If specified during app creation, the app is cloned from a source app."
- }
- },
- "containerSize": {
- "type": "int",
- "nullable": true,
- "metadata": {
- "description": "Optional. Size of the function container."
- }
- },
- "customDomainVerificationId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Unique identifier that verifies the custom domains assigned to the app. Customer will add this ID to a txt record for verification."
- }
- },
- "dailyMemoryTimeQuota": {
- "type": "int",
- "nullable": true,
- "metadata": {
- "description": "Optional. Maximum allowed daily memory-time quota (applicable on dynamic apps only)."
- }
- },
- "enabled": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Setting this value to false disables the app (takes the app offline)."
- }
- },
- "hostNameSslStates": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Hostname SSL states are used to manage the SSL bindings for app's hostnames."
- }
- },
- "hyperV": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Hyper-V sandbox."
- }
- },
- "publicNetworkAccess": {
- "type": "string",
- "nullable": true,
- "allowedValues": [
- "Enabled",
- "Disabled"
- ],
- "metadata": {
- "description": "Optional. Allow or block all public traffic."
- }
- },
- "redundancyMode": {
- "type": "string",
- "defaultValue": "None",
- "allowedValues": [
- "ActiveActive",
- "Failover",
- "GeoRedundant",
- "Manual",
- "None"
- ],
- "metadata": {
- "description": "Optional. Site redundancy mode."
- }
- },
- "basicPublishingCredentialsPolicies": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. The site publishing credential policy names which are associated with the site slot."
- }
- },
- "vnetContentShareEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. To enable accessing content over virtual network."
- }
- },
- "vnetImagePullEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. To enable pulling image over Virtual Network."
- }
- },
- "vnetRouteAllEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Virtual Network Route All enabled. This causes all outbound traffic to have Virtual Network Security Groups and User Defined Routes applied."
- }
- },
- "hybridConnectionRelays": {
- "type": "array",
- "nullable": true,
- "metadata": {
- "description": "Optional. Names of hybrid connection relays to connect app with."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "enableReferencedModulesTelemetry": false,
- "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]",
- "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned, UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]",
- "builtInRoleNames": {
- "App Compliance Automation Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f37683f-2463-46b6-9ce7-9b788b988ba2')]",
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]",
- "Web Plan Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b')]",
- "Website Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772')]"
- }
- },
- "resources": {
- "app": {
- "existing": true,
- "type": "Microsoft.Web/sites",
- "apiVersion": "2024-04-01",
- "name": "[parameters('appName')]"
- },
- "slot": {
- "type": "Microsoft.Web/sites/slots",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), parameters('name'))]",
- "location": "[parameters('location')]",
- "kind": "[parameters('kind')]",
- "tags": "[parameters('tags')]",
- "identity": "[variables('identity')]",
- "properties": {
- "serverFarmId": "[parameters('serverFarmResourceId')]",
- "clientAffinityEnabled": "[parameters('clientAffinityEnabled')]",
- "httpsOnly": "[parameters('httpsOnly')]",
- "hostingEnvironmentProfile": "[if(not(empty(parameters('appServiceEnvironmentResourceId'))), createObject('id', parameters('appServiceEnvironmentResourceId')), null())]",
- "storageAccountRequired": "[parameters('storageAccountRequired')]",
- "keyVaultReferenceIdentity": "[parameters('keyVaultAccessIdentityResourceId')]",
- "virtualNetworkSubnetId": "[parameters('virtualNetworkSubnetId')]",
- "siteConfig": "[parameters('siteConfig')]",
- "functionAppConfig": "[parameters('functionAppConfig')]",
- "clientCertEnabled": "[parameters('clientCertEnabled')]",
- "clientCertExclusionPaths": "[parameters('clientCertExclusionPaths')]",
- "clientCertMode": "[parameters('clientCertMode')]",
- "cloningInfo": "[parameters('cloningInfo')]",
- "containerSize": "[parameters('containerSize')]",
- "customDomainVerificationId": "[parameters('customDomainVerificationId')]",
- "dailyMemoryTimeQuota": "[parameters('dailyMemoryTimeQuota')]",
- "enabled": "[parameters('enabled')]",
- "hostNameSslStates": "[parameters('hostNameSslStates')]",
- "hyperV": "[parameters('hyperV')]",
- "publicNetworkAccess": "[parameters('publicNetworkAccess')]",
- "redundancyMode": "[parameters('redundancyMode')]",
- "vnetContentShareEnabled": "[parameters('vnetContentShareEnabled')]",
- "vnetImagePullEnabled": "[parameters('vnetImagePullEnabled')]",
- "vnetRouteAllEnabled": "[parameters('vnetRouteAllEnabled')]"
- }
- },
- "slot_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Web/sites/{0}/slots/{1}', parameters('appName'), parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "slot"
- ]
- },
- "slot_diagnosticSettings": {
- "copy": {
- "name": "slot_diagnosticSettings",
- "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]"
- },
- "type": "Microsoft.Insights/diagnosticSettings",
- "apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.Web/sites/{0}/slots/{1}', parameters('appName'), parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
- "properties": {
- "copy": [
- {
- "name": "metrics",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]",
- "input": {
- "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]",
- "timeGrain": null
- }
- },
- {
- "name": "logs",
- "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]",
- "input": {
- "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]",
- "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]",
- "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]"
- }
- }
- ],
- "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]",
- "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]",
- "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]",
- "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]",
- "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]",
- "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]"
- },
- "dependsOn": [
- "slot"
- ]
- },
- "slot_roleAssignments": {
- "copy": {
- "name": "slot_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Web/sites/{0}/slots/{1}', parameters('appName'), parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Web/sites/slots', parameters('appName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "slot"
- ]
- },
- "slot_appsettings": {
- "condition": "[or(or(not(empty(parameters('appSettingsKeyValuePairs'))), not(empty(parameters('appInsightResourceId')))), not(empty(parameters('storageAccountResourceId'))))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Slot-{1}-Config-AppSettings', uniqueString(deployment().name, parameters('location')), parameters('name'))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "slotName": {
- "value": "[parameters('name')]"
- },
- "appName": {
- "value": "[parameters('appName')]"
- },
- "kind": {
- "value": "[parameters('kind')]"
- },
- "storageAccountResourceId": {
- "value": "[parameters('storageAccountResourceId')]"
- },
- "storageAccountUseIdentityAuthentication": {
- "value": "[parameters('storageAccountUseIdentityAuthentication')]"
- },
- "appInsightResourceId": {
- "value": "[parameters('appInsightResourceId')]"
- },
- "appSettingsKeyValuePairs": {
- "value": "[parameters('appSettingsKeyValuePairs')]"
- },
- "currentAppSettings": "[if(not(empty(resourceId('Microsoft.Web/sites/slots', parameters('appName'), parameters('name')))), createObject('value', list(format('{0}/config/appsettings', resourceId('Microsoft.Web/sites/slots', parameters('appName'), parameters('name'))), '2023-12-01').properties), createObject('value', createObject()))]"
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "18192409627790392598"
- },
- "name": "Site Slot App Settings",
- "description": "This module deploys a Site Slot App Setting."
- },
- "parameters": {
- "slotName": {
- "type": "string",
- "metadata": {
- "description": "Required. Slot name to be configured."
- }
- },
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent site resource. Required if the template is used in a standalone deployment."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "functionapp",
- "functionapp,linux",
- "functionapp,workflowapp",
- "functionapp,workflowapp,linux",
- "functionapp,linux,container",
- "functionapp,linux,container,azurecontainerapps",
- "app,linux",
- "app",
- "linux,api",
- "api",
- "app,linux,container",
- "app,container,windows"
- ],
- "metadata": {
- "description": "Required. Type of site to deploy."
- }
- },
- "storageAccountResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions."
- }
- },
- "storageAccountUseIdentityAuthentication": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. If the provided storage account requires Identity based authentication ('allowSharedKeyAccess' is set to false). When set to true, the minimum role assignment required for the App Service Managed Identity to the storage account is 'Storage Blob Data Owner'."
- }
- },
- "appInsightResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Resource ID of the app insight to leverage for this resource."
- }
- },
- "appSettingsKeyValuePairs": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. The app settings key-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING."
- }
- },
- "currentAppSettings": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Optional. The current app settings."
- }
- }
- },
- "resources": {
- "app::slot": {
- "existing": true,
- "type": "Microsoft.Web/sites/slots",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), parameters('slotName'))]"
- },
- "app": {
- "existing": true,
- "type": "Microsoft.Web/sites",
- "apiVersion": "2024-04-01",
- "name": "[parameters('appName')]"
- },
- "appInsight": {
- "condition": "[not(empty(parameters('appInsightResourceId')))]",
- "existing": true,
- "type": "Microsoft.Insights/components",
- "apiVersion": "2020-02-02",
- "subscriptionId": "[split(parameters('appInsightResourceId'), '/')[2]]",
- "resourceGroup": "[split(parameters('appInsightResourceId'), '/')[4]]",
- "name": "[last(split(parameters('appInsightResourceId'), '/'))]"
- },
- "storageAccount": {
- "condition": "[not(empty(parameters('storageAccountResourceId')))]",
- "existing": true,
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2023-05-01",
- "subscriptionId": "[split(parameters('storageAccountResourceId'), '/')[2]]",
- "resourceGroup": "[split(parameters('storageAccountResourceId'), '/')[4]]",
- "name": "[last(split(parameters('storageAccountResourceId'), '/'))]"
- },
- "slotSettings": {
- "type": "Microsoft.Web/sites/slots/config",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}/{2}', parameters('appName'), parameters('slotName'), 'appsettings')]",
- "kind": "[parameters('kind')]",
- "properties": "[union(coalesce(parameters('currentAppSettings'), createObject()), coalesce(parameters('appSettingsKeyValuePairs'), createObject()), if(and(not(empty(parameters('storageAccountResourceId'))), not(parameters('storageAccountUseIdentityAuthentication'))), createObject('AzureWebJobsStorage', format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}', last(split(parameters('storageAccountResourceId'), '/')), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('storageAccountResourceId'), '/')[2], split(parameters('storageAccountResourceId'), '/')[4]), 'Microsoft.Storage/storageAccounts', last(split(parameters('storageAccountResourceId'), '/'))), '2023-05-01').keys[0].value, environment().suffixes.storage)), if(and(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountUseIdentityAuthentication')), union(createObject('AzureWebJobsStorage__accountName', last(split(parameters('storageAccountResourceId'), '/'))), createObject('AzureWebJobsStorage__blobServiceUri', reference('storageAccount').primaryEndpoints.blob)), createObject())), if(not(empty(parameters('appInsightResourceId'))), createObject('APPLICATIONINSIGHTS_CONNECTION_STRING', reference('appInsight').ConnectionString), createObject()))]",
- "dependsOn": [
- "appInsight",
- "storageAccount"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the slot config."
- },
- "value": "appsettings"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the slot config."
- },
- "value": "[resourceId('Microsoft.Web/sites/slots/config', parameters('appName'), parameters('slotName'), 'appsettings')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the slot config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "slot"
- ]
- },
- "slot_authsettingsv2": {
- "condition": "[not(empty(parameters('authSettingV2Configuration')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Slot-{1}-Config-AuthSettingsV2', uniqueString(deployment().name, parameters('location')), parameters('name'))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "slotName": {
- "value": "[parameters('name')]"
- },
- "appName": {
- "value": "[parameters('appName')]"
- },
- "kind": {
- "value": "[parameters('kind')]"
- },
- "authSettingV2Configuration": {
- "value": "[coalesce(parameters('authSettingV2Configuration'), createObject())]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "4602741618711602070"
- },
- "name": "Site Slot Auth Settings V2 Config",
- "description": "This module deploys a Site Auth Settings V2 Configuration."
- },
- "parameters": {
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent site resource. Required if the template is used in a standalone deployment."
- }
- },
- "slotName": {
- "type": "string",
- "metadata": {
- "description": "Required. Slot name to be configured."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "functionapp",
- "functionapp,linux",
- "functionapp,workflowapp",
- "functionapp,workflowapp,linux",
- "functionapp,linux,container",
- "functionapp,linux,container,azurecontainerapps",
- "app,linux",
- "app",
- "linux,api",
- "api",
- "app,linux,container",
- "app,container,windows"
- ],
- "metadata": {
- "description": "Required. Type of site to deploy."
- }
- },
- "authSettingV2Configuration": {
- "type": "object",
- "metadata": {
- "description": "Required. The auth settings V2 configuration."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Web/sites/slots/config",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}/{2}', parameters('appName'), parameters('slotName'), 'authsettingsV2')]",
- "kind": "[parameters('kind')]",
- "properties": "[parameters('authSettingV2Configuration')]"
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the slot config."
- },
- "value": "authsettingsV2"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the slot config."
- },
- "value": "[resourceId('Microsoft.Web/sites/slots/config', parameters('appName'), parameters('slotName'), 'authsettingsV2')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the slot config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "slot"
- ]
- },
- "slot_basicPublishingCredentialsPolicies": {
- "copy": {
- "name": "slot_basicPublishingCredentialsPolicies",
- "count": "[length(coalesce(parameters('basicPublishingCredentialsPolicies'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Slot-Publish-Cred-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appName": {
- "value": "[parameters('appName')]"
- },
- "slotName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[coalesce(parameters('basicPublishingCredentialsPolicies'), createArray())[copyIndex()].name]"
- },
- "allow": {
- "value": "[tryGet(coalesce(parameters('basicPublishingCredentialsPolicies'), createArray())[copyIndex()], 'allow')]"
- },
- "location": {
- "value": "[parameters('location')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "8803130402255189673"
- },
- "name": "Web Site Slot Basic Publishing Credentials Policies",
- "description": "This module deploys a Web Site Slot Basic Publishing Credentials Policy."
- },
- "parameters": {
- "name": {
- "type": "string",
- "allowedValues": [
- "scm",
- "ftp"
- ],
- "metadata": {
- "description": "Required. The name of the resource."
- }
- },
- "allow": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Set to true to enable or false to disable a publishing method."
- }
- },
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent web site. Required if the template is used in a standalone deployment."
- }
- },
- "slotName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent web site slot. Required if the template is used in a standalone deployment."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}/{2}', parameters('appName'), parameters('slotName'), parameters('name'))]",
- "location": "[parameters('location')]",
- "properties": {
- "allow": "[parameters('allow')]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the basic publishing credential policy."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the basic publishing credential policy."
- },
- "value": "[resourceId('Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies', parameters('appName'), parameters('slotName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the basic publishing credential policy was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference(resourceId('Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies', parameters('appName'), parameters('slotName'), parameters('name')), '2024-04-01', 'full').location]"
- }
- }
- }
- },
- "dependsOn": [
- "slot"
- ]
- },
- "slot_hybridConnectionRelays": {
- "copy": {
- "name": "slot_hybridConnectionRelays",
- "count": "[length(coalesce(parameters('hybridConnectionRelays'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Slot-HybridConnectionRelay-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "hybridConnectionResourceId": {
- "value": "[coalesce(parameters('hybridConnectionRelays'), createArray())[copyIndex()].resourceId]"
- },
- "appName": {
- "value": "[parameters('appName')]"
- },
- "slotName": {
- "value": "[parameters('name')]"
- },
- "sendKeyName": {
- "value": "[tryGet(coalesce(parameters('hybridConnectionRelays'), createArray())[copyIndex()], 'sendKeyName')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "16445776675656358479"
- },
- "name": "Web/Function Apps Slot Hybrid Connection Relay",
- "description": "This module deploys a Site Slot Hybrid Connection Namespace Relay."
- },
- "parameters": {
- "hybridConnectionResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource ID of the relay namespace hybrid connection."
- }
- },
- "slotName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the site slot. Required if the template is used in a standalone deployment."
- }
- },
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent web site. Required if the template is used in a standalone deployment."
- }
- },
- "sendKeyName": {
- "type": "string",
- "defaultValue": "defaultSender",
- "metadata": {
- "description": "Optional. Name of the authorization rule send key to use."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}/{2}/{3}', parameters('appName'), parameters('slotName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10])]",
- "properties": {
- "serviceBusNamespace": "[split(parameters('hybridConnectionResourceId'), '/')[8]]",
- "serviceBusSuffix": "[split(substring(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces', split(parameters('hybridConnectionResourceId'), '/')[8]), '2021-11-01').serviceBusEndpoint, indexOf(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces', split(parameters('hybridConnectionResourceId'), '/')[8]), '2021-11-01').serviceBusEndpoint, '.servicebus')), ':')[0]]",
- "relayName": "[split(parameters('hybridConnectionResourceId'), '/')[10]]",
- "relayArmUri": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10])]",
- "hostname": "[split(json(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '2021-11-01').userMetadata)[0].value, ':')[0]]",
- "port": "[int(split(json(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '2021-11-01').userMetadata)[0].value, ':')[1])]",
- "sendKeyName": "[parameters('sendKeyName')]",
- "sendKeyValue": "[listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections/authorizationRules', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10], parameters('sendKeyName')), '2021-11-01').primaryKey]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the hybrid connection relay.."
- },
- "value": "[format('{0}/{1}/{2}/{3}', parameters('appName'), parameters('slotName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10])]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the hybrid connection relay."
- },
- "value": "[resourceId('Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays', split(format('{0}/{1}/{2}/{3}', parameters('appName'), parameters('slotName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '/')[0], split(format('{0}/{1}/{2}/{3}', parameters('appName'), parameters('slotName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '/')[1], split(format('{0}/{1}/{2}/{3}', parameters('appName'), parameters('slotName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '/')[2], split(format('{0}/{1}/{2}/{3}', parameters('appName'), parameters('slotName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '/')[3])]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the resource was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "slot"
- ]
- },
- "slot_extensionMSdeploy": {
- "condition": "[not(empty(parameters('msDeployConfiguration')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Site-Extension-MSDeploy', uniqueString(deployment().name, parameters('location')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "appName": {
- "value": "[parameters('appName')]"
- },
- "msDeployConfiguration": {
- "value": "[coalesce(parameters('msDeployConfiguration'), createObject())]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "14895622660217616811"
- },
- "name": "Site Deployment Extension ",
- "description": "This module deploys a Site extension for MSDeploy."
- },
- "parameters": {
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the parent site resource."
- }
- },
- "msDeployConfiguration": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Sets the MSDeployment Properties."
- }
- }
- },
- "resources": {
- "app": {
- "existing": true,
- "type": "Microsoft.Web/sites",
- "apiVersion": "2024-04-01",
- "name": "[parameters('appName')]"
- },
- "msdeploy": {
- "type": "Microsoft.Web/sites/extensions",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('appName'), 'MSDeploy')]",
- "kind": "MSDeploy",
- "properties": "[parameters('msDeployConfiguration')]"
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the MSDeploy Package."
- },
- "value": "MSDeploy"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the Site Extension."
- },
- "value": "[resourceId('Microsoft.Web/sites/extensions', parameters('appName'), 'MSDeploy')]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the site config was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- }
- },
- "slot_privateEndpoints": {
- "copy": {
- "name": "slot_privateEndpoints",
- "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-slot-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), resourceGroup().id), '/')[2]]",
- "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), resourceGroup().id), '/')[4]]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Web/sites', parameters('appName')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), format('sites-{0}', parameters('name'))), copyIndex()))]"
- },
- "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Web/sites', parameters('appName')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), format('sites-{0}', parameters('name'))), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Web/sites', parameters('appName')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), format('sites-{0}', parameters('name')))))))), createObject('value', null()))]",
- "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Web/sites', parameters('appName')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), format('sites-{0}', parameters('name'))), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Web/sites', parameters('appName')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), format('sites-{0}', parameters('name')))), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
- "subnetResourceId": {
- "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]"
- },
- "enableTelemetry": {
- "value": "[variables('enableReferencedModulesTelemetry')]"
- },
- "location": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]"
- },
- "lock": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]"
- },
- "privateDnsZoneGroup": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]"
- },
- "roleAssignments": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]"
- },
- "tags": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
- },
- "customDnsConfigs": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]"
- },
- "ipConfigurations": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]"
- },
- "applicationSecurityGroupResourceIds": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]"
- },
- "customNetworkInterfaceName": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.13.18514",
- "templateHash": "15954548978129725136"
- },
- "name": "Private Endpoints",
- "description": "This module deploys a Private Endpoint."
- },
- "definitions": {
- "privateDnsZoneGroupType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private DNS Zone Group."
- }
- },
- "privateDnsZoneGroupConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateDnsZoneGroupConfigType"
- },
- "metadata": {
- "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "ipConfigurationType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource that is unique within a resource group."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "memberName": {
- "type": "string",
- "metadata": {
- "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "privateIPAddress": {
- "type": "string",
- "metadata": {
- "description": "Required. A private IP address obtained from the private endpoint's subnet."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private endpoint IP configurations."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "privateLinkServiceConnectionType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the private link service connection."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
- }
- },
- "privateLinkServiceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of private link service."
- }
- },
- "requestMessage": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private link service connection."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "customDnsConfigType": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. A list of private IP addresses of the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a lock.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "privateDnsZoneGroupConfigType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS zone group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "private-dns-zone-group/main.bicep"
- }
- }
- },
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the private endpoint resource to create."
- }
- },
- "subnetResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
- }
- },
- "applicationSecurityGroupResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Application security groups in which the private endpoint IP configuration is included."
- }
- },
- "customNetworkInterfaceName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The custom name of the network interface attached to the private endpoint."
- }
- },
- "ipConfigurations": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/ipConfigurationType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
- }
- },
- "privateDnsZoneGroup": {
- "$ref": "#/definitions/privateDnsZoneGroupType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The private DNS zone group to configure for the private endpoint."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to be applied on all resources/resource groups in this deployment."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/customDnsConfigType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Custom DNS configurations."
- }
- },
- "manualPrivateLinkServiceConnections": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateLinkServiceConnectionType"
- },
- "nullable": true,
- "metadata": {
- "description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty."
- }
- },
- "privateLinkServiceConnections": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateLinkServiceConnectionType"
- },
- "nullable": true,
- "metadata": {
- "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]",
- "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]",
- "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]",
- "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]",
- "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "privateEndpoint": {
- "type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2023-11-01",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "copy": [
- {
- "name": "applicationSecurityGroups",
- "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]",
- "input": {
- "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]"
- }
- }
- ],
- "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]",
- "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]",
- "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]",
- "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]",
- "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]",
- "subnet": {
- "id": "[parameters('subnetResourceId')]"
- }
- }
- },
- "privateEndpoint_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- },
- "privateEndpoint_roleAssignments": {
- "copy": {
- "name": "privateEndpoint_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- },
- "privateEndpoint_privateDnsZoneGroup": {
- "condition": "[not(empty(parameters('privateDnsZoneGroup')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]"
- },
- "privateEndpointName": {
- "value": "[parameters('name')]"
- },
- "privateDnsZoneConfigs": {
- "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.13.18514",
- "templateHash": "5440815542537978381"
- },
- "name": "Private Endpoint Private DNS Zone Groups",
- "description": "This module deploys a Private Endpoint Private DNS Zone Group."
- },
- "definitions": {
- "privateDnsZoneGroupConfigType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS zone group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- }
- },
- "parameters": {
- "privateEndpointName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment."
- }
- },
- "privateDnsZoneConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateDnsZoneGroupConfigType"
- },
- "minLength": 1,
- "maxLength": 5,
- "metadata": {
- "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones."
- }
- },
- "name": {
- "type": "string",
- "defaultValue": "default",
- "metadata": {
- "description": "Optional. The name of the private DNS zone group."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "privateDnsZoneConfigsVar",
- "count": "[length(parameters('privateDnsZoneConfigs'))]",
- "input": {
- "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]",
- "properties": {
- "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]"
- }
- }
- }
- ]
- },
- "resources": {
- "privateEndpoint": {
- "existing": true,
- "type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2023-11-01",
- "name": "[parameters('privateEndpointName')]"
- },
- "privateDnsZoneGroup": {
- "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
- "apiVersion": "2023-11-01",
- "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]",
- "properties": {
- "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]"
- }
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint DNS zone group."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint DNS zone group."
- },
- "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the private endpoint DNS zone group was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- }
- },
- "outputs": {
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the private endpoint was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint."
- },
- "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint."
- },
- "value": "[parameters('name')]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]"
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/customDnsConfigType"
- },
- "metadata": {
- "description": "The custom DNS configurations of the private endpoint."
- },
- "value": "[reference('privateEndpoint').customDnsConfigs]"
- },
- "networkInterfaceResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "The resource IDs of the network interfaces associated with the private endpoint."
- },
- "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]"
- },
- "groupId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "The group Id for the private endpoint Group."
- },
- "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]"
- }
- }
- }
- },
- "dependsOn": [
- "slot"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the slot."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the slot."
- },
- "value": "[resourceId('Microsoft.Web/sites/slots', parameters('appName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the slot was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "systemAssignedMIPrincipalId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "The principal ID of the system assigned identity."
- },
- "value": "[tryGet(tryGet(reference('slot', '2024-04-01', 'full'), 'identity'), 'principalId')]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('slot', '2024-04-01', 'full').location]"
- },
- "privateEndpoints": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateEndpointOutputType"
- },
- "metadata": {
- "description": "The private endpoints of the slot."
- },
- "copy": {
- "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]",
- "input": {
- "name": "[reference(format('slot_privateEndpoints[{0}]', copyIndex())).outputs.name.value]",
- "resourceId": "[reference(format('slot_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]",
- "groupId": "[tryGet(tryGet(reference(format('slot_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]",
- "customDnsConfigs": "[reference(format('slot_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]",
- "networkInterfaceResourceIds": "[reference(format('slot_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]"
- }
- }
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_basicPublishingCredentialsPolicies": {
- "copy": {
- "name": "app_basicPublishingCredentialsPolicies",
- "count": "[length(coalesce(parameters('basicPublishingCredentialsPolicies'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-Site-Publish-Cred-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "webAppName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[coalesce(parameters('basicPublishingCredentialsPolicies'), createArray())[copyIndex()].name]"
- },
- "allow": {
- "value": "[tryGet(coalesce(parameters('basicPublishingCredentialsPolicies'), createArray())[copyIndex()], 'allow')]"
- },
- "location": {
- "value": "[parameters('location')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "7001118912896436334"
- },
- "name": "Web Site Basic Publishing Credentials Policies",
- "description": "This module deploys a Web Site Basic Publishing Credentials Policy."
- },
- "parameters": {
- "name": {
- "type": "string",
- "allowedValues": [
- "scm",
- "ftp"
- ],
- "metadata": {
- "description": "Required. The name of the resource."
- }
- },
- "allow": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Set to true to enable or false to disable a publishing method."
- }
- },
- "webAppName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent web site. Required if the template is used in a standalone deployment."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}', parameters('webAppName'), parameters('name'))]",
- "location": "[parameters('location')]",
- "properties": {
- "allow": "[parameters('allow')]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the basic publishing credential policy."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the basic publishing credential policy."
- },
- "value": "[resourceId('Microsoft.Web/sites/basicPublishingCredentialsPolicies', parameters('webAppName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the basic publishing credential policy was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference(resourceId('Microsoft.Web/sites/basicPublishingCredentialsPolicies', parameters('webAppName'), parameters('name')), '2024-04-01', 'full').location]"
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_hybridConnectionRelays": {
- "copy": {
- "name": "app_hybridConnectionRelays",
- "count": "[length(coalesce(parameters('hybridConnectionRelays'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-HybridConnectionRelay-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "hybridConnectionResourceId": {
- "value": "[coalesce(parameters('hybridConnectionRelays'), createArray())[copyIndex()].resourceId]"
- },
- "appName": {
- "value": "[parameters('name')]"
- },
- "sendKeyName": {
- "value": "[tryGet(coalesce(parameters('hybridConnectionRelays'), createArray())[copyIndex()], 'sendKeyName')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.93.31351",
- "templateHash": "13214417392638890300"
- },
- "name": "Web/Function Apps Hybrid Connection Relay",
- "description": "This module deploys a Site Hybrid Connection Namespace Relay."
- },
- "parameters": {
- "hybridConnectionResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource ID of the relay namespace hybrid connection."
- }
- },
- "appName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent web site. Required if the template is used in a standalone deployment."
- }
- },
- "sendKeyName": {
- "type": "string",
- "defaultValue": "defaultSender",
- "metadata": {
- "description": "Optional. Name of the authorization rule send key to use."
- }
- }
- },
- "resources": [
- {
- "type": "Microsoft.Web/sites/hybridConnectionNamespaces/relays",
- "apiVersion": "2024-04-01",
- "name": "[format('{0}/{1}/{2}', parameters('appName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10])]",
- "properties": {
- "serviceBusNamespace": "[split(parameters('hybridConnectionResourceId'), '/')[8]]",
- "serviceBusSuffix": "[split(substring(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces', split(parameters('hybridConnectionResourceId'), '/')[8]), '2021-11-01').serviceBusEndpoint, indexOf(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces', split(parameters('hybridConnectionResourceId'), '/')[8]), '2021-11-01').serviceBusEndpoint, '.servicebus')), ':')[0]]",
- "relayName": "[split(parameters('hybridConnectionResourceId'), '/')[10]]",
- "relayArmUri": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10])]",
- "hostname": "[split(json(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '2021-11-01').userMetadata)[0].value, ':')[0]]",
- "port": "[int(split(json(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '2021-11-01').userMetadata)[0].value, ':')[1])]",
- "sendKeyName": "[parameters('sendKeyName')]",
- "sendKeyValue": "[listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hybridConnectionResourceId'), '/')[2], split(parameters('hybridConnectionResourceId'), '/')[4]), 'Microsoft.Relay/namespaces/hybridConnections/authorizationRules', split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10], parameters('sendKeyName')), '2021-11-01').primaryKey]"
- }
- }
- ],
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the hybrid connection relay.."
- },
- "value": "[format('{0}/{1}/{2}', parameters('appName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10])]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the hybrid connection relay."
- },
- "value": "[resourceId('Microsoft.Web/sites/hybridConnectionNamespaces/relays', split(format('{0}/{1}/{2}', parameters('appName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '/')[0], split(format('{0}/{1}/{2}', parameters('appName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '/')[1], split(format('{0}/{1}/{2}', parameters('appName'), split(parameters('hybridConnectionResourceId'), '/')[8], split(parameters('hybridConnectionResourceId'), '/')[10]), '/')[2])]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The name of the resource group the resource was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- },
- "app_privateEndpoints": {
- "copy": {
- "name": "app_privateEndpoints",
- "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-app-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), resourceGroup().id), '/')[2]]",
- "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), resourceGroup().id), '/')[4]]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Web/sites', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'sites'), copyIndex()))]"
- },
- "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Web/sites', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'sites'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Web/sites', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'sites')))))), createObject('value', null()))]",
- "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Web/sites', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'sites'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Web/sites', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'sites')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
- "subnetResourceId": {
- "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]"
- },
- "enableTelemetry": {
- "value": "[variables('enableReferencedModulesTelemetry')]"
- },
- "location": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]"
- },
- "lock": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]"
- },
- "privateDnsZoneGroup": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]"
- },
- "roleAssignments": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]"
- },
- "tags": {
- "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
- },
- "customDnsConfigs": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]"
- },
- "ipConfigurations": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]"
- },
- "applicationSecurityGroupResourceIds": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]"
- },
- "customNetworkInterfaceName": {
- "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.13.18514",
- "templateHash": "15954548978129725136"
- },
- "name": "Private Endpoints",
- "description": "This module deploys a Private Endpoint."
- },
- "definitions": {
- "privateDnsZoneGroupType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the Private DNS Zone Group."
- }
- },
- "privateDnsZoneGroupConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateDnsZoneGroupConfigType"
- },
- "metadata": {
- "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "ipConfigurationType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource that is unique within a resource group."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "memberName": {
- "type": "string",
- "metadata": {
- "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "privateIPAddress": {
- "type": "string",
- "metadata": {
- "description": "Required. A private IP address obtained from the private endpoint's subnet."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private endpoint IP configurations."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "privateLinkServiceConnectionType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the private link service connection."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
- }
- },
- "privateLinkServiceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of private link service."
- }
- },
- "requestMessage": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private link service connection."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "customDnsConfigType": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. A list of private IP addresses of the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
- },
- "kind": {
- "type": "string",
- "allowedValues": [
- "CanNotDelete",
- "None",
- "ReadOnly"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the type of lock."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a lock.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "privateDnsZoneGroupConfigType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS zone group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- },
- "metadata": {
- "__bicep_imported_from!": {
- "sourceTemplate": "private-dns-zone-group/main.bicep"
- }
- }
- },
- "roleAssignmentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
- }
- },
- "roleDefinitionIdOrName": {
- "type": "string",
- "metadata": {
- "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
- }
- },
- "principalId": {
- "type": "string",
- "metadata": {
- "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
- }
- },
- "principalType": {
- "type": "string",
- "allowedValues": [
- "Device",
- "ForeignGroup",
- "Group",
- "ServicePrincipal",
- "User"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. The principal type of the assigned principal ID."
- }
- },
- "description": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The description of the role assignment."
- }
- },
- "condition": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
- }
- },
- "conditionVersion": {
- "type": "string",
- "allowedValues": [
- "2.0"
- ],
- "nullable": true,
- "metadata": {
- "description": "Optional. Version of the condition."
- }
- },
- "delegatedManagedIdentityResourceId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The Resource Id of the delegated managed identity resource."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for a role assignment.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- }
- },
- "parameters": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. Name of the private endpoint resource to create."
- }
- },
- "subnetResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
- }
- },
- "applicationSecurityGroupResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Application security groups in which the private endpoint IP configuration is included."
- }
- },
- "customNetworkInterfaceName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The custom name of the network interface attached to the private endpoint."
- }
- },
- "ipConfigurations": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/ipConfigurationType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
- }
- },
- "privateDnsZoneGroup": {
- "$ref": "#/definitions/privateDnsZoneGroupType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The private DNS zone group to configure for the private endpoint."
- }
- },
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Optional. Location for all Resources."
- }
- },
- "lock": {
- "$ref": "#/definitions/lockType",
- "nullable": true,
- "metadata": {
- "description": "Optional. The lock settings of the service."
- }
- },
- "roleAssignments": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/roleAssignmentType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Array of role assignments to create."
- }
- },
- "tags": {
- "type": "object",
- "nullable": true,
- "metadata": {
- "description": "Optional. Tags to be applied on all resources/resource groups in this deployment."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/customDnsConfigType"
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. Custom DNS configurations."
- }
- },
- "manualPrivateLinkServiceConnections": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateLinkServiceConnectionType"
- },
- "nullable": true,
- "metadata": {
- "description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty."
- }
- },
- "privateLinkServiceConnections": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateLinkServiceConnectionType"
- },
- "nullable": true,
- "metadata": {
- "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty."
- }
- },
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
- "metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "formattedRoleAssignments",
- "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
- "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
- }
- ],
- "builtInRoleNames": {
- "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]",
- "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]",
- "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]",
- "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]",
- "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]",
- "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
- "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]",
- "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
- "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]"
- }
- },
- "resources": {
- "avmTelemetry": {
- "condition": "[parameters('enableTelemetry')]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
- "properties": {
- "mode": "Incremental",
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "resources": [],
- "outputs": {
- "telemetry": {
- "type": "String",
- "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
- }
- }
- }
- }
- },
- "privateEndpoint": {
- "type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2023-11-01",
- "name": "[parameters('name')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "copy": [
- {
- "name": "applicationSecurityGroups",
- "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]",
- "input": {
- "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]"
- }
- }
- ],
- "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]",
- "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]",
- "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]",
- "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]",
- "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]",
- "subnet": {
- "id": "[parameters('subnetResourceId')]"
- }
- }
- },
- "privateEndpoint_lock": {
- "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
- "type": "Microsoft.Authorization/locks",
- "apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
- "properties": {
- "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- },
- "privateEndpoint_roleAssignments": {
- "copy": {
- "name": "privateEndpoint_roleAssignments",
- "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
- },
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
- "properties": {
- "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
- "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
- "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
- "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
- "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
- "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
- "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- },
- "privateEndpoint_privateDnsZoneGroup": {
- "condition": "[not(empty(parameters('privateDnsZoneGroup')))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "name": {
- "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]"
- },
- "privateEndpointName": {
- "value": "[parameters('name')]"
- },
- "privateDnsZoneConfigs": {
- "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "languageVersion": "2.0",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.33.13.18514",
- "templateHash": "5440815542537978381"
- },
- "name": "Private Endpoint Private DNS Zone Groups",
- "description": "This module deploys a Private Endpoint Private DNS Zone Group."
- },
- "definitions": {
- "privateDnsZoneGroupConfigType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of the private DNS zone group config."
- }
- },
- "privateDnsZoneResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of the private DNS zone."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- }
- },
- "parameters": {
- "privateEndpointName": {
- "type": "string",
- "metadata": {
- "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment."
- }
- },
- "privateDnsZoneConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateDnsZoneGroupConfigType"
- },
- "minLength": 1,
- "maxLength": 5,
- "metadata": {
- "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones."
- }
- },
- "name": {
- "type": "string",
- "defaultValue": "default",
- "metadata": {
- "description": "Optional. The name of the private DNS zone group."
- }
- }
- },
- "variables": {
- "copy": [
- {
- "name": "privateDnsZoneConfigsVar",
- "count": "[length(parameters('privateDnsZoneConfigs'))]",
- "input": {
- "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]",
- "properties": {
- "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]"
- }
- }
- }
- ]
- },
- "resources": {
- "privateEndpoint": {
- "existing": true,
- "type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2023-11-01",
- "name": "[parameters('privateEndpointName')]"
- },
- "privateDnsZoneGroup": {
- "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
- "apiVersion": "2023-11-01",
- "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]",
- "properties": {
- "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]"
- }
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint DNS zone group."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint DNS zone group."
- },
- "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]"
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the private endpoint DNS zone group was deployed into."
- },
- "value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "privateEndpoint"
- ]
- }
- },
- "outputs": {
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the private endpoint was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint."
- },
- "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
- },
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint."
- },
- "value": "[parameters('name')]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]"
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/customDnsConfigType"
- },
- "metadata": {
- "description": "The custom DNS configurations of the private endpoint."
- },
- "value": "[reference('privateEndpoint').customDnsConfigs]"
- },
- "networkInterfaceResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "The resource IDs of the network interfaces associated with the private endpoint."
- },
- "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]"
- },
- "groupId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "The group Id for the private endpoint Group."
- },
- "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]"
- }
- }
- }
- },
- "dependsOn": [
- "app"
- ]
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the site."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the site."
- },
- "value": "[resourceId('Microsoft.Web/sites', parameters('name'))]"
- },
- "slots": {
- "type": "array",
- "metadata": {
- "description": "The list of the slots."
- },
- "copy": {
- "count": "[length(coalesce(parameters('slots'), createArray()))]",
- "input": "[format('{0}-Slot-{1}', uniqueString(deployment().name, parameters('location')), coalesce(parameters('slots'), createArray())[copyIndex()].name)]"
- }
- },
- "slotResourceIds": {
- "type": "array",
- "metadata": {
- "description": "The list of the slot resource ids."
- },
- "copy": {
- "count": "[length(coalesce(parameters('slots'), createArray()))]",
- "input": "[reference(format('app_slots[{0}]', copyIndex())).outputs.resourceId.value]"
- }
- },
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the site was deployed into."
- },
- "value": "[resourceGroup().name]"
- },
- "systemAssignedMIPrincipalId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "The principal ID of the system assigned identity."
- },
- "value": "[tryGet(tryGet(reference('app', '2024-04-01', 'full'), 'identity'), 'principalId')]"
- },
- "slotSystemAssignedMIPrincipalIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "The principal ID of the system assigned identity of slots."
- },
- "copy": {
- "count": "[length(coalesce(parameters('slots'), createArray()))]",
- "input": "[coalesce(tryGet(tryGet(reference(format('app_slots[{0}]', copyIndex())).outputs, 'systemAssignedMIPrincipalId'), 'value'), '')]"
- }
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
- },
- "value": "[reference('app', '2024-04-01', 'full').location]"
- },
- "defaultHostname": {
- "type": "string",
- "metadata": {
- "description": "Default hostname of the app."
- },
- "value": "[reference('app').defaultHostName]"
- },
- "customDomainVerificationId": {
- "type": "string",
- "metadata": {
- "description": "Unique identifier that verifies the custom domains assigned to the app. Customer will add this ID to a txt record for verification."
- },
- "value": "[reference('app').customDomainVerificationId]"
- },
- "privateEndpoints": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/privateEndpointOutputType"
- },
- "metadata": {
- "description": "The private endpoints of the site."
- },
- "copy": {
- "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]",
- "input": {
- "name": "[reference(format('app_privateEndpoints[{0}]', copyIndex())).outputs.name.value]",
- "resourceId": "[reference(format('app_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]",
- "groupId": "[tryGet(tryGet(reference(format('app_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]",
- "customDnsConfigs": "[reference(format('app_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]",
- "networkInterfaceResourceIds": "[reference(format('app_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]"
- }
- }
- },
- "slotPrivateEndpoints": {
- "type": "array",
- "metadata": {
- "description": "The private endpoints of the slots."
- },
- "copy": {
- "count": "[length(coalesce(parameters('slots'), createArray()))]",
- "input": "[reference(format('app_slots[{0}]', copyIndex())).outputs.privateEndpoints.value]"
- }
- },
- "outboundIpAddresses": {
- "type": "string",
- "metadata": {
- "description": "The outbound IP addresses of the app."
- },
- "value": "[reference('app').outboundIpAddresses]"
- }
- }
- }
- }
- }
- ],
- "outputs": {
- "SERVICE_API_NAME": {
- "type": "string",
- "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-flex-consumption', parameters('serviceName'))), '2025-04-01').outputs.name.value]"
- },
- "SERVICE_API_IDENTITY_PRINCIPAL_ID": {
- "type": "string",
- "value": "[if(equals(parameters('identityType'), 'SystemAssigned'), coalesce(tryGet(tryGet(reference(resourceId('Microsoft.Resources/deployments', format('{0}-flex-consumption', parameters('serviceName'))), '2025-04-01').outputs, 'systemAssignedMIPrincipalId'), 'value'), ''), '')]"
- }
- }
- }
- },
- "dependsOn": [
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity')]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'appserviceplan')]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'monitoring')]",
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage')]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "[format('dependencies{0}', variables('projectName'))]",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[variables('tags')]"
- },
- "storageName": {
- "value": "[format('ai{0}{1}', variables('abbrs').storageStorageAccounts, variables('resourceToken'))]"
- },
- "aiServicesName": {
- "value": "[format('{0}{1}', parameters('aiServicesName'), variables('uniqueSuffix'))]"
- },
- "aiSearchName": {
- "value": "[format('{0}{1}', parameters('aiSearchName'), variables('uniqueSuffix'))]"
- },
- "cosmosDbName": {
- "value": "[format('{0}{1}', parameters('cosmosDbName'), variables('uniqueSuffix'))]"
- },
- "enableAzureSearch": {
- "value": "[parameters('enableAzureSearch')]"
- },
- "enableCosmosDb": {
- "value": "[parameters('enableCosmosDb')]"
- },
- "modelName": {
- "value": "[parameters('modelName')]"
- },
- "modelFormat": {
- "value": "[parameters('modelFormat')]"
- },
- "modelVersion": {
- "value": "[parameters('modelVersion')]"
- },
- "modelSkuName": {
- "value": "[parameters('modelSkuName')]"
- },
- "modelCapacity": {
- "value": "[parameters('modelCapacity')]"
- },
- "modelDeploymentName": {
- "value": "[parameters('modelDeploymentName')]"
- },
- "modelLocation": {
- "value": "[parameters('location')]"
- },
- "aiServiceAccountResourceId": {
- "value": "[parameters('aiServiceAccountResourceId')]"
- },
- "aiSearchServiceResourceId": {
- "value": "[parameters('aiSearchServiceResourceId')]"
- },
- "aiStorageAccountResourceId": {
- "value": "[parameters('aiStorageAccountResourceId')]"
- },
- "aiCosmosDbAccountResourceId": {
- "value": "[parameters('aiCosmosDbAccountResourceId')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "1486066558996912834"
- }
- },
- "parameters": {
- "location": {
- "type": "string",
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Azure region of the deployment"
- }
- },
- "tags": {
- "type": "object",
- "defaultValue": {},
- "metadata": {
- "description": "Tags to add to the resources"
- }
- },
- "aiServicesName": {
- "type": "string",
- "metadata": {
- "description": "AI services name"
- }
- },
- "aiSearchName": {
- "type": "string",
- "metadata": {
- "description": "The name of the AI Search resource"
- }
- },
- "enableAzureSearch": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Enable Azure AI Search resource creation"
- }
- },
- "cosmosDbName": {
- "type": "string",
- "metadata": {
- "description": "The name of the Cosmos DB account"
- }
- },
- "enableCosmosDb": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Enable Cosmos DB resource creation"
- }
- },
- "storageName": {
- "type": "string",
- "metadata": {
- "description": "Name of the storage account"
- }
- },
- "modelName": {
- "type": "string",
- "metadata": {
- "description": "Model name for deployment"
- }
- },
- "modelFormat": {
- "type": "string",
- "metadata": {
- "description": "Model format for deployment"
- }
- },
- "modelVersion": {
- "type": "string",
- "metadata": {
- "description": "Model version for deployment"
- }
- },
- "modelSkuName": {
- "type": "string",
- "metadata": {
- "description": "Model deployment SKU name"
- }
- },
- "modelCapacity": {
- "type": "int",
- "metadata": {
- "description": "Model deployment capacity"
- }
- },
- "modelDeploymentName": {
- "type": "string",
- "defaultValue": "chat",
- "metadata": {
- "description": "Name for the model deployment in Azure AI Services"
- }
- },
- "modelLocation": {
- "type": "string",
- "metadata": {
- "description": "Model/AI Resource deployment location"
- }
- },
- "aiServiceAccountResourceId": {
- "type": "string",
- "metadata": {
- "description": "The AI Service Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- },
- "aiSearchServiceResourceId": {
- "type": "string",
- "metadata": {
- "description": "The AI Search Service full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- },
- "aiStorageAccountResourceId": {
- "type": "string",
- "metadata": {
- "description": "The AI Storage Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- },
- "aiCosmosDbAccountResourceId": {
- "type": "string",
- "metadata": {
- "description": "The AI Cosmos DB Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created."
- }
- },
- "sku": {
- "type": "string",
- "defaultValue": "Standard_LRS"
- }
- },
- "variables": {
- "aiServiceExists": "[not(equals(parameters('aiServiceAccountResourceId'), ''))]",
- "skipAzureSearchCreation": "[or(not(equals(parameters('aiSearchServiceResourceId'), '')), not(parameters('enableAzureSearch')))]",
- "aiStorageExists": "[not(equals(parameters('aiStorageAccountResourceId'), ''))]",
- "skipCosmosDbCreation": "[or(not(equals(parameters('aiCosmosDbAccountResourceId'), '')), not(parameters('enableCosmosDb')))]",
- "canaryRegions": [
- "eastus2euap",
- "centraluseuap"
- ],
- "cosmosDbRegion": "[if(contains(variables('canaryRegions'), parameters('location')), 'eastus2', parameters('location'))]"
- },
- "resources": [
- {
- "condition": "[not(variables('aiServiceExists'))]",
- "type": "Microsoft.CognitiveServices/accounts",
- "apiVersion": "2025-04-01-preview",
- "name": "[parameters('aiServicesName')]",
- "location": "[parameters('modelLocation')]",
- "sku": {
- "name": "S0"
- },
- "kind": "AIServices",
- "identity": {
- "type": "SystemAssigned"
- },
- "properties": {
- "allowProjectManagement": true,
- "customSubDomainName": "[toLower(format('{0}', parameters('aiServicesName')))]",
- "networkAcls": {
- "defaultAction": "Allow",
- "virtualNetworkRules": [],
- "ipRules": []
- },
- "publicNetworkAccess": "Enabled",
- "disableLocalAuth": true
- }
- },
- {
- "condition": "[not(variables('aiServiceExists'))]",
- "type": "Microsoft.CognitiveServices/accounts/deployments",
- "apiVersion": "2025-04-01-preview",
- "name": "[format('{0}/{1}', parameters('aiServicesName'), parameters('modelDeploymentName'))]",
- "sku": {
- "capacity": "[parameters('modelCapacity')]",
- "name": "[parameters('modelSkuName')]"
- },
- "properties": {
- "model": {
- "name": "[parameters('modelName')]",
- "format": "[parameters('modelFormat')]",
- "version": "[parameters('modelVersion')]"
- }
- },
- "dependsOn": [
- "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]"
- ]
- },
- {
- "condition": "[not(variables('skipAzureSearchCreation'))]",
- "type": "Microsoft.Search/searchServices",
- "apiVersion": "2024-06-01-preview",
- "name": "[parameters('aiSearchName')]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "identity": {
- "type": "SystemAssigned"
- },
- "properties": {
- "disableLocalAuth": true,
- "encryptionWithCmk": {
- "enforcement": "Unspecified"
- },
- "hostingMode": "default",
- "partitionCount": 1,
- "publicNetworkAccess": "enabled",
- "replicaCount": 1,
- "semanticSearch": "disabled"
- },
- "sku": {
- "name": "standard"
- }
- },
- {
- "condition": "[not(variables('aiStorageExists'))]",
- "type": "Microsoft.Storage/storageAccounts",
- "apiVersion": "2022-05-01",
- "name": "[parameters('storageName')]",
- "location": "[parameters('location')]",
- "kind": "StorageV2",
- "sku": {
- "name": "[parameters('sku')]"
- },
- "properties": {
- "minimumTlsVersion": "TLS1_2",
- "allowBlobPublicAccess": false,
- "publicNetworkAccess": "Enabled",
- "networkAcls": {
- "bypass": "AzureServices",
- "defaultAction": "Allow",
- "virtualNetworkRules": []
- },
- "allowSharedKeyAccess": false
- }
- },
- {
- "condition": "[not(variables('skipCosmosDbCreation'))]",
- "type": "Microsoft.DocumentDB/databaseAccounts",
- "apiVersion": "2024-11-15",
- "name": "[parameters('cosmosDbName')]",
- "location": "[variables('cosmosDbRegion')]",
- "kind": "GlobalDocumentDB",
- "properties": {
- "consistencyPolicy": {
- "defaultConsistencyLevel": "Session"
- },
- "disableLocalAuth": true,
- "enableAutomaticFailover": false,
- "enableMultipleWriteLocations": false,
- "enableFreeTier": false,
- "locations": [
- {
- "locationName": "[parameters('location')]",
- "failoverPriority": 0,
- "isZoneRedundant": false
- }
- ],
- "databaseAccountOfferType": "Standard"
- }
- }
- ],
- "outputs": {
- "aiServicesName": {
- "type": "string",
- "value": "[parameters('aiServicesName')]"
- },
- "aiservicesID": {
- "type": "string",
- "value": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]"
- },
- "aiServiceAccountResourceGroupName": {
- "type": "string",
- "value": "[resourceGroup().name]"
- },
- "aiServiceAccountSubscriptionId": {
- "type": "string",
- "value": "[subscription().subscriptionId]"
- },
- "aiSearchName": {
- "type": "string",
- "value": "[parameters('aiSearchName')]"
- },
- "aisearchID": {
- "type": "string",
- "value": "[if(not(variables('skipAzureSearchCreation')), resourceId('Microsoft.Search/searchServices', parameters('aiSearchName')), parameters('aiSearchServiceResourceId'))]"
- },
- "aiSearchServiceResourceGroupName": {
- "type": "string",
- "value": "[if(not(variables('skipAzureSearchCreation')), resourceGroup().name, '')]"
- },
- "aiSearchServiceSubscriptionId": {
- "type": "string",
- "value": "[if(not(variables('skipAzureSearchCreation')), subscription().subscriptionId, '')]"
- },
- "storageAccountName": {
- "type": "string",
- "value": "[parameters('storageName')]"
- },
- "storageId": {
- "type": "string",
- "value": "[if(not(variables('aiStorageExists')), resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), parameters('aiStorageAccountResourceId'))]"
- },
- "storageAccountResourceGroupName": {
- "type": "string",
- "value": "[if(not(variables('aiStorageExists')), resourceGroup().name, '')]"
- },
- "storageAccountSubscriptionId": {
- "type": "string",
- "value": "[if(not(variables('aiStorageExists')), subscription().subscriptionId, '')]"
- },
- "cosmosDbAccountName": {
- "type": "string",
- "value": "[parameters('cosmosDbName')]"
- },
- "cosmosDbAccountId": {
- "type": "string",
- "value": "[if(not(variables('skipCosmosDbCreation')), resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbName')), parameters('aiCosmosDbAccountResourceId'))]"
- },
- "cosmosDbAccountResourceGroupName": {
- "type": "string",
- "value": "[if(not(variables('skipCosmosDbCreation')), resourceGroup().name, '')]"
- },
- "cosmosDbAccountSubscriptionId": {
- "type": "string",
- "value": "[if(not(variables('skipCosmosDbCreation')), subscription().subscriptionId, '')]"
- }
- }
- }
- },
- "dependsOn": [
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "[format('project{0}', variables('projectName'))]",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "location": {
- "value": "[parameters('location')]"
- },
- "tags": {
- "value": "[variables('tags')]"
- },
- "aiServicesAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiServicesName.value]"
- },
- "aiProjectName": {
- "value": "[variables('projectName')]"
- },
- "aiProjectFriendlyName": {
- "value": "[parameters('aiProjectFriendlyName')]"
- },
- "aiProjectDescription": {
- "value": "[parameters('aiProjectDescription')]"
- },
- "enableAzureSearch": {
- "value": "[parameters('enableAzureSearch')]"
- },
- "enableCosmosDb": {
- "value": "[parameters('enableCosmosDb')]"
- },
- "cosmosDbAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.cosmosDbAccountName.value]"
- },
- "cosmosDbAccountSubscriptionId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.cosmosDbAccountSubscriptionId.value]"
- },
- "cosmosDbAccountResourceGroupName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.cosmosDbAccountResourceGroupName.value]"
- },
- "storageAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.storageAccountName.value]"
- },
- "storageAccountSubscriptionId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.storageAccountSubscriptionId.value]"
- },
- "storageAccountResourceGroupName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.storageAccountResourceGroupName.value]"
- },
- "aiSearchName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiSearchName.value]"
- },
- "aiSearchSubscriptionId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiSearchServiceSubscriptionId.value]"
- },
- "aiSearchResourceGroupName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiSearchServiceResourceGroupName.value]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "12002139959618347601"
- }
- },
- "parameters": {
- "location": {
- "type": "string",
- "metadata": {
- "description": "Azure region of the deployment"
- }
- },
- "tags": {
- "type": "object",
- "metadata": {
- "description": "Tags to add to the resources"
- }
- },
- "aiServicesAccountName": {
- "type": "string",
- "metadata": {
- "description": "AI Services Foundry account under which the project will be created"
- }
- },
- "aiProjectName": {
- "type": "string",
- "metadata": {
- "description": "AI Project name"
- }
- },
- "aiProjectFriendlyName": {
- "type": "string",
- "defaultValue": "[parameters('aiProjectName')]",
- "metadata": {
- "description": "AI Project display name"
- }
- },
- "aiProjectDescription": {
- "type": "string",
- "metadata": {
- "description": "AI Project description"
- }
- },
- "enableAzureSearch": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Enable Azure AI Search for vector store and search capabilities"
- }
- },
- "enableCosmosDb": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Enable Cosmos DB for agent thread storage"
- }
- },
- "cosmosDbAccountName": {
- "type": "string",
- "metadata": {
- "description": "Cosmos DB Account for agent thread storage"
- }
- },
- "cosmosDbAccountSubscriptionId": {
- "type": "string"
- },
- "cosmosDbAccountResourceGroupName": {
- "type": "string"
- },
- "storageAccountName": {
- "type": "string",
- "metadata": {
- "description": "Storage Account for agent artifacts"
- }
- },
- "storageAccountSubscriptionId": {
- "type": "string"
- },
- "storageAccountResourceGroupName": {
- "type": "string"
- },
- "aiSearchName": {
- "type": "string",
- "metadata": {
- "description": "AI Search Service for vector store and search"
- }
- },
- "aiSearchSubscriptionId": {
- "type": "string"
- },
- "aiSearchResourceGroupName": {
- "type": "string"
- }
- },
- "resources": [
- {
- "condition": "[parameters('enableCosmosDb')]",
- "type": "Microsoft.CognitiveServices/accounts/projects/connections",
- "apiVersion": "2025-04-01-preview",
- "name": "[format('{0}/{1}/{2}', parameters('aiServicesAccountName'), parameters('aiProjectName'), parameters('cosmosDbAccountName'))]",
- "properties": {
- "category": "CosmosDB",
- "target": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('cosmosDbAccountSubscriptionId'), parameters('cosmosDbAccountResourceGroupName')), 'Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName')), '2024-11-15').documentEndpoint]",
- "authType": "AAD",
- "metadata": {
- "ApiType": "Azure",
- "ResourceId": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('cosmosDbAccountSubscriptionId'), parameters('cosmosDbAccountResourceGroupName')), 'Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName'))]",
- "location": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('cosmosDbAccountSubscriptionId'), parameters('cosmosDbAccountResourceGroupName')), 'Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName')), '2024-11-15', 'full').location]"
- }
- },
- "dependsOn": [
- "[resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName'))]"
- ]
- },
- {
- "type": "Microsoft.CognitiveServices/accounts/projects/connections",
- "apiVersion": "2025-04-01-preview",
- "name": "[format('{0}/{1}/{2}', parameters('aiServicesAccountName'), parameters('aiProjectName'), parameters('storageAccountName'))]",
- "properties": {
- "category": "AzureStorageAccount",
- "target": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('storageAccountSubscriptionId'), parameters('storageAccountResourceGroupName')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2024-01-01').primaryEndpoints.blob]",
- "authType": "AAD",
- "metadata": {
- "ApiType": "Azure",
- "ResourceId": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('storageAccountSubscriptionId'), parameters('storageAccountResourceGroupName')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
- "location": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('storageAccountSubscriptionId'), parameters('storageAccountResourceGroupName')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2024-01-01', 'full').location]"
- }
- },
- "dependsOn": [
- "[resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName'))]"
- ]
- },
- {
- "condition": "[parameters('enableAzureSearch')]",
- "type": "Microsoft.CognitiveServices/accounts/projects/connections",
- "apiVersion": "2025-04-01-preview",
- "name": "[format('{0}/{1}/{2}', parameters('aiServicesAccountName'), parameters('aiProjectName'), parameters('aiSearchName'))]",
- "properties": {
- "category": "CognitiveSearch",
- "target": "[format('https://{0}.search.windows.net', parameters('aiSearchName'))]",
- "authType": "AAD",
- "metadata": {
- "ApiType": "Azure",
- "ResourceId": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('aiSearchSubscriptionId'), parameters('aiSearchResourceGroupName')), 'Microsoft.Search/searchServices', parameters('aiSearchName'))]",
- "location": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('aiSearchSubscriptionId'), parameters('aiSearchResourceGroupName')), 'Microsoft.Search/searchServices', parameters('aiSearchName')), '2024-06-01-preview', 'full').location]"
- }
- },
- "dependsOn": [
- "[resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName'))]"
- ]
- },
- {
- "type": "Microsoft.CognitiveServices/accounts/projects",
- "apiVersion": "2025-04-01-preview",
- "name": "[format('{0}/{1}', parameters('aiServicesAccountName'), parameters('aiProjectName'))]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "identity": {
- "type": "SystemAssigned"
- },
- "properties": {
- "description": "[parameters('aiProjectDescription')]",
- "displayName": "[parameters('aiProjectFriendlyName')]"
- }
- }
- ],
- "outputs": {
- "aiProjectName": {
- "type": "string",
- "value": "[parameters('aiProjectName')]"
- },
- "aiProjectResourceId": {
- "type": "string",
- "value": "[resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName'))]"
- },
- "aiProjectPrincipalId": {
- "type": "string",
- "value": "[reference(resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName')), '2025-04-01-preview', 'full').identity.principalId]"
- },
- "aiSearchConnection": {
- "type": "string",
- "value": "[parameters('aiSearchName')]"
- },
- "azureStorageConnection": {
- "type": "string",
- "value": "[parameters('storageAccountName')]"
- },
- "cosmosDbConnection": {
- "type": "string",
- "value": "[parameters('cosmosDbAccountName')]"
- },
- "projectWorkspaceId": {
- "type": "string",
- "value": "[format('{0}-{1}-{2}-{3}-{4}', substring(reference(resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName')), '2025-04-01-preview').internalId, 0, 8), substring(reference(resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName')), '2025-04-01-preview').internalId, 8, 4), substring(reference(resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName')), '2025-04-01-preview').internalId, 12, 4), substring(reference(resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName')), '2025-04-01-preview').internalId, 16, 4), substring(reference(resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiServicesAccountName'), parameters('aiProjectName')), '2025-04-01-preview').internalId, 20, 12))]"
- },
- "projectEndpoint": {
- "type": "string",
- "value": "[format('https://{0}.services.ai.azure.com/api/projects/{1}', parameters('aiServicesAccountName'), parameters('aiProjectName'))]"
- }
- }
- }
- },
- "dependsOn": [
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName')))]",
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "[format('rbac{0}', variables('projectName'))]",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "aiProjectPrincipalId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.aiProjectPrincipalId.value]"
- },
- "userPrincipalId": {
- "value": "[parameters('principalId')]"
- },
- "allowUserIdentityPrincipal": {
- "value": "[not(empty(parameters('principalId')))]"
- },
- "aiServicesName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiServicesName.value]"
- },
- "aiSearchName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiSearchName.value]"
- },
- "aiCosmosDbName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.cosmosDbAccountName.value]"
- },
- "aiStorageAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.storageAccountName.value]"
- },
- "integrationStorageAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage'), '2025-04-01').outputs.name.value]"
- },
- "functionAppManagedIdentityPrincipalId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity'), '2025-04-01').outputs.principalId.value]"
- },
- "allowFunctionAppIdentityPrincipal": {
- "value": true
- },
- "enableAzureSearch": {
- "value": "[parameters('enableAzureSearch')]"
- },
- "enableCosmosDb": {
- "value": "[parameters('enableCosmosDb')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "13465598790985520929"
- }
- },
- "parameters": {
- "aiProjectPrincipalId": {
- "type": "string"
- },
- "aiProjectPrincipalType": {
- "type": "string",
- "defaultValue": "ServicePrincipal"
- },
- "userPrincipalId": {
- "type": "string",
- "defaultValue": ""
- },
- "allowUserIdentityPrincipal": {
- "type": "bool",
- "defaultValue": true
- },
- "aiServicesName": {
- "type": "string"
- },
- "aiSearchName": {
- "type": "string"
- },
- "aiCosmosDbName": {
- "type": "string"
- },
- "aiStorageAccountName": {
- "type": "string"
- },
- "integrationStorageAccountName": {
- "type": "string"
- },
- "functionAppManagedIdentityPrincipalId": {
- "type": "string",
- "defaultValue": ""
- },
- "allowFunctionAppIdentityPrincipal": {
- "type": "bool",
- "defaultValue": true
- },
- "enableAzureSearch": {
- "type": "bool",
- "defaultValue": false
- },
- "enableCosmosDb": {
- "type": "bool",
- "defaultValue": false
- }
- },
- "variables": {
- "cognitiveServicesContributorRoleDefinitionId": "25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68",
- "cognitiveServicesOpenAIUserRoleDefinitionId": "5e0bd9bd-7b93-4f28-af87-19fc36ad61bd",
- "cognitiveServicesUserRoleDefinitionId": "a97b65f3-24c7-4388-baec-2e87135dc908",
- "searchIndexDataContributorRoleDefinitionId": "8ebe5a00-799e-43f5-93ac-243d3dce84a7",
- "searchServiceContributorRoleDefinitionId": "7ca78c08-252a-4471-8644-bb5ff32d4ba0",
- "storageBlobDataContributorRoleDefinitionId": "ba92f5b4-2d11-453d-a403-e96b0029c9fe",
- "cosmosDbOperatorRoleDefinitionId": "230815da-be43-4aae-9cb4-875f7bd000aa",
- "storageQueueDataContributorRoleDefinitionId": "974c5e8b-45b9-4653-ba55-5f855dd0fb88"
- },
- "resources": [
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')), variables('cognitiveServicesContributorRoleDefinitionId'), parameters('aiProjectPrincipalId'))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesContributorRoleDefinitionId'))]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(parameters('aiProjectPrincipalId'), variables('cognitiveServicesOpenAIUserRoleDefinitionId'), resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesOpenAIUserRoleDefinitionId'))]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(parameters('aiProjectPrincipalId'), variables('cognitiveServicesUserRoleDefinitionId'), resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesUserRoleDefinitionId'))]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "condition": "[and(parameters('allowUserIdentityPrincipal'), not(empty(parameters('userPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')), variables('cognitiveServicesContributorRoleDefinitionId'), parameters('userPrincipalId'))]",
- "properties": {
- "principalId": "[parameters('userPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesContributorRoleDefinitionId'))]",
- "principalType": "User"
- }
- },
- {
- "condition": "[and(parameters('allowUserIdentityPrincipal'), not(empty(parameters('userPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(parameters('userPrincipalId'), variables('cognitiveServicesOpenAIUserRoleDefinitionId'), resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')))]",
- "properties": {
- "principalId": "[parameters('userPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesOpenAIUserRoleDefinitionId'))]",
- "principalType": "User"
- }
- },
- {
- "condition": "[and(parameters('allowUserIdentityPrincipal'), not(empty(parameters('userPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(parameters('userPrincipalId'), variables('cognitiveServicesUserRoleDefinitionId'), resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')))]",
- "properties": {
- "principalId": "[parameters('userPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesUserRoleDefinitionId'))]",
- "principalType": "User"
- }
- },
- {
- "condition": "[parameters('enableAzureSearch')]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Search/searchServices', parameters('aiSearchName'))]",
- "name": "[guid(parameters('aiProjectPrincipalId'), variables('searchIndexDataContributorRoleDefinitionId'), resourceId('Microsoft.Search/searchServices', parameters('aiSearchName')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('searchIndexDataContributorRoleDefinitionId'))]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "condition": "[parameters('enableAzureSearch')]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Search/searchServices', parameters('aiSearchName'))]",
- "name": "[guid(parameters('aiProjectPrincipalId'), variables('searchServiceContributorRoleDefinitionId'), resourceId('Microsoft.Search/searchServices', parameters('aiSearchName')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('searchServiceContributorRoleDefinitionId'))]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('aiStorageAccountName'))]",
- "name": "[guid(parameters('aiProjectPrincipalId'), variables('storageBlobDataContributorRoleDefinitionId'), resourceId('Microsoft.Storage/storageAccounts', parameters('aiStorageAccountName')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('storageBlobDataContributorRoleDefinitionId'))]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "condition": "[parameters('enableCosmosDb')]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('aiCosmosDbName'))]",
- "name": "[guid(parameters('aiProjectPrincipalId'), variables('cosmosDbOperatorRoleDefinitionId'), resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('aiCosmosDbName')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cosmosDbOperatorRoleDefinitionId'))]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('integrationStorageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('integrationStorageAccountName')), parameters('aiProjectPrincipalId'), variables('storageQueueDataContributorRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('storageQueueDataContributorRoleDefinitionId'))]",
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "principalType": "[parameters('aiProjectPrincipalType')]"
- }
- },
- {
- "condition": "[and(parameters('allowUserIdentityPrincipal'), not(empty(parameters('userPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('integrationStorageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('integrationStorageAccountName')), parameters('userPrincipalId'), variables('storageQueueDataContributorRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('storageQueueDataContributorRoleDefinitionId'))]",
- "principalId": "[parameters('userPrincipalId')]",
- "principalType": "User"
- }
- },
- {
- "condition": "[and(parameters('allowFunctionAppIdentityPrincipal'), not(empty(parameters('functionAppManagedIdentityPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')), variables('cognitiveServicesContributorRoleDefinitionId'), parameters('functionAppManagedIdentityPrincipalId'))]",
- "properties": {
- "principalId": "[parameters('functionAppManagedIdentityPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesContributorRoleDefinitionId'))]",
- "principalType": "ServicePrincipal"
- }
- },
- {
- "condition": "[and(parameters('allowFunctionAppIdentityPrincipal'), not(empty(parameters('functionAppManagedIdentityPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(parameters('functionAppManagedIdentityPrincipalId'), variables('cognitiveServicesOpenAIUserRoleDefinitionId'), resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')))]",
- "properties": {
- "principalId": "[parameters('functionAppManagedIdentityPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesOpenAIUserRoleDefinitionId'))]",
- "principalType": "ServicePrincipal"
- }
- },
- {
- "condition": "[and(parameters('allowFunctionAppIdentityPrincipal'), not(empty(parameters('functionAppManagedIdentityPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName'))]",
- "name": "[guid(parameters('functionAppManagedIdentityPrincipalId'), variables('cognitiveServicesUserRoleDefinitionId'), resourceId('Microsoft.CognitiveServices/accounts', parameters('aiServicesName')))]",
- "properties": {
- "principalId": "[parameters('functionAppManagedIdentityPrincipalId')]",
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('cognitiveServicesUserRoleDefinitionId'))]",
- "principalType": "ServicePrincipal"
- }
- }
- ]
- }
- },
- "dependsOn": [
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity')]",
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage')]"
- ]
- },
- {
- "condition": "[and(parameters('enableAzureSearch'), parameters('enableCosmosDb'))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "[format('caphost{0}', variables('projectName'))]",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "aiServicesAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiServicesName.value]"
- },
- "projectName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.aiProjectName.value]"
- },
- "aiSearchConnection": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.aiSearchConnection.value]"
- },
- "azureStorageConnection": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.azureStorageConnection.value]"
- },
- "cosmosDbConnection": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.cosmosDbConnection.value]"
- },
- "accountCapHost": {
- "value": "[format('{0}{1}', parameters('accountCapabilityHostName'), variables('uniqueSuffix'))]"
- },
- "projectCapHost": {
- "value": "[format('{0}{1}', parameters('projectCapabilityHostName'), variables('uniqueSuffix'))]"
- },
- "enableAzureSearch": {
- "value": "[parameters('enableAzureSearch')]"
- },
- "enableCosmosDb": {
- "value": "[parameters('enableCosmosDb')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "6300504802026129812"
- }
- },
- "parameters": {
- "cosmosDbConnection": {
- "type": "string"
- },
- "azureStorageConnection": {
- "type": "string"
- },
- "aiSearchConnection": {
- "type": "string"
- },
- "projectName": {
- "type": "string"
- },
- "aiServicesAccountName": {
- "type": "string"
- },
- "projectCapHost": {
- "type": "string"
- },
- "accountCapHost": {
- "type": "string"
- },
- "enableAzureSearch": {
- "type": "bool",
- "defaultValue": false
- },
- "enableCosmosDb": {
- "type": "bool",
- "defaultValue": false
- }
- },
- "resources": [
- {
- "type": "Microsoft.CognitiveServices/accounts/capabilityHosts",
- "apiVersion": "2025-04-01-preview",
- "name": "[format('{0}/{1}', parameters('aiServicesAccountName'), parameters('accountCapHost'))]",
- "properties": {
- "capabilityHostKind": "Agents"
- }
- },
- {
- "type": "Microsoft.CognitiveServices/accounts/projects/capabilityHosts",
- "apiVersion": "2025-04-01-preview",
- "name": "[format('{0}/{1}/{2}', parameters('aiServicesAccountName'), parameters('projectName'), parameters('projectCapHost'))]",
- "properties": "[union(createObject('capabilityHostKind', 'Agents', 'storageConnections', createArray(format('{0}', parameters('azureStorageConnection')))), if(parameters('enableAzureSearch'), createObject('vectorStoreConnections', createArray(format('{0}', parameters('aiSearchConnection')))), createObject()), if(parameters('enableCosmosDb'), createObject('threadStorageConnections', createArray(format('{0}', parameters('cosmosDbConnection')))), createObject()))]",
- "dependsOn": [
- "[resourceId('Microsoft.CognitiveServices/accounts/capabilityHosts', parameters('aiServicesAccountName'), parameters('accountCapHost'))]"
- ]
- }
- ]
- }
- },
- "dependsOn": [
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('rbac{0}', variables('projectName')))]",
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "condition": "[and(parameters('enableAzureSearch'), parameters('enableCosmosDb'))]",
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "[format('postcap{0}', variables('projectName'))]",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "aiProjectPrincipalId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.aiProjectPrincipalId.value]"
- },
- "aiProjectWorkspaceId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.projectWorkspaceId.value]"
- },
- "aiStorageAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.storageAccountName.value]"
- },
- "cosmosDbAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.cosmosDbAccountName.value]"
- },
- "enableCosmosDb": {
- "value": "[parameters('enableCosmosDb')]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "5311757261854492420"
- }
- },
- "parameters": {
- "aiProjectPrincipalId": {
- "type": "string"
- },
- "aiProjectPrincipalType": {
- "type": "string",
- "defaultValue": "ServicePrincipal"
- },
- "aiProjectWorkspaceId": {
- "type": "string"
- },
- "aiStorageAccountName": {
- "type": "string"
- },
- "cosmosDbAccountName": {
- "type": "string"
- },
- "enableCosmosDb": {
- "type": "bool",
- "defaultValue": false
- }
- },
- "variables": {
- "storageBlobDataOwnerRoleDefinitionId": "b7e6dc6d-f1e8-4753-8033-0f276bb0955b",
- "conditionStr": "[format('((!(ActionMatches{{''Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags/read''}}) AND !(ActionMatches{{''Microsoft.Storage/storageAccounts/blobServices/containers/blobs/filter/action''}}) AND !(ActionMatches{{''Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags/write''}}) ) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers:name] StringStartsWithIgnoreCase ''{0}'' AND @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:name] StringLikeIgnoreCase ''*-azureml-agent''))', parameters('aiProjectWorkspaceId'))]",
- "userThreadName": "[format('{0}-thread-message-store', parameters('aiProjectWorkspaceId'))]",
- "systemThreadName": "[format('{0}-system-thread-message-store', parameters('aiProjectWorkspaceId'))]",
- "entityStoreName": "[format('{0}-agent-entity-store', parameters('aiProjectWorkspaceId'))]",
- "roleDefinitionId": "[if(parameters('enableCosmosDb'), resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('cosmosDbAccountName'), '00000000-0000-0000-0000-000000000002'), '')]",
- "scopeSystemContainer": "[if(parameters('enableCosmosDb'), format('{0}/dbs/enterprise_memory/colls/{1}', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName')), variables('systemThreadName')), '')]",
- "scopeUserContainer": "[if(parameters('enableCosmosDb'), format('{0}/dbs/enterprise_memory/colls/{1}', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName')), variables('userThreadName')), '')]",
- "scopeEntityContainer": "[if(parameters('enableCosmosDb'), format('{0}/dbs/enterprise_memory/colls/{1}', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName')), variables('entityStoreName')), '')]"
- },
- "resources": [
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('aiStorageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('aiStorageAccountName')), parameters('aiProjectPrincipalId'), variables('storageBlobDataOwnerRoleDefinitionId'), parameters('aiProjectWorkspaceId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('storageBlobDataOwnerRoleDefinitionId'))]",
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "principalType": "[parameters('aiProjectPrincipalType')]",
- "conditionVersion": "2.0",
- "condition": "[variables('conditionStr')]"
- }
- },
- {
- "condition": "[parameters('enableCosmosDb')]",
- "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
- "apiVersion": "2022-05-15",
- "name": "[format('{0}/{1}', parameters('cosmosDbAccountName'), guid(parameters('aiProjectWorkspaceId'), resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers', parameters('cosmosDbAccountName'), 'enterprise_memory', variables('userThreadName')), variables('roleDefinitionId'), parameters('aiProjectPrincipalId')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[variables('roleDefinitionId')]",
- "scope": "[variables('scopeUserContainer')]"
- }
- },
- {
- "condition": "[parameters('enableCosmosDb')]",
- "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
- "apiVersion": "2022-05-15",
- "name": "[format('{0}/{1}', parameters('cosmosDbAccountName'), guid(parameters('aiProjectWorkspaceId'), resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers', parameters('cosmosDbAccountName'), 'enterprise_memory', variables('systemThreadName')), variables('roleDefinitionId'), parameters('aiProjectPrincipalId')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[variables('roleDefinitionId')]",
- "scope": "[variables('scopeSystemContainer')]"
- }
- },
- {
- "condition": "[parameters('enableCosmosDb')]",
- "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
- "apiVersion": "2022-05-15",
- "name": "[format('{0}/{1}', parameters('cosmosDbAccountName'), guid(parameters('aiProjectWorkspaceId'), resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers', parameters('cosmosDbAccountName'), 'enterprise_memory', variables('entityStoreName')), variables('roleDefinitionId'), parameters('aiProjectPrincipalId')))]",
- "properties": {
- "principalId": "[parameters('aiProjectPrincipalId')]",
- "roleDefinitionId": "[variables('roleDefinitionId')]",
- "scope": "[variables('scopeEntityContainer')]"
- }
- }
- ]
- }
- },
- "dependsOn": [
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName')))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('caphost{0}', variables('projectName')))]",
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]"
- ]
- },
- {
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2025-04-01",
- "name": "rbacAssignments",
- "resourceGroup": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "storageAccountName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage'), '2025-04-01').outputs.name.value]"
- },
- "appInsightsName": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'monitoring'), '2025-04-01').outputs.applicationInsightsName.value]"
- },
- "managedIdentityPrincipalId": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity'), '2025-04-01').outputs.principalId.value]"
- },
- "userIdentityPrincipalId": {
- "value": "[parameters('principalId')]"
- },
- "enableBlob": {
- "value": "[variables('storageEndpointConfig').enableBlob]"
- },
- "enableQueue": {
- "value": "[variables('storageEndpointConfig').enableQueue]"
- },
- "enableTable": {
- "value": "[variables('storageEndpointConfig').enableTable]"
- },
- "allowUserIdentityPrincipal": {
- "value": "[variables('storageEndpointConfig').allowUserIdentityPrincipal]"
- }
- },
- "template": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "_generator": {
- "name": "bicep",
- "version": "0.44.1.10279",
- "templateHash": "12790120829214215653"
- }
- },
- "parameters": {
- "storageAccountName": {
- "type": "string"
- },
- "appInsightsName": {
- "type": "string"
- },
- "managedIdentityPrincipalId": {
- "type": "string"
- },
- "userIdentityPrincipalId": {
- "type": "string",
- "defaultValue": ""
- },
- "allowUserIdentityPrincipal": {
- "type": "bool",
- "defaultValue": true
- },
- "enableBlob": {
- "type": "bool",
- "defaultValue": true
- },
- "enableQueue": {
- "type": "bool",
- "defaultValue": false
- },
- "enableTable": {
- "type": "bool",
- "defaultValue": false
- }
- },
- "variables": {
- "storageRoleDefinitionId": "b7e6dc6d-f1e8-4753-8033-0f276bb0955b",
- "queueRoleDefinitionId": "974c5e8b-45b9-4653-ba55-5f855dd0fb88",
- "tableRoleDefinitionId": "0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3",
- "monitoringRoleDefinitionId": "3913510d-42f4-4e42-8a64-420c390055eb"
- },
- "resources": [
- {
- "condition": "[parameters('enableBlob')]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('managedIdentityPrincipalId'), variables('storageRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('storageRoleDefinitionId'))]",
- "principalId": "[parameters('managedIdentityPrincipalId')]",
- "principalType": "ServicePrincipal"
- }
- },
- {
- "condition": "[and(and(parameters('enableBlob'), parameters('allowUserIdentityPrincipal')), not(empty(parameters('userIdentityPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('userIdentityPrincipalId'), variables('storageRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('storageRoleDefinitionId'))]",
- "principalId": "[parameters('userIdentityPrincipalId')]",
- "principalType": "User"
- }
- },
- {
- "condition": "[parameters('enableQueue')]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('managedIdentityPrincipalId'), variables('queueRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('queueRoleDefinitionId'))]",
- "principalId": "[parameters('managedIdentityPrincipalId')]",
- "principalType": "ServicePrincipal"
- }
- },
- {
- "condition": "[and(and(parameters('enableQueue'), parameters('allowUserIdentityPrincipal')), not(empty(parameters('userIdentityPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('userIdentityPrincipalId'), variables('queueRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('queueRoleDefinitionId'))]",
- "principalId": "[parameters('userIdentityPrincipalId')]",
- "principalType": "User"
- }
- },
- {
- "condition": "[parameters('enableTable')]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('managedIdentityPrincipalId'), variables('tableRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('tableRoleDefinitionId'))]",
- "principalId": "[parameters('managedIdentityPrincipalId')]",
- "principalType": "ServicePrincipal"
- }
- },
- {
- "condition": "[and(and(parameters('enableTable'), parameters('allowUserIdentityPrincipal')), not(empty(parameters('userIdentityPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
- "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('userIdentityPrincipalId'), variables('tableRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('tableRoleDefinitionId'))]",
- "principalId": "[parameters('userIdentityPrincipalId')]",
- "principalType": "User"
- }
- },
- {
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]",
- "name": "[guid(resourceId('Microsoft.Insights/components', parameters('appInsightsName')), parameters('managedIdentityPrincipalId'), variables('monitoringRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('monitoringRoleDefinitionId'))]",
- "principalId": "[parameters('managedIdentityPrincipalId')]",
- "principalType": "ServicePrincipal"
- }
- },
- {
- "condition": "[and(parameters('allowUserIdentityPrincipal'), not(empty(parameters('userIdentityPrincipalId'))))]",
- "type": "Microsoft.Authorization/roleAssignments",
- "apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]",
- "name": "[guid(resourceId('Microsoft.Insights/components', parameters('appInsightsName')), parameters('userIdentityPrincipalId'), variables('monitoringRoleDefinitionId'))]",
- "properties": {
- "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('monitoringRoleDefinitionId'))]",
- "principalId": "[parameters('userIdentityPrincipalId')]",
- "principalType": "User"
- }
- }
- ]
- }
- },
- "dependsOn": [
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity')]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'monitoring')]",
- "[subscriptionResourceId('Microsoft.Resources/resourceGroups', if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName'))))]",
- "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage')]"
- ]
- }
- ],
- "outputs": {
- "APPLICATIONINSIGHTS_CONNECTION_STRING": {
- "type": "string",
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'monitoring'), '2025-04-01').outputs.applicationInsightsConnectionString.value]"
- },
- "AZURE_LOCATION": {
- "type": "string",
- "value": "[parameters('location')]"
- },
- "AZURE_TENANT_ID": {
- "type": "string",
- "value": "[tenant().tenantId]"
- },
- "SERVICE_API_NAME": {
- "type": "string",
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'api'), '2025-04-01').outputs.SERVICE_API_NAME.value]"
- },
- "SERVICE_API_URI": {
- "type": "string",
- "value": "[format('https://{0}.azurewebsites.net', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'api'), '2025-04-01').outputs.SERVICE_API_NAME.value)]"
- },
- "AZURE_FUNCTION_APP_NAME": {
- "type": "string",
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'api'), '2025-04-01').outputs.SERVICE_API_NAME.value]"
- },
- "RESOURCE_GROUP": {
- "type": "string",
- "value": "[if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))]"
- },
- "STORAGE_ACCOUNT_NAME": {
- "type": "string",
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage'), '2025-04-01').outputs.name.value]"
- },
- "AI_SERVICES_NAME": {
- "type": "string",
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiServicesName.value]"
- },
- "PROJECT_ENDPOINT": {
- "type": "string",
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('project{0}', variables('projectName'))), '2025-04-01').outputs.projectEndpoint.value]"
- },
- "MODEL_DEPLOYMENT_NAME": {
- "type": "string",
- "value": "[parameters('modelDeploymentName')]"
- },
- "AZURE_OPENAI_ENDPOINT": {
- "type": "string",
- "value": "[format('https://{0}.openai.azure.com/', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', format('dependencies{0}', variables('projectName'))), '2025-04-01').outputs.aiServicesName.value)]"
- },
- "AZURE_OPENAI_DEPLOYMENT_NAME": {
- "type": "string",
- "value": "[parameters('modelDeploymentName')]"
- },
- "AZURE_CLIENT_ID": {
- "type": "string",
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'apiUserAssignedIdentity'), '2025-04-01').outputs.clientId.value]"
- },
- "STORAGE_CONNECTION__queueServiceUri": {
- "type": "string",
- "value": "[format('https://{0}.queue.{1}', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, if(not(empty(parameters('resourceGroupName'))), parameters('resourceGroupName'), format('{0}{1}', variables('abbrs').resourcesResourceGroups, parameters('environmentName')))), 'Microsoft.Resources/deployments', 'storage'), '2025-04-01').outputs.name.value, environment().suffixes.storage)]"
- }
- }
-}
\ No newline at end of file
From 11e609d4e4562df9ff7084856f4dc44d17955c74 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:00:43 -0700
Subject: [PATCH 05/13] Refine uv README guidance
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
README.md | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index d64e3db..62a424c 100644
--- a/README.md
+++ b/README.md
@@ -6,13 +6,12 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
## Prerequisites
-- Python 3.13+
-- [uv](https://docs.astral.sh/uv/getting-started/installation/)
+- Python 3.13+ via [uv](https://docs.astral.sh/uv/getting-started/installation/)
- [Azure Functions Core Tools](https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local#install-the-azure-functions-core-tools)
- [Azure Developer CLI (azd)](https://aka.ms/azd-install) (only needed for deploying Microsoft Foundry resources)
- Access to an AI model via one of:
- - **GitHub Copilot subscription** — models are available automatically
- - **Bring Your Own Key (BYOK)** — use an API key from [Microsoft Foundry](https://ai.azure.com) (see [BYOK docs](https://github.com/github/copilot-sdk/blob/main/docs/auth/byok.md))
+ - **GitHub Copilot subscription** - models are available automatically
+ - **Bring Your Own Key (BYOK)** - use an API key from [Microsoft Foundry](https://ai.azure.com) (see [BYOK docs](https://github.com/github/copilot-sdk/blob/main/docs/auth/byok.md))
## Quickstart
@@ -102,12 +101,17 @@ export AZURE_OPENAI_MODEL="gpt-5-mini" # optional, defaults to gpt-5-mini
```
**Getting these values:**
-- If you ran `azd up`, the endpoint is already in your environment — run `azd env get-values | grep AZURE_OPENAI_ENDPOINT`
-- For the API key, go to [Azure Portal](https://portal.azure.com) → your AI Services resource → **Keys and Endpoint** → select the **Azure OpenAI** tab
+- If you ran `azd up`, the endpoint is already in your environment. Run `azd env get-values | grep AZURE_OPENAI_ENDPOINT`
+- For the API key, go to [Azure Portal](https://portal.azure.com), your AI Services resource, **Keys and Endpoint**, then select the **Azure OpenAI** tab
- Or find both in the [Microsoft Foundry portal](https://ai.azure.com) under your project settings
See the [BYOK docs](https://github.com/github/copilot-sdk/blob/main/docs/auth/byok.md) for details.
+## Next steps
+
+- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [Use MCP with Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-extension) and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
+- Build durable, long-running Functions workflows: [Durable Functions overview](https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview) and [Azure Functions timer triggers](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer).
+
## Learn More
- [GitHub Copilot SDK](https://github.com/github/copilot-sdk)
From 174e729baccbdefa0265dd23e1e1f219c7708618 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:02:04 -0700
Subject: [PATCH 06/13] Fix Azure Functions MCP docs link
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 62a424c..d67173c 100644
--- a/README.md
+++ b/README.md
@@ -109,7 +109,7 @@ See the [BYOK docs](https://github.com/github/copilot-sdk/blob/main/docs/auth/by
## Next steps
-- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [Use MCP with Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-extension) and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
+- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [Connect an MCP server on Azure Functions to Foundry Agent Service](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-foundry-tools) and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
- Build durable, long-running Functions workflows: [Durable Functions overview](https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview) and [Azure Functions timer triggers](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer).
## Learn More
From 5cef8b52e9a623f95770b3a3bbbbf94882547c13 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:06:54 -0700
Subject: [PATCH 07/13] Add Functions MCP loopback tutorial
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
.env.example | 6 +++++
README.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++-
function_app.py | 52 +++++++++++++++++++++++++++++++++++---
host.json | 7 +++++
pyproject.toml | 2 +-
requirements.txt | 2 +-
uv.lock | 2 +-
7 files changed, 130 insertions(+), 7 deletions(-)
diff --git a/.env.example b/.env.example
index a7f97d1..57bdca2 100644
--- a/.env.example
+++ b/.env.example
@@ -8,3 +8,9 @@ AZURE_AI_MODEL_DEPLOYMENT_NAME="chat"
GITHUB_REPOSITORY="microsoft-foundry/foundry-samples"
# GITHUB_TOKEN can be set to increase public API rate limits. OAuth is not required.
GITHUB_TOKEN=""
+
+# Optional Copilot SDK MCP loopback. Local Functions does not need a key.
+# For Azure, set this to https://.azurewebsites.net/runtime/webhooks/mcp
+# and set MCP_EXTENSION_KEY to the mcp_extension system key.
+COPILOT_MCP_SERVER_URL="http://localhost:7071/runtime/webhooks/mcp"
+MCP_EXTENSION_KEY=""
diff --git a/README.md b/README.md
index d67173c..b9e9d15 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,7 @@ The agent logic is in [`function_app.py`](function_app.py). It creates a `Copilo
- An HTTP endpoint at `/api/ask` for chat or API requests.
- A timer-triggered function named `daily_repo_digest` that runs the digest at 9 AM Pacific.
+- An MCP tool named `get_repo_digest_context` at `/runtime/webhooks/mcp`.
[`chat.py`](chat.py) is a lightweight console client that POSTs messages to the function in a loop, giving you an interactive chat experience. It defaults to `http://localhost:7071` but can be pointed at a deployed instance via the `AGENT_URL` environment variable.
@@ -71,6 +72,69 @@ Local development uses [`pyproject.toml`](pyproject.toml) with `uv sync` and `uv
The timer trigger uses the Azure Functions NCRONTAB schedule `0 0 16,17 * * *`. Azure Functions timer schedules run in UTC for this Linux Functions sample, so the function wakes at both possible 9 AM Pacific UTC offsets and only creates a digest when the current `America/Los_Angeles` hour is 9. This keeps the sample aligned with Pacific daylight and standard time without adding a separate scheduler service.
+## MCP extension tutorial
+
+This sample also exposes the live repo data fetcher as an Azure Functions MCP extension tool, then shows how to consume that tool from the Copilot SDK. The implementation uses the Python v2 Functions programming model:
+
+```python
+@app.mcp_tool()
+@app.mcp_tool_property(
+ arg_name="repository",
+ description="Public GitHub repository in owner/name format.",
+ is_required=False,
+)
+def get_repo_digest_context(repository: str = DEFAULT_REPOSITORY) -> str:
+ return json.dumps(_repo_digest_context(repository), indent=2)
+```
+
+The Functions MCP extension exposes the server at:
+
+```text
+http://localhost:7071/runtime/webhooks/mcp
+```
+
+For a deployed Function App, use:
+
+```text
+https://.azurewebsites.net/runtime/webhooks/mcp
+```
+
+Remote endpoints require the `mcp_extension` system key unless you change `host.json` to use anonymous webhook authorization. Get the deployed key with:
+
+```bash
+az functionapp keys list \
+ --resource-group \
+ --name \
+ --query systemKeys.mcp_extension \
+ --output tsv
+```
+
+To have this sample consume its own MCP tool from the Copilot SDK, set:
+
+```bash
+export COPILOT_MCP_SERVER_URL="http://localhost:7071/runtime/webhooks/mcp"
+
+# Only needed for a deployed Function App endpoint.
+export MCP_EXTENSION_KEY=""
+```
+
+When `COPILOT_MCP_SERVER_URL` is set, `function_app.py` passes this MCP server into `CopilotClient.create_session`:
+
+```python
+config["mcp_servers"] = {
+ "repo-digest-functions": {
+ "type": "http",
+ "url": mcp_server_url,
+ "headers": headers,
+ "tools": ["get_repo_digest_context"],
+ }
+}
+```
+
+Then the digest prompt tells the model to call `get_repo_digest_context` for live GitHub data. If `COPILOT_MCP_SERVER_URL` is not set, the sample falls back to fetching public GitHub REST data directly before sending the prompt to the model.
+
+For the underlying Functions MCP extension docs, see [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial), [Model context protocol bindings for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp), and [MCP tool trigger for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp-tool-trigger). For the Copilot SDK side, see [Using MCP servers with the GitHub Copilot SDK](https://github.com/github/copilot-sdk/blob/main/docs/features/mcp.md).
+
## Deploy Microsoft Foundry Resources
If you prefer to use your own models via BYOK and don't already have a Microsoft Foundry project with a model deployed:
@@ -109,7 +173,7 @@ See the [BYOK docs](https://github.com/github/copilot-sdk/blob/main/docs/auth/by
## Next steps
-- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [Connect an MCP server on Azure Functions to Foundry Agent Service](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-foundry-tools) and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
+- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [Model context protocol bindings for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp) and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
- Build durable, long-running Functions workflows: [Durable Functions overview](https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview) and [Azure Functions timer triggers](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer).
## Learn More
diff --git a/function_app.py b/function_app.py
index 623c831..d2dfa54 100644
--- a/function_app.py
+++ b/function_app.py
@@ -44,6 +44,20 @@ def _session_config():
token = credential.get_token("https://cognitiveservices.azure.com/.default")
provider["bearer_token"] = token.token
config["provider"] = provider
+ mcp_server_url = os.environ.get("COPILOT_MCP_SERVER_URL")
+ if mcp_server_url:
+ headers = {}
+ mcp_extension_key = os.environ.get("MCP_EXTENSION_KEY")
+ if mcp_extension_key:
+ headers["x-functions-key"] = mcp_extension_key
+ config["mcp_servers"] = {
+ "repo-digest-functions": {
+ "type": "http",
+ "url": mcp_server_url,
+ "headers": headers,
+ "tools": ["get_repo_digest_context"],
+ }
+ }
return config
@@ -153,8 +167,28 @@ def _repo_digest_context(repository: str) -> dict:
async def _run_digest(prompt: str) -> str:
repository = _repository_from_prompt(prompt)
- context = _repo_digest_context(repository)
- digest_prompt = f"""
+ config = _session_config()
+ if "mcp_servers" in config:
+ digest_prompt = f"""
+Create a concise daily repo digest for {repository}.
+
+Use the `get_repo_digest_context` MCP tool to get live GitHub data before writing the digest.
+
+User request:
+{prompt}
+
+Return:
+1. A one-line summary.
+2. Pull requests updated in the last 24 hours.
+3. Issues updated in the last 24 hours.
+4. Workflow failures from the last 24 hours.
+5. Suggested next actions.
+
+If a section has no items, say "None found".
+"""
+ else:
+ context = _repo_digest_context(repository)
+ digest_prompt = f"""
Create a concise daily repo digest for {repository}.
User request:
@@ -172,7 +206,7 @@ async def _run_digest(prompt: str) -> str:
If a section has no items, say "None found".
"""
- session = await client.create_session(_session_config())
+ session = await client.create_session(**config)
try:
reply = await session.send_and_wait({"prompt": digest_prompt})
return (reply.data.content if reply and reply.data else None) or "No response"
@@ -180,6 +214,18 @@ async def _run_digest(prompt: str) -> str:
await session.destroy()
+@app.mcp_tool()
+@app.mcp_tool_property(
+ arg_name="repository",
+ description="Public GitHub repository in owner/name format. Defaults to microsoft-foundry/foundry-samples.",
+ is_required=False,
+)
+def get_repo_digest_context(repository: str = DEFAULT_REPOSITORY) -> str:
+ """Return live GitHub data for a daily repository digest."""
+ repository = repository or os.environ.get("GITHUB_REPOSITORY", DEFAULT_REPOSITORY)
+ return json.dumps(_repo_digest_context(repository), indent=2)
+
+
@app.route(route="ask", methods=["POST"])
async def ask(req: func.HttpRequest) -> func.HttpResponse:
"""HTTP trigger that sends a message to the Copilot SDK agent."""
diff --git a/host.json b/host.json
index dbf749f..84bf5aa 100644
--- a/host.json
+++ b/host.json
@@ -1,6 +1,13 @@
{
"version": "2.0",
"functionTimeout": "00:30:00",
+ "extensions": {
+ "mcp": {
+ "instructions": "Use the repo digest tools to fetch live public GitHub repository data for daily summaries.",
+ "serverName": "repo-digest-functions",
+ "serverVersion": "1.0.0"
+ }
+ },
"logging": {
"applicationInsights": {
"samplingSettings": {
diff --git a/pyproject.toml b/pyproject.toml
index 387ffac..effbf2a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ description = "Azure Functions and Copilot SDK sample that creates daily GitHub
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
- "azure-functions",
+ "azure-functions>=2.2.0",
"azure-identity",
"github-copilot-sdk",
]
diff --git a/requirements.txt b/requirements.txt
index d772063..26e0e67 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,3 @@
-azure-functions
+azure-functions>=2.2.0
azure-identity
github-copilot-sdk
diff --git a/uv.lock b/uv.lock
index 5e879c0..6fc9e0d 100644
--- a/uv.lock
+++ b/uv.lock
@@ -514,7 +514,7 @@ dependencies = [
[package.metadata]
requires-dist = [
- { name = "azure-functions" },
+ { name = "azure-functions", specifier = ">=2.2.0" },
{ name = "azure-identity" },
{ name = "github-copilot-sdk" },
]
From 58c144e4b5e31f30a1b362e0b0866eade6774d27 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:14:19 -0700
Subject: [PATCH 08/13] Split MCP tutorial notes from main README
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
README-MCP.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++
README.md | 73 ++++++++++------------------------------------
2 files changed, 96 insertions(+), 58 deletions(-)
create mode 100644 README-MCP.md
diff --git a/README-MCP.md b/README-MCP.md
new file mode 100644
index 0000000..75160f2
--- /dev/null
+++ b/README-MCP.md
@@ -0,0 +1,81 @@
+# MCP extension notes
+
+This sample exposes the live repo data fetcher as an Azure Functions MCP extension tool and can consume that same Functions-hosted MCP service from the Copilot SDK.
+
+The full Azure Functions tutorial belongs in Microsoft Learn. Start with [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial), then use these sample-specific notes to see how the pieces map into this repo.
+
+## Expose a Functions MCP tool
+
+The repo digest data fetcher is exposed from [`function_app.py`](function_app.py) with the Python v2 Functions programming model:
+
+```python
+@app.mcp_tool()
+@app.mcp_tool_property(
+ arg_name="repository",
+ description="Public GitHub repository in owner/name format.",
+ is_required=False,
+)
+def get_repo_digest_context(repository: str = DEFAULT_REPOSITORY) -> str:
+ return json.dumps(_repo_digest_context(repository), indent=2)
+```
+
+The Functions MCP extension exposes the server at:
+
+```text
+http://localhost:7071/runtime/webhooks/mcp
+```
+
+For a deployed Function App, use:
+
+```text
+https://.azurewebsites.net/runtime/webhooks/mcp
+```
+
+Remote endpoints require the `mcp_extension` system key unless `host.json` is configured for anonymous webhook authorization. Get the deployed key with:
+
+```bash
+az functionapp keys list \
+ --resource-group \
+ --name \
+ --query systemKeys.mcp_extension \
+ --output tsv
+```
+
+## Consume the Functions MCP service from Copilot SDK
+
+Pass the Functions MCP endpoint as a remote HTTP MCP server when creating a Copilot SDK session:
+
+```python
+session = await client.create_session(
+ on_permission_request=PermissionHandler.approve_all,
+ mcp_servers={
+ "repo-digest-functions": {
+ "type": "http",
+ "url": "https://.azurewebsites.net/runtime/webhooks/mcp",
+ "headers": {"x-functions-key": ""},
+ "tools": ["get_repo_digest_context"],
+ }
+ },
+)
+```
+
+For local loopback in this sample, set:
+
+```bash
+export COPILOT_MCP_SERVER_URL="http://localhost:7071/runtime/webhooks/mcp"
+```
+
+For a deployed Function App endpoint, also set:
+
+```bash
+export MCP_EXTENSION_KEY=""
+```
+
+When `COPILOT_MCP_SERVER_URL` is set, `function_app.py` passes the MCP server into `CopilotClient.create_session` and asks the model to call `get_repo_digest_context` for live GitHub data. If `COPILOT_MCP_SERVER_URL` is not set, the sample falls back to fetching public GitHub REST data directly before sending the prompt to the model.
+
+## References
+
+- [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial)
+- [Model context protocol bindings for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp)
+- [MCP tool trigger for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp-tool-trigger)
+- [Using MCP servers with the GitHub Copilot SDK](https://github.com/github/copilot-sdk/blob/main/docs/features/mcp.md)
diff --git a/README.md b/README.md
index b9e9d15..4c7447b 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ The agent logic is in [`function_app.py`](function_app.py). It creates a `Copilo
- An HTTP endpoint at `/api/ask` for chat or API requests.
- A timer-triggered function named `daily_repo_digest` that runs the digest at 9 AM Pacific.
-- An MCP tool named `get_repo_digest_context` at `/runtime/webhooks/mcp`.
+- An optional MCP tool named `get_repo_digest_context` at `/runtime/webhooks/mcp`.
[`chat.py`](chat.py) is a lightweight console client that POSTs messages to the function in a loop, giving you an interactive chat experience. It defaults to `http://localhost:7071` but can be pointed at a deployed instance via the `AGENT_URL` environment variable.
@@ -72,68 +72,25 @@ Local development uses [`pyproject.toml`](pyproject.toml) with `uv sync` and `uv
The timer trigger uses the Azure Functions NCRONTAB schedule `0 0 16,17 * * *`. Azure Functions timer schedules run in UTC for this Linux Functions sample, so the function wakes at both possible 9 AM Pacific UTC offsets and only creates a digest when the current `America/Los_Angeles` hour is 9. This keeps the sample aligned with Pacific daylight and standard time without adding a separate scheduler service.
-## MCP extension tutorial
+## MCP extension
-This sample also exposes the live repo data fetcher as an Azure Functions MCP extension tool, then shows how to consume that tool from the Copilot SDK. The implementation uses the Python v2 Functions programming model:
+This sample includes an optional Functions-hosted MCP tool for the repo digest data fetcher. For the Azure Functions side, start with [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial). To call a Functions-hosted remote MCP service from the Copilot SDK, pass the service URL into `mcp_servers`:
```python
-@app.mcp_tool()
-@app.mcp_tool_property(
- arg_name="repository",
- description="Public GitHub repository in owner/name format.",
- is_required=False,
+session = await client.create_session(
+ on_permission_request=PermissionHandler.approve_all,
+ mcp_servers={
+ "repo-digest-functions": {
+ "type": "http",
+ "url": "https://.azurewebsites.net/runtime/webhooks/mcp",
+ "headers": {"x-functions-key": ""},
+ "tools": ["get_repo_digest_context"],
+ }
+ },
)
-def get_repo_digest_context(repository: str = DEFAULT_REPOSITORY) -> str:
- return json.dumps(_repo_digest_context(repository), indent=2)
```
-The Functions MCP extension exposes the server at:
-
-```text
-http://localhost:7071/runtime/webhooks/mcp
-```
-
-For a deployed Function App, use:
-
-```text
-https://.azurewebsites.net/runtime/webhooks/mcp
-```
-
-Remote endpoints require the `mcp_extension` system key unless you change `host.json` to use anonymous webhook authorization. Get the deployed key with:
-
-```bash
-az functionapp keys list \
- --resource-group \
- --name \
- --query systemKeys.mcp_extension \
- --output tsv
-```
-
-To have this sample consume its own MCP tool from the Copilot SDK, set:
-
-```bash
-export COPILOT_MCP_SERVER_URL="http://localhost:7071/runtime/webhooks/mcp"
-
-# Only needed for a deployed Function App endpoint.
-export MCP_EXTENSION_KEY=""
-```
-
-When `COPILOT_MCP_SERVER_URL` is set, `function_app.py` passes this MCP server into `CopilotClient.create_session`:
-
-```python
-config["mcp_servers"] = {
- "repo-digest-functions": {
- "type": "http",
- "url": mcp_server_url,
- "headers": headers,
- "tools": ["get_repo_digest_context"],
- }
-}
-```
-
-Then the digest prompt tells the model to call `get_repo_digest_context` for live GitHub data. If `COPILOT_MCP_SERVER_URL` is not set, the sample falls back to fetching public GitHub REST data directly before sending the prompt to the model.
-
-For the underlying Functions MCP extension docs, see [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial), [Model context protocol bindings for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp), and [MCP tool trigger for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp-tool-trigger). For the Copilot SDK side, see [Using MCP servers with the GitHub Copilot SDK](https://github.com/github/copilot-sdk/blob/main/docs/features/mcp.md).
+See [README-MCP.md](README-MCP.md) for the focused MCP extension and Copilot SDK loopback notes.
## Deploy Microsoft Foundry Resources
@@ -173,7 +130,7 @@ See the [BYOK docs](https://github.com/github/copilot-sdk/blob/main/docs/auth/by
## Next steps
-- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [Model context protocol bindings for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-mcp) and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
+- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [MCP extension notes for this sample](README-MCP.md), [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial), and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
- Build durable, long-running Functions workflows: [Durable Functions overview](https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview) and [Azure Functions timer triggers](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer).
## Learn More
From a2b7409035589edd0540ff69b7e29d72c2c00ab1 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:16:10 -0700
Subject: [PATCH 09/13] Rename MCP extension notes
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
README-MCP.md => MCP-extension-notes.md | 0
README.md | 4 ++--
2 files changed, 2 insertions(+), 2 deletions(-)
rename README-MCP.md => MCP-extension-notes.md (100%)
diff --git a/README-MCP.md b/MCP-extension-notes.md
similarity index 100%
rename from README-MCP.md
rename to MCP-extension-notes.md
diff --git a/README.md b/README.md
index 4c7447b..fcdb72e 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,7 @@ session = await client.create_session(
)
```
-See [README-MCP.md](README-MCP.md) for the focused MCP extension and Copilot SDK loopback notes.
+See [MCP-extension-notes.md](MCP-extension-notes.md) for the focused MCP extension and Copilot SDK loopback notes.
## Deploy Microsoft Foundry Resources
@@ -130,7 +130,7 @@ See the [BYOK docs](https://github.com/github/copilot-sdk/blob/main/docs/auth/by
## Next steps
-- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [MCP extension notes for this sample](README-MCP.md), [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial), and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
+- Add tools and data sources with Azure Functions custom bindings, Python helpers, or MCP integration: [MCP extension notes for this sample](MCP-extension-notes.md), [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial), and [connect MCP server endpoints to Foundry agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/model-context-protocol).
- Build durable, long-running Functions workflows: [Durable Functions overview](https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview) and [Azure Functions timer triggers](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer).
## Learn More
From 533ccca0e4c2e94ced5592ba8a4a903947b3585c Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:17:29 -0700
Subject: [PATCH 10/13] Simplify main README MCP guidance
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
README.md | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/README.md b/README.md
index fcdb72e..790b822 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,6 @@ The agent logic is in [`function_app.py`](function_app.py). It creates a `Copilo
- An HTTP endpoint at `/api/ask` for chat or API requests.
- A timer-triggered function named `daily_repo_digest` that runs the digest at 9 AM Pacific.
-- An optional MCP tool named `get_repo_digest_context` at `/runtime/webhooks/mcp`.
[`chat.py`](chat.py) is a lightweight console client that POSTs messages to the function in a loop, giving you an interactive chat experience. It defaults to `http://localhost:7071` but can be pointed at a deployed instance via the `AGENT_URL` environment variable.
@@ -72,26 +71,6 @@ Local development uses [`pyproject.toml`](pyproject.toml) with `uv sync` and `uv
The timer trigger uses the Azure Functions NCRONTAB schedule `0 0 16,17 * * *`. Azure Functions timer schedules run in UTC for this Linux Functions sample, so the function wakes at both possible 9 AM Pacific UTC offsets and only creates a digest when the current `America/Los_Angeles` hour is 9. This keeps the sample aligned with Pacific daylight and standard time without adding a separate scheduler service.
-## MCP extension
-
-This sample includes an optional Functions-hosted MCP tool for the repo digest data fetcher. For the Azure Functions side, start with [Tutorial: Host an MCP server on Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-mcp-tutorial). To call a Functions-hosted remote MCP service from the Copilot SDK, pass the service URL into `mcp_servers`:
-
-```python
-session = await client.create_session(
- on_permission_request=PermissionHandler.approve_all,
- mcp_servers={
- "repo-digest-functions": {
- "type": "http",
- "url": "https://.azurewebsites.net/runtime/webhooks/mcp",
- "headers": {"x-functions-key": ""},
- "tools": ["get_repo_digest_context"],
- }
- },
-)
-```
-
-See [MCP-extension-notes.md](MCP-extension-notes.md) for the focused MCP extension and Copilot SDK loopback notes.
-
## Deploy Microsoft Foundry Resources
If you prefer to use your own models via BYOK and don't already have a Microsoft Foundry project with a model deployed:
From fb8b671d937d966f4f32af3463b8e3c87cbee021 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:29:42 -0700
Subject: [PATCH 11/13] Use Azure Functions host as default digest repo
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
.env.example | 2 +-
README.md | 6 +++---
chat.py | 2 +-
function_app.py | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/.env.example b/.env.example
index 57bdca2..e74bde4 100644
--- a/.env.example
+++ b/.env.example
@@ -5,7 +5,7 @@ AZURE_AI_PROJECT_ENDPOINT="https://.services.ai.azure.com/api/
AZURE_AI_MODEL_DEPLOYMENT_NAME="chat"
# Optional GitHub configuration for the daily digest sample
-GITHUB_REPOSITORY="microsoft-foundry/foundry-samples"
+GITHUB_REPOSITORY="Azure/azure-functions-host"
# GITHUB_TOKEN can be set to increase public API rate limits. OAuth is not required.
GITHUB_TOKEN=""
diff --git a/README.md b/README.md
index 790b822..394571e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Daily Repo Digest QuickStart (Python Copilot SDK on Azure Functions)
-A simple AI agent built with the GitHub Copilot SDK, running as an Azure Function. It creates live daily GitHub repository digests for recent pull requests, issues, and workflow failures. The default repository is `microsoft-foundry/foundry-samples`.
+A simple AI agent built with the GitHub Copilot SDK, running as an Azure Function. It creates live daily GitHub repository digests for recent pull requests, issues, and workflow failures. The default repository is `Azure/azure-functions-host`.
> Looking for [C#](https://github.com/Azure-Samples/simple-agent-functions-dotnet) or [TypeScript](https://github.com/Azure-Samples/simple-agent-functions-typescript)?
@@ -39,7 +39,7 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
# Or use curl directly
curl -X POST http://localhost:7071/api/ask \
- -d "Create a concise daily repo digest for microsoft-foundry/foundry-samples."
+ -d "Create a concise daily repo digest for Azure/azure-functions-host."
```
To chat with a deployed instance, grab the URL and function key from your `azd` environment:
@@ -63,7 +63,7 @@ The agent logic is in [`function_app.py`](function_app.py). It creates a `Copilo
[`chat.py`](chat.py) is a lightweight console client that POSTs messages to the function in a loop, giving you an interactive chat experience. It defaults to `http://localhost:7071` but can be pointed at a deployed instance via the `AGENT_URL` environment variable.
-Ask for a digest with an optional public repo such as `microsoft-foundry/foundry-samples`. If you omit the repo, the agent uses `microsoft-foundry/foundry-samples` by default. Set `GITHUB_REPOSITORY` to change the default repository. Set `GITHUB_TOKEN` only if you want higher public GitHub API rate limits.
+Ask for a digest with an optional public repo such as `Azure/azure-functions-host`. If you omit the repo, the agent uses `Azure/azure-functions-host` by default. Set `GITHUB_REPOSITORY` to change the default repository. Set `GITHUB_TOKEN` only if you want higher public GitHub API rate limits.
Local development uses [`pyproject.toml`](pyproject.toml) with `uv sync` and `uv run`. [`requirements.txt`](requirements.txt) is kept for Azure Functions packaging and should stay aligned with the dependencies in `pyproject.toml`.
diff --git a/chat.py b/chat.py
index 7fad780..2c104e5 100644
--- a/chat.py
+++ b/chat.py
@@ -7,7 +7,7 @@
print(f"=== Repo Digest Agent Chat ===")
print(f"Endpoint: {BASE_URL}/api/ask")
-print("Ask for a daily digest, or include a public repo like microsoft-foundry/foundry-samples.")
+print("Ask for a daily digest, or include a public repo like Azure/azure-functions-host.")
print("Type 'exit' or 'quit' to end.\n")
while True:
diff --git a/function_app.py b/function_app.py
index d2dfa54..5bb1083 100644
--- a/function_app.py
+++ b/function_app.py
@@ -13,7 +13,7 @@
app = func.FunctionApp()
client = CopilotClient()
-DEFAULT_REPOSITORY = "microsoft-foundry/foundry-samples"
+DEFAULT_REPOSITORY = "Azure/azure-functions-host"
PACIFIC_TIME = ZoneInfo("America/Los_Angeles")
GITHUB_API = "https://api.github.com"
@@ -217,7 +217,7 @@ async def _run_digest(prompt: str) -> str:
@app.mcp_tool()
@app.mcp_tool_property(
arg_name="repository",
- description="Public GitHub repository in owner/name format. Defaults to microsoft-foundry/foundry-samples.",
+ description="Public GitHub repository in owner/name format. Defaults to Azure/azure-functions-host.",
is_required=False,
)
def get_repo_digest_context(repository: str = DEFAULT_REPOSITORY) -> str:
From c7ed748bcced7defd591e1b2d29a8309af7f96f4 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 02:31:47 -0700
Subject: [PATCH 12/13] Bump template metadata version
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
azure.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/azure.yaml b/azure.yaml
index 14fea44..19d3a5e 100644
--- a/azure.yaml
+++ b/azure.yaml
@@ -2,7 +2,7 @@
name: simple-agent-functions-python
metadata:
- template: simple-agent-functions-python@1.0.0
+ template: simple-agent-functions-python@1.1.0
services:
api:
project: ./
From e4e0f0d249ce04b692f21a8c31343d0ea1d02157 Mon Sep 17 00:00:00 2001
From: Paul Yuknewicz
Date: Thu, 9 Jul 2026 16:27:29 -0700
Subject: [PATCH 13/13] Address Python digest review feedback
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
.gitignore | 1 -
README.md | 11 +++++++++--
function_app.py | 4 ++--
local.settings.json | 8 ++++++++
4 files changed, 19 insertions(+), 5 deletions(-)
create mode 100644 local.settings.json
diff --git a/.gitignore b/.gitignore
index 1ccb1c2..69fdf14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -145,7 +145,6 @@ cython_debug/
Thumbs.db
# Azure Functions
-local.settings.json
__blobstorage__/
__queuestorage__/
__azurite_db*__.json
diff --git a/README.md b/README.md
index 394571e..32a8784 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
- Python 3.13+ via [uv](https://docs.astral.sh/uv/getting-started/installation/)
- [Azure Functions Core Tools](https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local#install-the-azure-functions-core-tools)
+- [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) for local Azure Functions storage
- [Azure Developer CLI (azd)](https://aka.ms/azd-install) (only needed for deploying Microsoft Foundry resources)
- Access to an AI model via one of:
- **GitHub Copilot subscription** - models are available automatically
@@ -25,13 +26,19 @@ A simple AI agent built with the GitHub Copilot SDK, running as an Azure Functio
uv sync
```
-3. Run the function locally:
+3. Start Azurite in a separate terminal:
+
+ ```bash
+ azurite --skipApiVersionCheck --silent --location ./.azurite
+ ```
+
+4. Run the function locally:
```bash
uv run func start
```
-4. Test the digest agent (in a new terminal):
+5. Test the digest agent in another terminal:
```bash
# Interactive chat client
diff --git a/function_app.py b/function_app.py
index 5bb1083..ea8a37a 100644
--- a/function_app.py
+++ b/function_app.py
@@ -208,10 +208,10 @@ async def _run_digest(prompt: str) -> str:
"""
session = await client.create_session(**config)
try:
- reply = await session.send_and_wait({"prompt": digest_prompt})
+ reply = await session.send_and_wait(digest_prompt)
return (reply.data.content if reply and reply.data else None) or "No response"
finally:
- await session.destroy()
+ await session.disconnect()
@app.mcp_tool()
diff --git a/local.settings.json b/local.settings.json
new file mode 100644
index 0000000..1907bd2
--- /dev/null
+++ b/local.settings.json
@@ -0,0 +1,8 @@
+{
+ "IsEncrypted": false,
+ "Values": {
+ "AzureWebJobsStorage": "UseDevelopmentStorage=true",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "GITHUB_REPOSITORY": "Azure/azure-functions-host"
+ }
+}