Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions .github/workflows/azure-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ on:
# Set this to the mainline branch you are using
branches:
- main
pull_request:
# Run when pull requests are opened or updated
branches:
- main
# GitHub Actions workflow to deploy to Azure using azd

permissions:
actions: read # Needed for uploading SARIF reports
security-events: write # Needed for uploading SARIF reports
Expand All @@ -37,18 +40,16 @@ jobs:
AZURE_LOCATION: ${{ github.event.inputs.azure_location || 'eastus' }}

steps:
- name: Checkout the branch ${{ github.ref_name }}
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
ref: ${{ github.ref_name }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Install azd
uses: Azure/setup-azd@cf638ffd167fc81e1851241a478a723c05fa9cb3 # v2.2.0
uses: Azure/setup-azd@cf638ffd167fc81e1851241a478a723c05fa9cb3 # v2.2.0
with:
version: '1.20.0' # Specify your desired azd version here

- name: Setup Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: '18.x'

Expand All @@ -58,7 +59,7 @@ jobs:
terraform_version: 1.13.3

- name: Install TFLint
uses: terraform-linters/setup-tflint@acd1575d3c037258ce5b2dd01379dc49ce24c6b7 # v6.2.0
uses: terraform-linters/setup-tflint@acd1575d3c037258ce5b2dd01379dc49ce24c6b7 # v6.2.0
with:
tflint_version: v0.58.1
github_token: ${{ secrets.GITHUB_TOKEN }} # Used to avoid rate
Expand Down Expand Up @@ -86,9 +87,21 @@ jobs:
echo "GitLeaks scan completed"

- name: Setup .NET SDK
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
with:
dotnet-version: '8.0.x'
shell: bash
run: |
# Install .NET SDK to temp directory for self-hosted runners to avoid permission issues
DOTNET_INSTALL_DIR="${{ runner.temp }}/dotnet"
mkdir -p "$DOTNET_INSTALL_DIR"

# Download and run the dotnet-install script
curl -sSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh --channel 9.0 --install-dir "$DOTNET_INSTALL_DIR"
rm dotnet-install.sh

# Add to PATH for subsequent steps
echo "$DOTNET_INSTALL_DIR" >> $GITHUB_PATH
echo "DOTNET_ROOT=$DOTNET_INSTALL_DIR" >> $GITHUB_ENV

- name: Install Power Platform Tools
uses: microsoft/powerplatform-actions/actions-install@6c7b538671a040d11afd8ab94d77bfe3b3ed87e6 # v1.9.1
Expand All @@ -100,7 +113,7 @@ jobs:
pac help

- name: Set Up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # 6.0.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # 6.0.0
with:
python-version: "3.x"

Expand Down Expand Up @@ -181,7 +194,7 @@ jobs:
sarif_file: ./checkov-results.sarif/results_sarif.sarif

- name: Azd down
if: ${{ github.event.inputs.run_azd_down == 'true' }}
if: ${{ github.event.inputs.run_azd_down == 'true' || github.event_name == 'pull_request' }}
env:
POWER_PLATFORM_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}
POWER_PLATFORM_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
Expand Down
2 changes: 1 addition & 1 deletion docs/app_registration_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ To enable secure automation and integration with Azure and Power Platform, you n
1. Login to your Power Platform:

```shell
pac auth create
pac auth create --deviceCode
```

1. Create new **App Registration**:
Expand Down
2 changes: 1 addition & 1 deletion docs/cicd.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ All infrastructure for CI/CD lives under `cicd/` and can be customized to meet y

## Prerequisites

- Working local environment of this template. If you do not have one, Follow the step by step instructions for setting up your [**Local Environment**](../README.md#local-environment)
- Working local environment of this template. If you do not have one, Follow the step by step instructions for setting up your [**Local Environment**](../README.md#local-environment).
- An Azure subscription with either User Access Administrator or Owner permissions to create workload identity resources like service principal, and OIDC to be used by the GitHub Actions.
- GitHub CLI (`gh`) installed and authenticated to trigger the bootstrap workflow from your terminal.

Expand Down
13 changes: 13 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Troubleshooting tips

## Quota error during deployment

If you see an InsufficientQuota error mentioning "Tokens Per Minute", the requested `scale.capacity` (thousands of TPM) exceeds your subscription's available quota — lower `scale.capacity` in TFVARS or request a quota increase in the Azure portal.

## Private endpoint fails with AccountProvisioningStateInvalid

This occurs when Terraform tries to create the private endpoint before the Azure OpenAI (Cognitive Services) account leaves the `Accepted` state; wait until the resource shows `Succeeded` (portal or `az resource show`) and re-run the provisioning (`azd provision`).

## Use GitHub Copilot to help troubleshoot

If you're unsure how to fix a deployment error, open the relevant files in VS Code and use GitHub Copilot for suggestions. Copilot can propose TFVARS overrides, sample values, terraform plan snippets, or concise support-request wording; always review and test generated suggestions before applying them.
12 changes: 12 additions & 0 deletions infra/main.app_insights.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@

resource "random_uuid" "uid" {}

resource "azurerm_log_analytics_workspace" "monitoring" {
count = var.include_log_analytics ? 1 : 0

daily_quota_gb = -1
location = local.primary_azure_region
name = azurecaf_name.main_names.results["azurerm_log_analytics_workspace"]
resource_group_name = local.resource_group_name
retention_in_days = var.log_analytics_retention_in_days
sku = "PerGB2018"
tags = var.tags
}

resource "azurerm_application_insights" "insights" {
count = var.include_app_insights ? 1 : 0

Expand Down
7 changes: 5 additions & 2 deletions infra/main.naming.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

locals {
# Organization suffixes and prefixes are optional, and we need to form an array of non-empty values only
org_prefix = compact([var.org_naming.org_prefix])
org_suffix = compact([var.org_naming.org_environment, var.org_naming.org_suffix])
org_prefix = compact([var.org_naming.org_prefix])
org_suffix = compact([var.org_naming.org_environment, var.org_naming.org_suffix])
azd_env_seed = parseint(substr(md5(var.azd_environment_name), 0, 8), 16)
}

# Generate unique names for primary resources
Expand All @@ -17,6 +18,7 @@ resource "azurecaf_name" "main_names" {
"azurerm_storage_account",
"azurerm_search_service",
"azurerm_cognitive_account",
"azurerm_log_analytics_workspace",
"azurerm_virtual_network",
"azurerm_network_security_group",
"azurerm_virtual_network_gateway",
Expand All @@ -25,6 +27,7 @@ resource "azurecaf_name" "main_names" {
prefixes = local.org_prefix
suffixes = local.org_suffix
random_length = 4
random_seed = local.azd_env_seed
# use_slug = false
clean_input = true
}
Expand Down
26 changes: 26 additions & 0 deletions infra/main.resource_group.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

# Resource Group Configuration and Management
# This file contains resource group resources and related diagnostic settings

# Resource group logic - use existing or create new
locals {
use_existing_resource_group = var.resource_group_name != null && var.resource_group_name != ""
resource_group_name = local.use_existing_resource_group ? var.resource_group_name : azurerm_resource_group.this[0].name
resource_group_id = local.use_existing_resource_group ? data.azurerm_resource_group.existing[0].id : azurerm_resource_group.this[0].id
}

# Data source to validate existing resource group exists
data "azurerm_resource_group" "existing" {
count = local.use_existing_resource_group ? 1 : 0
name = var.resource_group_name
}

# The Resource Group that will contain the resources managed by this module (only created if not using existing)
resource "azurerm_resource_group" "this" {
count = local.use_existing_resource_group ? 0 : 1
location = local.primary_azure_region
name = azurecaf_name.main_names.results["azurerm_resource_group"]
tags = merge(var.tags, local.env_tags)
}
Loading
Loading